List of usage examples for android.media MediaCodec BUFFER_FLAG_CODEC_CONFIG
int BUFFER_FLAG_CODEC_CONFIG
To view the source code for android.media MediaCodec BUFFER_FLAG_CODEC_CONFIG.
Click Source Link
From source file:com.serenegiant.media.TLMediaEncoder.java
/** * drain encoded data and write them to intermediate file *//*ww w. ja v a2s . co m*/ protected void drain() { if (mMediaCodec == null) return; int encoderStatus; while (mIsRunning && (mState == STATE_RUNNING)) { // get encoded data with maximum timeout duration of TIMEOUT_USEC(=10[msec]) try { encoderStatus = mMediaCodec.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC); } catch (IllegalStateException e) { break; } if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { // wait 5 counts(=TIMEOUT_USEC x 5 = 50msec) until data/EOS come if (!mIsEOS) { break; // out of while } } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { if (DEBUG) Log.v(TAG, "INFO_OUTPUT_BUFFERS_CHANGED"); // this should not come when encoding encoderOutputBuffers = mMediaCodec.getOutputBuffers(); } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { if (DEBUG) Log.v(TAG, "INFO_OUTPUT_FORMAT_CHANGED"); // this status indicate the output format of codec is changed // this should come only once before actual encoded data // but this status never come on Android4.3 or less // and in that case, you should treat when MediaCodec.BUFFER_FLAG_CODEC_CONFIG come. // get output format from codec and pass them to muxer // getOutputFormat should be called after INFO_OUTPUT_FORMAT_CHANGED otherwise crash. if (mSequence == 0) { // sequence 0 is for saving MediaFormat final MediaFormat format = mMediaCodec.getOutputFormat(); // API >= 16 try { writeFormat(mCurrentOutputStream, mConfigFormat, format); // changeOutputStream(); } catch (IOException e) { Log.e(TAG, "drain:failed to write MediaFormat ", e); } } } else if (encoderStatus < 0) { // unexpected status if (DEBUG) Log.w(TAG, "drain:unexpected result from encoder#dequeueOutputBuffer: " + encoderStatus); } else { final ByteBuffer encodedData = encoderOutputBuffers[encoderStatus]; if (encodedData == null) { // this never should come...may be a MediaCodec internal error throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null"); } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { // You should set output format to muxer here when you target Android4.3 or less // but MediaCodec#getOutputFormat can not call here(because INFO_OUTPUT_FORMAT_CHANGED don't come yet) // therefor we should expand and prepare output format from buffer data. // This sample is for API>=18(>=Android 4.3), just ignore this flag here if (DEBUG) Log.d(TAG, "drain:BUFFER_FLAG_CODEC_CONFIG"); mBufferInfo.size = 0; } if (mBufferInfo.size != 0) { mFrameCounts++; if (mCurrentOutputStream == null) { throw new RuntimeException("drain:temporary file not ready"); } // write encoded data to muxer(need to adjust presentationTimeUs. mBufferInfo.presentationTimeUs = getPTSUs(); try { writeStream(mCurrentOutputStream, mSequence, mFrameCounts, mBufferInfo, encodedData, writeBuffer); } catch (IOException e) { throw new RuntimeException("drain:failed to writeStream:" + e.getMessage()); } prevOutputPTSUs = mBufferInfo.presentationTimeUs; } // return buffer to encoder mMediaCodec.releaseOutputBuffer(encoderStatus, false); if ((mNumFrames > 0) && (mFrameCounts >= mNumFrames)) { setState(STATE_PAUSING, null); // request pause } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { // when EOS come. mIsRunning = false; break; // out of while } } } }