Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDL 0297] Add function to transmit audio data of AudioStream in time division #1556

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ public IAudioStreamListener startAudioStream(SdlSession session) {
public void onComplete(boolean success) {
assertEquals(true, success);

manager.pushResource(com.smartdevicelink.test.R.raw.test_audio_square_250hz_80amp_1s, mockFileListener);
manager.pushResource(com.smartdevicelink.test.R.raw.test_audio_square_250hz_80amp_1s, mockFileListener, true);
}
});

Expand Down Expand Up @@ -567,7 +567,7 @@ public void onComplete(boolean success) {
public void onComplete(boolean success) {
assertEquals(true, success);

manager.pushResource(com.smartdevicelink.test.R.raw.test_audio_square_250hz_80amp_1s, mockFileListener);
manager.pushResource(com.smartdevicelink.test.R.raw.test_audio_square_250hz_80amp_1s, mockFileListener, true);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.smartdevicelink.util.DebugTool;

import java.nio.ByteBuffer;
import java.util.ArrayList;

/**
* The audio decoder to decode a single audio file to PCM.
Expand Down Expand Up @@ -75,30 +76,37 @@ public void start() {
decoder.setCallback(new MediaCodec.Callback() {
@Override
public void onInputBufferAvailable(@NonNull MediaCodec mediaCodec, int i) {
ByteBuffer inputBuffer = mediaCodec.getInputBuffer(i);
if (inputBuffer == null) return;

MediaCodec.BufferInfo info = AudioDecoder.super.onInputBufferAvailable(extractor, inputBuffer);
mediaCodec.queueInputBuffer(i, info.offset, info.size, info.presentationTimeUs, info.flags);
try {
ByteBuffer inputBuffer = mediaCodec.getInputBuffer(i);
if (inputBuffer == null) return;

MediaCodec.BufferInfo info = AudioDecoder.super.onInputBufferAvailable(extractor, inputBuffer);
mediaCodec.queueInputBuffer(i, info.offset, info.size, info.presentationTimeUs, info.flags);
} catch (Exception e) {
e.printStackTrace();
listener.onDecoderError(e);
}
}

@Override
public void onOutputBufferAvailable(@NonNull MediaCodec mediaCodec, int i, @NonNull MediaCodec.BufferInfo bufferInfo) {
ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(i);
if (outputBuffer == null) return;

if (outputBuffer.limit() > 0) {
SampleBuffer targetSampleBuffer = AudioDecoder.super.onOutputBufferAvailable(outputBuffer);
AudioDecoder.this.listener.onAudioDataAvailable(targetSampleBuffer);
} else {
DebugTool.logWarning(TAG, "output buffer empty. Chance that silence was detected");
}

mediaCodec.releaseOutputBuffer(i, false);

if (bufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
listener.onDecoderFinish(true);
stop();
try {
ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(i);
if (outputBuffer == null) return;
ArrayList<SampleBuffer> targetSampleBufferList = null;
if (outputBuffer.limit() > 0) {
targetSampleBufferList = AudioDecoder.super.onOutputBufferAvailable(outputBuffer);
} else {
DebugTool.logWarning(TAG, "output buffer empty. Chance that silence was detected");
}
AudioDecoder.this.listener.onAudioDataAvailable(targetSampleBufferList,bufferInfo.flags);
mediaCodec.releaseOutputBuffer(i, false);
if (bufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
listener.onDecoderFinish(true);
stop();
}
} catch (Exception e) {
e.printStackTrace();
listener.onDecoderError(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.ArrayList;

/**
* The audio decoder to decode a single audio file to PCM.
Expand Down Expand Up @@ -87,6 +88,14 @@ public void start() {
}
}

@Override
public void stop() {
if (mThread != null) {
mThread.interrupt();
mThread = null;
}
super.stop();
}

/**
* Runnable to decode audio data
Expand All @@ -107,63 +116,85 @@ private static class DecoderRunnable implements Runnable {
@Override
public void run() {
final AudioDecoderCompat reference = weakReference.get();
if (reference == null) {
DebugTool.logWarning(TAG, "AudioDecoderCompat reference was null");
return;
try {
if (reference == null) {
DebugTool.logWarning(TAG, "AudioDecoderCompat reference was null");
return;
}
if(reference.decoder == null){
DebugTool.logWarning(TAG, "AudioDecoderCompat decoder was null");
return;
}
while (reference!= null && !reference.mThread.isInterrupted()) {
if( AudioDecoder(reference,reference.decoder.getInputBuffers(),reference.decoder.getOutputBuffers())){
break;
}
}
} catch (Exception e) {
DebugTool.logWarning(TAG, "DecoderRunnable Exception:" + e);
} finally {
if (reference != null && reference.mThread != null) {
try {
reference.mThread.interrupt();
} catch (Exception e) {
e.printStackTrace();
} finally {
reference.mThread = null;
}
}
}
final ByteBuffer[] inputBuffersArray = reference.decoder.getInputBuffers();
final ByteBuffer[] outputBuffersArray = reference.decoder.getOutputBuffers();
}

boolean AudioDecoder(final AudioDecoderCompat reference,final ByteBuffer[] inputBuffersArray,final ByteBuffer[] outputBuffersArray){
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) {
int inputBuffersArrayIndex = 0;
while (inputBuffersArrayIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
try {
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);
}
} catch (Exception e) {
return true;
}

int outputBuffersArrayIndex = 0;
while (outputBuffersArrayIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
}
int outputBuffersArrayIndex = 0;
while (outputBuffersArrayIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
try {
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);
ArrayList<SampleBuffer> sampleBufferList = reference.onOutputBufferAvailable(outputBuffer);
if (reference.listener != null) {
reference.listener.onAudioDataAvailable(sampleBuffer);
reference.listener.onAudioDataAvailable(sampleBufferList, outputBufferInfo.flags);
}
reference.decoder.releaseOutputBuffer(outputBuffersArrayIndex, false);
}
} else if (outputBuffersArrayIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = reference.decoder.getOutputFormat();
reference.onOutputFormatChanged(newFormat);
}
} catch (Exception e) {
return true;
}

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;
}
}
if (outputBufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
reference.listener.onAudioDataAvailable(null,outputBufferInfo.flags);
if (reference.listener != null) {
reference.listener.onDecoderFinish(true);
}
reference.stop();
return true;
}
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
*/
package com.smartdevicelink.managers.audio;

import java.util.ArrayList;

/**
* An interface for the audio decoder classes.
* The caller using the audio decoder will be
Expand All @@ -40,10 +42,9 @@
public interface AudioDecoderListener {
/**
* Notifies that decoded audio data is available.
*
* @param sampleBuffer The sample buffer holding the decoded audio data.
* @param sampleBufferList The sample buffer holding the decoded audio data.
*/
void onAudioDataAvailable(SampleBuffer sampleBuffer);
void onAudioDataAvailable(ArrayList<SampleBuffer> sampleBufferList, int flags);

/**
* Notifies that the audio decoding is finished.
Expand Down
Loading