/** @param frameCallback */ private final void handleOutputVideo(final IFrameCallback frameCallback) { // if (DEBUG) Log.v(TAG, "handleDrainVideo:"); while (mIsRunning && !mVideoOutputDone) { final int decoderStatus = mVideoMediaCodec.dequeueOutputBuffer(mVideoBufferInfo, TIMEOUT_USEC); if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { return; } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { mVideoOutputBuffers = mVideoMediaCodec.getOutputBuffers(); if (DEBUG) Log.d(TAG, "INFO_OUTPUT_BUFFERS_CHANGED:"); } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { final MediaFormat newFormat = mVideoMediaCodec.getOutputFormat(); if (DEBUG) Log.d(TAG, "video decoder output format changed: " + newFormat); } else if (decoderStatus < 0) { throw new RuntimeException( "unexpected result from video decoder.dequeueOutputBuffer: " + decoderStatus); } else { // decoderStatus >= 0 boolean doRender = false; if (mVideoBufferInfo.size > 0) { doRender = (mVideoBufferInfo.size != 0) && !internal_write_video( mVideoOutputBuffers[decoderStatus], 0, mVideoBufferInfo.size, mVideoBufferInfo.presentationTimeUs); if (doRender) { if (!frameCallback.onFrameAvailable(mVideoBufferInfo.presentationTimeUs)) mVideoStartTime = adjustPresentationTime( mVideoSync, mVideoStartTime, mVideoBufferInfo.presentationTimeUs); } } mVideoMediaCodec.releaseOutputBuffer(decoderStatus, doRender); if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { if (DEBUG) Log.d(TAG, "video:output EOS"); synchronized (mSync) { mVideoOutputDone = true; mSync.notifyAll(); } } } } }