/** * Processes a new output format. */ private void processOutputFormat() throws ExoPlaybackException { MediaFormat format = codec.getOutputFormat(); if (codecAdaptationWorkaroundMode != ADAPTATION_WORKAROUND_MODE_NEVER && format.getInteger(MediaFormat.KEY_WIDTH) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT && format.getInteger(MediaFormat.KEY_HEIGHT) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT) { // We assume this format changed event was caused by the adaptation workaround. shouldSkipAdaptationWorkaroundOutputBuffer = true; return; } if (codecNeedsMonoChannelCountWorkaround) { format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1); } onOutputFormatChanged(codec, format); }
MediaFormat newFormat = mEncoder.getOutputFormat(); if (VERBOSE) Log.i(TAG, "encoder output format changed: " + newFormat);
private int drainDecoder(long timeoutUs) { if (mIsDecoderEOS) return DRAIN_STATE_NONE; int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: mAudioChannel.setActualDecodedFormat(mDecoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { mIsDecoderEOS = true; mAudioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (mBufferInfo.size > 0) { mAudioChannel.drainDecoderBufferAndQueue(result, mBufferInfo.presentationTimeUs); } return DRAIN_STATE_CONSUMED; }
if (mActualOutputFormat != null) throw new RuntimeException("Video output format changed twice."); mActualOutputFormat = mEncoder.getOutputFormat(); mMuxer.setOutputFormat(QueuedMuxer.SampleType.VIDEO, mActualOutputFormat); return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
throw new RuntimeException("Audio output format changed twice."); mActualOutputFormat = mEncoder.getOutputFormat(); mMuxer.setOutputFormat(SAMPLE_TYPE, mActualOutputFormat); return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY;
public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { mDecoderOutputVideoFormat = codec.getOutputFormat(); if (VERBOSE) { Log.d(TAG, "video decoder: output format changed: " + mDecoderOutputVideoFormat); } } public void onInputBufferAvailable(MediaCodec codec, int index) {
public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { mDecoderOutputAudioFormat = codec.getOutputFormat(); if (VERBOSE) { Log.d(TAG, "audio decoder: output format changed: " + mDecoderOutputAudioFormat); } } public void onInputBufferAvailable(MediaCodec codec, int index) {
public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { if (VERBOSE) Log.d(TAG, "audio encoder: output format changed"); if (mOutputAudioTrack >= 0) { fail("audio encoder changed its output format again?"); } mEncoderOutputAudioFormat = codec.getOutputFormat(); setupMuxer(); } public void onInputBufferAvailable(MediaCodec codec, int index) {
public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { if (VERBOSE) Log.d(TAG, "video encoder: output format changed"); if (mOutputVideoTrack >= 0) { fail("video encoder changed its output format again?"); } mEncoderOutputVideoFormat = codec.getOutputFormat(); setupMuxer(); } public void onInputBufferAvailable(MediaCodec codec, int index) {
@Override public void run() { mOutputFormatChangedListener .outputFormatChanged(MediaCodecWrapper.this, mDecoder.getOutputFormat()); } });
@Override public void run() { mOutputFormatChangedListener .outputFormatChanged(MediaCodecWrapper.this, mDecoder.getOutputFormat()); } });
@Override public void run() { mOutputFormatChangedListener .outputFormatChanged(MediaCodecWrapper.this, mDecoder.getOutputFormat()); } });
private void resetOutputFormat() { // should happen before receiving buffers, and should only happen once if (mMuxerStarted) { throw new IllegalStateException("output format already changed!"); } MediaFormat newFormat = mMediaCodec.getOutputFormat(); Log.i(TAG, "output format changed.\n new format: " + newFormat.toString()); mVideoTrackIndex = mMuxer.addTrack(newFormat); mMuxer.start(); mMuxerStarted = true; Log.i(TAG, "started media muxer, videoIndex=" + mVideoTrackIndex); }
private int drainDecoder(long timeoutUs) { if (isDecoderEOS) return DRAIN_STATE_NONE; int result = decoder.dequeueOutputBuffer(bufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: audioChannel.setActualDecodedFormat(decoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { isDecoderEOS = true; audioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (bufferInfo.size > 0) { audioChannel.drainDecoderBufferAndQueue(result, bufferInfo.presentationTimeUs / timeScale); } return DRAIN_STATE_CONSUMED; }
private int drainDecoder(long timeoutUs) { if (mIsDecoderEOS) return DRAIN_STATE_NONE; int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: mAudioChannel.setActualDecodedFormat(mDecoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { mIsDecoderEOS = true; mAudioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (mBufferInfo.size > 0) { mAudioChannel.drainDecoderBufferAndQueue(result, mBufferInfo.presentationTimeUs); } return DRAIN_STATE_CONSUMED; }
private int drainDecoder(long timeoutUs) { if (mIsDecoderEOS) return DRAIN_STATE_NONE; int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: mAudioChannel.setActualDecodedFormat(mDecoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { mIsDecoderEOS = true; mAudioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (mBufferInfo.size > 0) { mAudioChannel.drainDecoderBufferAndQueue(result, mBufferInfo.presentationTimeUs); } return DRAIN_STATE_CONSUMED; }
private int drainDecoder(long timeoutUs) { if (isDecoderEOS) return DRAIN_STATE_NONE; int result = decoder.dequeueOutputBuffer(bufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: audioChannel.setActualDecodedFormat(decoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { isDecoderEOS = true; audioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (bufferInfo.size > 0) { audioChannel.drainDecoderBufferAndQueue(result, bufferInfo.presentationTimeUs / timeScale); } return DRAIN_STATE_CONSUMED; }
private int drainDecoder(long timeoutUs) { if (mIsDecoderEOS) return DRAIN_STATE_NONE; int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: mAudioChannelUgly.setActualDecodedFormat(mDecoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { mIsDecoderEOS = true; mAudioChannelUgly.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (mBufferInfo.size > 0) { mAudioChannelUgly.drainDecoderBufferAndQueue(result, mBufferInfo.presentationTimeUs); } return DRAIN_STATE_CONSUMED; }
private int drainDecoder(long timeoutUs) { if (mIsDecoderEOS) return DRAIN_STATE_NONE; int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: mAudioChannel.setActualDecodedFormat(mDecoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { mIsDecoderEOS = true; mAudioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (mBufferInfo.size > 0) { mAudioChannel.drainDecoderBufferAndQueue(result, mBufferInfo.presentationTimeUs); } return DRAIN_STATE_CONSUMED; }
private int drainDecoder(long timeoutUs) { if (mIsDecoderEOS) return DRAIN_STATE_NONE; int result = mDecoder.dequeueOutputBuffer(mBufferInfo, timeoutUs); switch (result) { case MediaCodec.INFO_TRY_AGAIN_LATER: return DRAIN_STATE_NONE; case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: mAudioChannel.setActualDecodedFormat(mDecoder.getOutputFormat()); case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: return DRAIN_STATE_SHOULD_RETRY_IMMEDIATELY; } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { mIsDecoderEOS = true; mAudioChannel.drainDecoderBufferAndQueue(AudioChannel.BUFFER_INDEX_END_OF_STREAM, 0); } else if (mBufferInfo.size > 0) { mAudioChannel.drainDecoderBufferAndQueue(result, mBufferInfo.presentationTimeUs); } return DRAIN_STATE_CONSUMED; }