diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/AsynchronousMediaCodecAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/AsynchronousMediaCodecAdapter.java index 18c7b1c201..6fb49f7cd4 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/AsynchronousMediaCodecAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/AsynchronousMediaCodecAdapter.java @@ -63,6 +63,18 @@ import com.google.android.exoplayer2.util.Assertions; codecStartRunnable.run(); } + @Override + public void queueInputBuffer( + int index, int offset, int size, long presentationTimeUs, int flags) { + codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags); + } + + @Override + public void queueSecureInputBuffer( + int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) { + codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags); + } + @Override public int dequeueInputBufferIndex() { if (flushing) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java index 5130b785d9..d231a247de 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java @@ -33,8 +33,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; * A {@link MediaCodecAdapter} that operates the underlying {@link MediaCodec} in asynchronous mode * and routes {@link MediaCodec.Callback} callbacks on a dedicated Thread that is managed * internally. - * - *

After creating an instance, you need to call {@link #start()} to start the internal Thread. */ @RequiresApi(23) /* package */ final class DedicatedThreadAsyncMediaCodecAdapter extends MediaCodec.Callback @@ -88,6 +86,22 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; state = STATE_STARTED; } + @Override + public void queueInputBuffer( + int index, int offset, int size, long presentationTimeUs, int flags) { + // This method does not need to be synchronized because it does not interact with the + // mediaCodecAsyncCallback. + codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags); + } + + @Override + public void queueSecureInputBuffer( + int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) { + // This method does not need to be synchronized because it does not interact with the + // mediaCodecAsyncCallback. + codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags); + } + @Override public synchronized int dequeueInputBufferIndex() { if (isFlushing()) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecAdapter.java index 2f347de0ae..ce1ba41533 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecAdapter.java @@ -65,6 +65,27 @@ import android.media.MediaFormat; */ MediaFormat getOutputFormat(); + /** + * Submit an input buffer for decoding. + * + *

The {@code index} must be an input buffer index that has been obtained from a previous call + * to {@link #dequeueInputBufferIndex()}. + * + * @see MediaCodec#queueInputBuffer + */ + void queueInputBuffer(int index, int offset, int size, long presentationTimeUs, int flags); + + /** + * Submit an input buffer that is potentially encrypted for decoding. + * + *

The {@code index} must be an input buffer index that has been obtained from a previous call + * to {@link #dequeueInputBufferIndex()}. + * + * @see MediaCodec#queueSecureInputBuffer + */ + void queueSecureInputBuffer( + int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags); + /** * Flushes the {@code MediaCodecAdapter}. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index 760195cfd8..ecb6bbf718 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -1136,7 +1136,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { // Do nothing. } else { codecReceivedEos = true; - codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); + codecAdapter.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); resetInputBuffer(); } codecDrainState = DRAIN_STATE_WAIT_END_OF_STREAM; @@ -1146,7 +1146,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { if (codecNeedsAdaptationWorkaroundBuffer) { codecNeedsAdaptationWorkaroundBuffer = false; buffer.data.put(ADAPTATION_WORKAROUND_BUFFER); - codec.queueInputBuffer(inputIndex, 0, ADAPTATION_WORKAROUND_BUFFER.length, 0, 0); + codecAdapter.queueInputBuffer(inputIndex, 0, ADAPTATION_WORKAROUND_BUFFER.length, 0, 0); resetInputBuffer(); codecReceivedBuffers = true; return true; @@ -1210,7 +1210,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { // Do nothing. } else { codecReceivedEos = true; - codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); + codecAdapter.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); resetInputBuffer(); } } catch (CryptoException e) { @@ -1261,9 +1261,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer { if (bufferEncrypted) { MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(buffer, adaptiveReconfigurationBytes); - codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0); + codecAdapter.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0); } else { - codec.queueInputBuffer(inputIndex, 0, buffer.data.limit(), presentationTimeUs, 0); + codecAdapter.queueInputBuffer(inputIndex, 0, buffer.data.limit(), presentationTimeUs, 0); } resetInputBuffer(); codecReceivedBuffers = true; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsyncMediaCodecAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsyncMediaCodecAdapter.java index af26f532c6..d04b9ce1b6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsyncMediaCodecAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsyncMediaCodecAdapter.java @@ -46,8 +46,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; * MediaCodec.Callback} methods will be accessed by the internal Thread. This class is * NOT generally thread-safe in the sense that its public methods cannot be called * by any thread. - * - *

After creating an instance, you need to call {@link #start()} to start the internal Thread. */ @RequiresApi(23) /* package */ final class MultiLockAsyncMediaCodecAdapter extends MediaCodec.Callback @@ -161,6 +159,22 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } } + @Override + public void queueInputBuffer( + int index, int offset, int size, long presentationTimeUs, int flags) { + // This method does not need to be synchronized because it is not interacting with + // MediaCodec.Callback and dequeueing buffers operations. + codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags); + } + + @Override + public void queueSecureInputBuffer( + int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) { + // This method does not need to be synchronized because it is not interacting with + // MediaCodec.Callback and dequeueing buffers operations. + codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags); + } + @Override public void flush() { synchronized (objectStateLock) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/SynchronousMediaCodecAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/SynchronousMediaCodecAdapter.java index ee9ab857cc..84d2ba1ba6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/SynchronousMediaCodecAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/SynchronousMediaCodecAdapter.java @@ -50,6 +50,18 @@ import android.media.MediaFormat; return codec.getOutputFormat(); } + @Override + public void queueInputBuffer( + int index, int offset, int size, long presentationTimeUs, int flags) { + codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags); + } + + @Override + public void queueSecureInputBuffer( + int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) { + codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags); + } + @Override public void flush() { codec.flush();