diff options
author | Bilal Alsharifi <bilal.alsharifi@gmail.com> | 2020-12-23 11:42:42 -0500 |
---|---|---|
committer | Bilal Alsharifi <bilal.alsharifi@gmail.com> | 2020-12-23 11:42:42 -0500 |
commit | a30246e0852a2d0ef9be99aff3a63b0b78b09ae8 (patch) | |
tree | c7307ce10c4a10073e55f3d38d918c97145b6eee | |
parent | 39f155234b0a0868e583e630c0e6143934369139 (diff) | |
download | sdl_android-a30246e0852a2d0ef9be99aff3a63b0b78b09ae8.tar.gz |
Use TaskMaster in AudioDecoderCompat
3 files changed, 114 insertions, 91 deletions
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java index db6c56fe5..2ab984fcb 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java @@ -32,27 +32,23 @@ package com.smartdevicelink.managers.audio; import android.content.Context; -import android.media.MediaCodec; -import android.media.MediaFormat; import android.net.Uri; import androidx.annotation.NonNull; +import com.livio.taskmaster.Queue; +import com.livio.taskmaster.Taskmaster; +import com.smartdevicelink.managers.ISdl; import com.smartdevicelink.managers.audio.AudioStreamManager.SampleType; -import com.smartdevicelink.util.DebugTool; import java.lang.ref.WeakReference; -import java.nio.ByteBuffer; /** * The audio decoder to decode a single audio file to PCM. * This decoder supports phones with api < 21 but uses methods deprecated with api 21. */ public class AudioDecoderCompat extends BaseAudioDecoder { - private static final String TAG = AudioDecoderCompat.class.getSimpleName(); - private static final int DEQUEUE_TIMEOUT = 3000; - private static Runnable sRunnable; - private Thread mThread; + private WeakReference<ISdl> internalInterface; /** * Creates a new object of AudioDecoder. @@ -63,19 +59,42 @@ public class AudioDecoderCompat extends BaseAudioDecoder { * @param sampleType The desired sample type (8bit, 16bit, float). * @param listener A listener who receives the decoded audio. */ + @Deprecated AudioDecoderCompat(@NonNull Uri audioSource, @NonNull Context context, int sampleRate, @SampleType int sampleType, AudioDecoderListener listener) { super(audioSource, context, sampleRate, sampleType, listener); } /** + * Creates a new object of AudioDecoder. + * + * @param internalInterface The internal interface to the connected device. + * @param audioSource The audio source to decode. + * @param context The context object to use to open the audio source. + * @param sampleRate The desired sample rate for decoded audio data. + * @param sampleType The desired sample type (8bit, 16bit, float). + * @param listener A listener who receives the decoded audio. + */ + AudioDecoderCompat(@NonNull ISdl internalInterface, @NonNull Uri audioSource, @NonNull Context context, int sampleRate, @SampleType int sampleType, AudioDecoderListener listener) { + super(audioSource, context, sampleRate, sampleType, listener); + this.internalInterface = new WeakReference<>(internalInterface); + } + + /** * Starts the audio decoding asynchronously. */ public void start() { try { initMediaComponents(); decoder.start(); - mThread = new Thread(new DecoderRunnable(AudioDecoderCompat.this)); - mThread.start(); + + if (internalInterface != null && internalInterface.get() != null) { + Taskmaster taskmaster = internalInterface.get().getTaskmaster(); + if (taskmaster != null) { + Queue transactionQueue = taskmaster.createQueue("AudioDecoderCompat", 6, false); + AudioDecoderCompatOperation operation = new AudioDecoderCompatOperation(this); + transactionQueue.add(operation, false); + } + } } catch (Exception e) { e.printStackTrace(); @@ -86,84 +105,4 @@ public class AudioDecoderCompat extends BaseAudioDecoder { stop(); } } - - - /** - * Runnable to decode audio data - */ - private static class DecoderRunnable implements Runnable { - final WeakReference<AudioDecoderCompat> weakReference; - - /** - * Decodes all audio data from source - * - * @param audioDecoderCompat instance of this class - */ - DecoderRunnable(@NonNull AudioDecoderCompat audioDecoderCompat) { - weakReference = new WeakReference<>(audioDecoderCompat); - - } - - @Override - public void run() { - final AudioDecoderCompat reference = weakReference.get(); - if (reference == null) { - DebugTool.logWarning(TAG, "AudioDecoderCompat reference was null"); - return; - } - final ByteBuffer[] inputBuffersArray = reference.decoder.getInputBuffers(); - final ByteBuffer[] outputBuffersArray = reference.decoder.getOutputBuffers(); - MediaCodec.BufferInfo outputBufferInfo = new MediaCodec.BufferInfo(); - MediaCodec.BufferInfo inputBufferInfo; - ByteBuffer inputBuffer, outputBuffer; - SampleBuffer sampleBuffer; - - while (reference != null && !reference.mThread.isInterrupted()) { - int inputBuffersArrayIndex = 0; - while (inputBuffersArrayIndex != MediaCodec.INFO_TRY_AGAIN_LATER) { - inputBuffersArrayIndex = reference.decoder.dequeueInputBuffer(DEQUEUE_TIMEOUT); - if (inputBuffersArrayIndex >= 0) { - inputBuffer = inputBuffersArray[inputBuffersArrayIndex]; - inputBufferInfo = reference.onInputBufferAvailable(reference.extractor, inputBuffer); - reference.decoder.queueInputBuffer(inputBuffersArrayIndex, inputBufferInfo.offset, inputBufferInfo.size, inputBufferInfo.presentationTimeUs, inputBufferInfo.flags); - } - } - - int outputBuffersArrayIndex = 0; - while (outputBuffersArrayIndex != MediaCodec.INFO_TRY_AGAIN_LATER) { - outputBuffersArrayIndex = reference.decoder.dequeueOutputBuffer(outputBufferInfo, DEQUEUE_TIMEOUT); - if (outputBuffersArrayIndex >= 0) { - outputBuffer = outputBuffersArray[outputBuffersArrayIndex]; - if ((outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0 && outputBufferInfo.size != 0) { - reference.decoder.releaseOutputBuffer(outputBuffersArrayIndex, false); - } else if (outputBuffer.limit() > 0) { - sampleBuffer = reference.onOutputBufferAvailable(outputBuffer); - if (reference.listener != null) { - reference.listener.onAudioDataAvailable(sampleBuffer); - } - reference.decoder.releaseOutputBuffer(outputBuffersArrayIndex, false); - } - } else if (outputBuffersArrayIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - MediaFormat newFormat = reference.decoder.getOutputFormat(); - reference.onOutputFormatChanged(newFormat); - } - } - - if (outputBufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) { - if (reference.listener != null) { - reference.listener.onDecoderFinish(true); - } - reference.stop(); - try { - reference.mThread.interrupt(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - reference.mThread = null; - break; - } - } - } - } - } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompatOperation.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompatOperation.java new file mode 100644 index 000000000..1371f8474 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompatOperation.java @@ -0,0 +1,84 @@ +package com.smartdevicelink.managers.audio; + +import android.media.MediaCodec; +import android.media.MediaFormat; + +import com.livio.taskmaster.Task; +import com.smartdevicelink.util.DebugTool; + +import java.lang.ref.WeakReference; +import java.nio.ByteBuffer; + +class AudioDecoderCompatOperation extends Task { + private static final String TAG = "AudioDecoderCompatOperation"; + private final WeakReference<AudioDecoderCompat> audioDecoderCompatWeakReference; + private static final int DEQUEUE_TIMEOUT = 3000; + + AudioDecoderCompatOperation(AudioDecoderCompat audioDecoderCompat) { + super("AudioDecoderCompatOperation"); + this.audioDecoderCompatWeakReference = new WeakReference<>(audioDecoderCompat); + } + + @Override + public void onExecute() { + start(); + } + + private void start() { + if (getState() == Task.CANCELED) { + return; + } + + final AudioDecoderCompat audioDecoderCompat = audioDecoderCompatWeakReference.get(); + if (audioDecoderCompat == null) { + DebugTool.logWarning(TAG, "AudioDecoderCompat reference was null"); + return; + } + final ByteBuffer[] inputBuffersArray = audioDecoderCompat.decoder.getInputBuffers(); + final ByteBuffer[] outputBuffersArray = audioDecoderCompat.decoder.getOutputBuffers(); + MediaCodec.BufferInfo outputBufferInfo = new MediaCodec.BufferInfo(); + MediaCodec.BufferInfo inputBufferInfo; + ByteBuffer inputBuffer, outputBuffer; + SampleBuffer sampleBuffer; + + while (true) { + int inputBuffersArrayIndex = 0; + while (inputBuffersArrayIndex != MediaCodec.INFO_TRY_AGAIN_LATER) { + inputBuffersArrayIndex = audioDecoderCompat.decoder.dequeueInputBuffer(DEQUEUE_TIMEOUT); + if (inputBuffersArrayIndex >= 0) { + inputBuffer = inputBuffersArray[inputBuffersArrayIndex]; + inputBufferInfo = audioDecoderCompat.onInputBufferAvailable(audioDecoderCompat.extractor, inputBuffer); + audioDecoderCompat.decoder.queueInputBuffer(inputBuffersArrayIndex, inputBufferInfo.offset, inputBufferInfo.size, inputBufferInfo.presentationTimeUs, inputBufferInfo.flags); + } + } + + int outputBuffersArrayIndex = 0; + while (outputBuffersArrayIndex != MediaCodec.INFO_TRY_AGAIN_LATER) { + outputBuffersArrayIndex = audioDecoderCompat.decoder.dequeueOutputBuffer(outputBufferInfo, DEQUEUE_TIMEOUT); + if (outputBuffersArrayIndex >= 0) { + outputBuffer = outputBuffersArray[outputBuffersArrayIndex]; + if ((outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0 && outputBufferInfo.size != 0) { + audioDecoderCompat.decoder.releaseOutputBuffer(outputBuffersArrayIndex, false); + } else if (outputBuffer.limit() > 0) { + sampleBuffer = audioDecoderCompat.onOutputBufferAvailable(outputBuffer); + if (audioDecoderCompat.listener != null) { + audioDecoderCompat.listener.onAudioDataAvailable(sampleBuffer); + } + audioDecoderCompat.decoder.releaseOutputBuffer(outputBuffersArrayIndex, false); + } + } else if (outputBuffersArrayIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { + MediaFormat newFormat = audioDecoderCompat.decoder.getOutputFormat(); + audioDecoderCompat.onOutputFormatChanged(newFormat); + } + } + + if (outputBufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) { + if (audioDecoderCompat.listener != null) { + audioDecoderCompat.listener.onDecoderFinish(true); + } + audioDecoderCompat.stop(); + break; + } + } + } +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java index bb7269e57..224c9768c 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java @@ -437,7 +437,7 @@ public class AudioStreamManager extends BaseAudioStreamManager { decoder = new AudioDecoder(audioSource, context.get(), sdlSampleRate, sdlSampleType, decoderListener);
} else {
// this BaseAudioDecoder subclass uses methods deprecated with api 21
- decoder = new AudioDecoderCompat(audioSource, context.get(), sdlSampleRate, sdlSampleType, decoderListener);
+ decoder = new AudioDecoderCompat(internalInterface, audioSource, context.get(), sdlSampleRate, sdlSampleType, decoderListener);
}
synchronized (queue) {
|