Example usage for android.media MediaCodec BUFFER_FLAG_CODEC_CONFIG

List of usage examples for android.media MediaCodec BUFFER_FLAG_CODEC_CONFIG

Introduction

In this page you can find the example usage for android.media MediaCodec BUFFER_FLAG_CODEC_CONFIG.

Prototype

int BUFFER_FLAG_CODEC_CONFIG

To view the source code for android.media MediaCodec BUFFER_FLAG_CODEC_CONFIG.

Click Source Link

Document

This indicated that the buffer marked as such contains codec initialization / codec specific data instead of media data.

Usage

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
            }
        }
    }
}