Fix for Android crash when playing streaming media

#rb Jack.Porter


#ROBOMERGE-SOURCE: CL 6167581 via CL 6167589 via CL 6168458

[CL 6178432 by jack porter in Main branch]
This commit is contained in:
jack porter
2019-04-30 12:20:44 -04:00
parent 54a88d8f18
commit b25fd54702
2 changed files with 113 additions and 95 deletions

View File

@@ -35,109 +35,131 @@ public class AudioDecoder
public byte[] DecodeAudio(byte[] rawBuffer)
{
byte[] data = null;
if( mAudioCodec != null)
synchronized(this)
{
int inIndex = mAudioCodec.dequeueInputBuffer(-1);
if (inIndex >= 0)
byte[] data = null;
if( mAudioCodec != null)
{
int sampleSize = rawBuffer.length;
ByteBuffer buffer = mAudioCodec.getInputBuffer(inIndex);
buffer.clear();
buffer.put(rawBuffer);
buffer.clear();
int inIndex = mAudioCodec.dequeueInputBuffer(-1);
if (inIndex >= 0)
{
int sampleSize = rawBuffer.length;
ByteBuffer buffer = mAudioCodec.getInputBuffer(inIndex);
buffer.clear();
buffer.put(rawBuffer);
buffer.clear();
mAudioCodec.queueInputBuffer(inIndex, 0, sampleSize, 0, 0);
}
mAudioCodec.queueInputBuffer(inIndex, 0, sampleSize, 0, 0);
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
int outIndex = mAudioCodec.dequeueOutputBuffer(info, 10000);
int outIndex = mAudioCodec.dequeueOutputBuffer(info, 10000);
if (outIndex >= 0)
{
ByteBuffer outBuffer = mAudioCodec.getOutputBuffer(outIndex);
data = new byte[info.size];
switch (outIndex)
{
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
GameActivity.Log.debug("Android Audio Decoder: INFO_OUTPUT_BUFFERS_CHANGED");
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
GameActivity.Log.debug("Android Audio Decoder: New format " + mAudioCodec.getOutputFormat());
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
GameActivity.Log.debug("Android Audio Decoder: dequeueOutputBuffer timed out!");
break;
default:
ByteBuffer outBuffer = mAudioCodec.getOutputBuffer(outIndex);
data = new byte[info.size];
outBuffer.get(data);
outBuffer.clear();
outBuffer.get(data);
outBuffer.clear();
mAudioCodec.releaseOutputBuffer(outIndex, true);
mAudioCodec.releaseOutputBuffer(outIndex, true);
}
}
return data;
}
return data;
}
public void reset()
public void resetCodec()
{
release();
synchronized(this)
{
if (null != mAudioCodec)
{
try
{
mAudioCodec.stop();
mAudioCodec.release();
}
catch(Exception e)
{
e.printStackTrace();
}
};
}
}
public void release()
{
if (null != mAudioCodec)
{
mAudioCodec.stop();
mAudioCodec.release();
}
resetCodec();
}
private boolean CreateCodec()
{
try
synchronized(this)
{
// Create the decoder
mAudioCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);
try
{
// Create the decoder
mAudioCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);
// Media settings
MediaFormat format = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, mSampleRate, mChannelCount);
// Media settings
MediaFormat format = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, mSampleRate, mChannelCount);
// PPS and SPS headers
format.setInteger(MediaFormat.KEY_BIT_RATE, mBitsPerSample);
// decoding params
format.setInteger(MediaFormat.KEY_BIT_RATE, mBitsPerSample);
byte[] bytes = new byte[]{(byte) 0x12, (byte)0x12};
ByteBuffer bb = ByteBuffer.wrap(bytes);
format.setByteBuffer("csd-0", bb);
// PPS and SPS headers
byte[] bytes = new byte[]{(byte) 0x12, (byte)0x12};
ByteBuffer bb = ByteBuffer.wrap(bytes);
format.setByteBuffer("csd-0", bb);
// Configure the decoder
mAudioCodec.configure(format, null, null, 0);
// Configure the decoder
mAudioCodec.configure(format, null, null, 0);
// Start the decoder
mAudioCodec.start();
bIsInitialized = true;
}
catch(Exception e)
{
GameActivity.Log.warn("Android Audio Decoder: CreateCodec failed!");
e.printStackTrace();
return false;
}
// Start the decoder
mAudioCodec.start();
bIsInitialized = true;
}
catch(Exception e)
{
GameActivity.Log.warn("Android Audio Decoder: CreateCodec failed!");
e.printStackTrace();
return false;
}
return true;
return true;
}
}
public boolean updateConfig(int sampleRate, int channelCount, int BitsPerSample, byte[] AacSpecificConfig)
{
bIsInitialized = false;
mSampleRate = sampleRate;
mChannelCount = channelCount;
mBitsPerSample = BitsPerSample;
mAacSpecificConfig = AacSpecificConfig;
if(mAudioCodec != null)
synchronized(this)
{
try
{
mAudioCodec.stop();
mAudioCodec.release();
}
catch(Exception e)
{
e.printStackTrace();
}
GameActivity.Log.warn("Android Audio Decoder: updateConfig channelCount:" + channelCount);
bIsInitialized = false;
mSampleRate = sampleRate;
mChannelCount = channelCount;
mBitsPerSample = BitsPerSample;
mAacSpecificConfig = AacSpecificConfig;
resetCodec();
return CreateCodec();
}
return CreateCodec();
}
}

View File

@@ -200,9 +200,24 @@ public class VideoDecoder
return -1;
}
public void reset()
public void resetCodec()
{
release();
synchronized(this)
{
if (null != mVideoCodec)
{
try
{
// Get an instance of MediaCodec and give it its Mime type
mVideoCodec.stop();
mVideoCodec.release();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
public void release()
@@ -217,11 +232,8 @@ public class VideoDecoder
while (WaitOnBitmapRender) ;
releaseOESTextureRenderer();
}
if (null != mVideoCodec)
{
mVideoCodec.stop();
mVideoCodec.release();
}
resetCodec();
}
private ByteBuffer getSPSPPSHeader()
@@ -305,28 +317,12 @@ public class VideoDecoder
SPS = inSPS;
PPS = inPPS;
release();
if(mVideoCodec == null)
{
if(SwizzlePixels || VulkanRenderer || !SupportsImageExternal)
{
//initBitmapRenderer();
}
return true;
}
try
{
// Get an instance of MediaCodec and give it its Mime type
mVideoCodec.stop();
mVideoCodec.release();
}
catch(Exception e)
{
e.printStackTrace();
}
resetCodec();
return CreateCodec();
}
@@ -370,7 +366,7 @@ public class VideoDecoder
if (!CreateBitmapRenderer())
{
GameActivity.Log.warn("initBitmapRenderer failed to alloc mBitmapRenderer ");
reset();
release();
}
}
}
@@ -1294,7 +1290,7 @@ public class VideoDecoder
if (!CreateOESTextureRenderer(externalTextureId))
{
GameActivity.Log.warn("updateVideoFrame failed to alloc mOESTextureRenderer ");
reset();
release();
return null;
}
}