Commit 1d4321b8 by christosts Committed by kim-vde

Move ownership of MediaCodec to MediaCodecAdapter

Move ownership of MediaCodec to MediaCodecAdapter so that all MediaCodec
interactions go through MediaCodecAdapter.

PiperOrigin-RevId: 341066926
parent 8b5ecdb9
...@@ -311,7 +311,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -311,7 +311,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override @Override
protected void configureCodec( protected void configureCodec(
MediaCodecInfo codecInfo, MediaCodecInfo codecInfo,
MediaCodecAdapter codecAdapter, MediaCodecAdapter codec,
Format format, Format format,
@Nullable MediaCrypto crypto, @Nullable MediaCrypto crypto,
float codecOperatingRate) { float codecOperatingRate) {
...@@ -319,7 +319,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -319,7 +319,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name); codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name);
MediaFormat mediaFormat = MediaFormat mediaFormat =
getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate); getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate);
codecAdapter.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0); codec.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0);
// Store the input MIME type if we're only using the codec for decryption. // Store the input MIME type if we're only using the codec for decryption.
boolean decryptOnlyCodecEnabled = boolean decryptOnlyCodecEnabled =
MimeTypes.AUDIO_RAW.equals(codecInfo.mimeType) MimeTypes.AUDIO_RAW.equals(codecInfo.mimeType)
...@@ -330,7 +330,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -330,7 +330,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override @Override
@KeepCodecResult @KeepCodecResult
protected int canKeepCodec( protected int canKeepCodec(
MediaCodec codec, MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) { MediaCodecAdapter codec, MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) {
if (getCodecMaxInputSize(codecInfo, newFormat) > codecMaxInputSize) { if (getCodecMaxInputSize(codecInfo, newFormat) > codecMaxInputSize) {
return KEEP_CODEC_RESULT_NO; return KEEP_CODEC_RESULT_NO;
} }
...@@ -558,7 +558,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -558,7 +558,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
protected boolean processOutputBuffer( protected boolean processOutputBuffer(
long positionUs, long positionUs,
long elapsedRealtimeUs, long elapsedRealtimeUs,
@Nullable MediaCodec codec, @Nullable MediaCodecAdapter codec,
@Nullable ByteBuffer buffer, @Nullable ByteBuffer buffer,
int bufferIndex, int bufferIndex,
int bufferFlags, int bufferFlags,
......
...@@ -56,6 +56,7 @@ import java.nio.ByteBuffer; ...@@ -56,6 +56,7 @@ import java.nio.ByteBuffer;
private final MediaCodec codec; private final MediaCodec codec;
private final AsynchronousMediaCodecCallback asynchronousMediaCodecCallback; private final AsynchronousMediaCodecCallback asynchronousMediaCodecCallback;
private final AsynchronousMediaCodecBufferEnqueuer bufferEnqueuer; private final AsynchronousMediaCodecBufferEnqueuer bufferEnqueuer;
private boolean codecReleased;
@State private int state; @State private int state;
/** /**
...@@ -162,6 +163,7 @@ import java.nio.ByteBuffer; ...@@ -162,6 +163,7 @@ import java.nio.ByteBuffer;
@Override @Override
public void release() { public void release() {
try {
if (state == STATE_STARTED) { if (state == STATE_STARTED) {
bufferEnqueuer.shutdown(); bufferEnqueuer.shutdown();
} }
...@@ -169,11 +171,12 @@ import java.nio.ByteBuffer; ...@@ -169,11 +171,12 @@ import java.nio.ByteBuffer;
asynchronousMediaCodecCallback.shutdown(); asynchronousMediaCodecCallback.shutdown();
} }
state = STATE_SHUT_DOWN; state = STATE_SHUT_DOWN;
} finally {
if (!codecReleased) {
codec.release();
codecReleased = true;
}
} }
@Override
public MediaCodec getCodec() {
return codec;
} }
@Override @Override
......
...@@ -157,9 +157,6 @@ public interface MediaCodecAdapter { ...@@ -157,9 +157,6 @@ public interface MediaCodecAdapter {
/** Releases the adapter and the underlying {@link MediaCodec}. */ /** Releases the adapter and the underlying {@link MediaCodec}. */
void release(); void release();
/** Returns the {@link MediaCodec} instance of this adapter. */
MediaCodec getCodec();
/** /**
* Registers a callback to be invoked when an output frame is rendered on the output surface. * Registers a callback to be invoked when an output frame is rendered on the output surface.
* *
......
...@@ -138,11 +138,7 @@ import java.nio.ByteBuffer; ...@@ -138,11 +138,7 @@ import java.nio.ByteBuffer;
public void release() { public void release() {
inputByteBuffers = null; inputByteBuffers = null;
outputByteBuffers = null; outputByteBuffers = null;
} codec.release();
@Override
public MediaCodec getCodec() {
return codec;
} }
@Override @Override
......
...@@ -461,7 +461,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -461,7 +461,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
setSurface((Surface) message); setSurface((Surface) message);
} else if (messageType == MSG_SET_SCALING_MODE) { } else if (messageType == MSG_SET_SCALING_MODE) {
scalingMode = (Integer) message; scalingMode = (Integer) message;
MediaCodec codec = getCodec(); @Nullable MediaCodecAdapter codec = getCodec();
if (codec != null) { if (codec != null) {
codec.setVideoScalingMode(scalingMode); codec.setVideoScalingMode(scalingMode);
} }
...@@ -493,7 +493,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -493,7 +493,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
updateSurfaceFrameRate(/* isNewSurface= */ true); updateSurfaceFrameRate(/* isNewSurface= */ true);
@State int state = getState(); @State int state = getState();
MediaCodec codec = getCodec(); @Nullable MediaCodecAdapter codec = getCodec();
if (codec != null) { if (codec != null) {
if (Util.SDK_INT >= 23 && surface != null && !codecNeedsSetOutputSurfaceWorkaround) { if (Util.SDK_INT >= 23 && surface != null && !codecNeedsSetOutputSurfaceWorkaround) {
setOutputSurfaceV23(codec, surface); setOutputSurfaceV23(codec, surface);
...@@ -537,7 +537,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -537,7 +537,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Override @Override
protected void configureCodec( protected void configureCodec(
MediaCodecInfo codecInfo, MediaCodecInfo codecInfo,
MediaCodecAdapter codecAdapter, MediaCodecAdapter codec,
Format format, Format format,
@Nullable MediaCrypto crypto, @Nullable MediaCrypto crypto,
float codecOperatingRate) { float codecOperatingRate) {
...@@ -560,16 +560,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -560,16 +560,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
surface = dummySurface; surface = dummySurface;
} }
codecAdapter.configure(mediaFormat, surface, crypto, 0); codec.configure(mediaFormat, surface, crypto, 0);
if (Util.SDK_INT >= 23 && tunneling) { if (Util.SDK_INT >= 23 && tunneling) {
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codecAdapter.getCodec()); tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
} }
} }
@Override @Override
@KeepCodecResult @KeepCodecResult
protected int canKeepCodec( protected int canKeepCodec(
MediaCodec codec, MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) { MediaCodecAdapter codec, MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) {
if (newFormat.width > codecMaxValues.width if (newFormat.width > codecMaxValues.width
|| newFormat.height > codecMaxValues.height || newFormat.height > codecMaxValues.height
|| getMaxInputSize(codecInfo, newFormat) > codecMaxValues.inputSize) { || getMaxInputSize(codecInfo, newFormat) > codecMaxValues.inputSize) {
...@@ -651,7 +651,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -651,7 +651,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Override @Override
protected void onOutputFormatChanged(Format format, @Nullable MediaFormat mediaFormat) { protected void onOutputFormatChanged(Format format, @Nullable MediaFormat mediaFormat) {
@Nullable MediaCodec codec = getCodec(); @Nullable MediaCodecAdapter codec = getCodec();
if (codec != null) { if (codec != null) {
// Must be applied each time the output format changes. // Must be applied each time the output format changes.
codec.setVideoScalingMode(scalingMode); codec.setVideoScalingMode(scalingMode);
...@@ -729,7 +729,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -729,7 +729,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
protected boolean processOutputBuffer( protected boolean processOutputBuffer(
long positionUs, long positionUs,
long elapsedRealtimeUs, long elapsedRealtimeUs,
@Nullable MediaCodec codec, @Nullable MediaCodecAdapter codec,
@Nullable ByteBuffer buffer, @Nullable ByteBuffer buffer,
int bufferIndex, int bufferIndex,
int bufferFlags, int bufferFlags,
...@@ -942,7 +942,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -942,7 +942,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @param index The index of the output buffer to skip. * @param index The index of the output buffer to skip.
* @param presentationTimeUs The presentation time of the output buffer, in microseconds. * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
*/ */
protected void skipOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) { protected void skipOutputBuffer(MediaCodecAdapter codec, int index, long presentationTimeUs) {
TraceUtil.beginSection("skipVideoBuffer"); TraceUtil.beginSection("skipVideoBuffer");
codec.releaseOutputBuffer(index, false); codec.releaseOutputBuffer(index, false);
TraceUtil.endSection(); TraceUtil.endSection();
...@@ -956,7 +956,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -956,7 +956,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @param index The index of the output buffer to drop. * @param index The index of the output buffer to drop.
* @param presentationTimeUs The presentation time of the output buffer, in microseconds. * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
*/ */
protected void dropOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) { protected void dropOutputBuffer(MediaCodecAdapter codec, int index, long presentationTimeUs) {
TraceUtil.beginSection("dropVideoBuffer"); TraceUtil.beginSection("dropVideoBuffer");
codec.releaseOutputBuffer(index, false); codec.releaseOutputBuffer(index, false);
TraceUtil.endSection(); TraceUtil.endSection();
...@@ -978,7 +978,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -978,7 +978,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @throws ExoPlaybackException If an error occurs flushing the codec. * @throws ExoPlaybackException If an error occurs flushing the codec.
*/ */
protected boolean maybeDropBuffersToKeyframe( protected boolean maybeDropBuffersToKeyframe(
MediaCodec codec, MediaCodecAdapter codec,
int index, int index,
long presentationTimeUs, long presentationTimeUs,
long positionUs, long positionUs,
...@@ -1037,7 +1037,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1037,7 +1037,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @param index The index of the output buffer to drop. * @param index The index of the output buffer to drop.
* @param presentationTimeUs The presentation time of the output buffer, in microseconds. * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
*/ */
protected void renderOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) { protected void renderOutputBuffer(MediaCodecAdapter codec, int index, long presentationTimeUs) {
maybeNotifyVideoSizeChanged(); maybeNotifyVideoSizeChanged();
TraceUtil.beginSection("releaseOutputBuffer"); TraceUtil.beginSection("releaseOutputBuffer");
codec.releaseOutputBuffer(index, true); codec.releaseOutputBuffer(index, true);
...@@ -1059,7 +1059,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1059,7 +1059,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
*/ */
@RequiresApi(21) @RequiresApi(21)
protected void renderOutputBufferV21( protected void renderOutputBufferV21(
MediaCodec codec, int index, long presentationTimeUs, long releaseTimeNs) { MediaCodecAdapter codec, int index, long presentationTimeUs, long releaseTimeNs) {
maybeNotifyVideoSizeChanged(); maybeNotifyVideoSizeChanged();
TraceUtil.beginSection("releaseOutputBuffer"); TraceUtil.beginSection("releaseOutputBuffer");
codec.releaseOutputBuffer(index, releaseTimeNs); codec.releaseOutputBuffer(index, releaseTimeNs);
...@@ -1132,7 +1132,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1132,7 +1132,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// OnFrameRenderedListenerV23.onFrameRenderedListener for tunneled playback on API level 23 and // OnFrameRenderedListenerV23.onFrameRenderedListener for tunneled playback on API level 23 and
// above. // above.
if (Util.SDK_INT >= 23 && tunneling) { if (Util.SDK_INT >= 23 && tunneling) {
MediaCodec codec = getCodec(); @Nullable MediaCodecAdapter codec = getCodec();
// If codec is null then the listener will be instantiated in configureCodec. // If codec is null then the listener will be instantiated in configureCodec.
if (codec != null) { if (codec != null) {
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec); tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
...@@ -1213,14 +1213,14 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1213,14 +1213,14 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
@RequiresApi(29) @RequiresApi(29)
private static void setHdr10PlusInfoV29(MediaCodec codec, byte[] hdr10PlusInfo) { private static void setHdr10PlusInfoV29(MediaCodecAdapter codec, byte[] hdr10PlusInfo) {
Bundle codecParameters = new Bundle(); Bundle codecParameters = new Bundle();
codecParameters.putByteArray(MediaCodec.PARAMETER_KEY_HDR10_PLUS_INFO, hdr10PlusInfo); codecParameters.putByteArray(MediaCodec.PARAMETER_KEY_HDR10_PLUS_INFO, hdr10PlusInfo);
codec.setParameters(codecParameters); codec.setParameters(codecParameters);
} }
@RequiresApi(23) @RequiresApi(23)
protected void setOutputSurfaceV23(MediaCodec codec, Surface surface) { protected void setOutputSurfaceV23(MediaCodecAdapter codec, Surface surface) {
codec.setOutputSurface(surface); codec.setOutputSurface(surface);
} }
...@@ -1762,19 +1762,19 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1762,19 +1762,19 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@RequiresApi(23) @RequiresApi(23)
private final class OnFrameRenderedListenerV23 private final class OnFrameRenderedListenerV23
implements MediaCodec.OnFrameRenderedListener, Handler.Callback { implements MediaCodecAdapter.OnFrameRenderedListener, Handler.Callback {
private static final int HANDLE_FRAME_RENDERED = 0; private static final int HANDLE_FRAME_RENDERED = 0;
private final Handler handler; private final Handler handler;
public OnFrameRenderedListenerV23(MediaCodec codec) { public OnFrameRenderedListenerV23(MediaCodecAdapter codec) {
handler = Util.createHandlerForCurrentLooper(/* callback= */ this); handler = Util.createHandlerForCurrentLooper(/* callback= */ this);
codec.setOnFrameRenderedListener(/* listener= */ this, handler); codec.setOnFrameRenderedListener(/* listener= */ this, handler);
} }
@Override @Override
public void onFrameRendered(MediaCodec codec, long presentationTimeUs, long nanoTime) { public void onFrameRendered(MediaCodecAdapter codec, long presentationTimeUs, long nanoTime) {
// Workaround bug in MediaCodec that causes deadlock if you call directly back into the // Workaround bug in MediaCodec that causes deadlock if you call directly back into the
// MediaCodec from this listener method. // MediaCodec from this listener method.
// Deadlock occurs because MediaCodec calls this listener method holding a lock, // Deadlock occurs because MediaCodec calls this listener method holding a lock,
......
...@@ -18,7 +18,6 @@ package com.google.android.exoplayer2.playbacktests.gts; ...@@ -18,7 +18,6 @@ package com.google.android.exoplayer2.playbacktests.gts;
import static java.lang.Math.max; import static java.lang.Math.max;
import android.content.Context; import android.content.Context;
import android.media.MediaCodec;
import android.media.MediaCrypto; import android.media.MediaCrypto;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.os.Handler; import android.os.Handler;
...@@ -133,7 +132,7 @@ import java.util.ArrayList; ...@@ -133,7 +132,7 @@ import java.util.ArrayList;
@Override @Override
protected void configureCodec( protected void configureCodec(
MediaCodecInfo codecInfo, MediaCodecInfo codecInfo,
MediaCodecAdapter codecAdapter, MediaCodecAdapter codec,
Format format, Format format,
MediaCrypto crypto, MediaCrypto crypto,
float operatingRate) { float operatingRate) {
...@@ -143,7 +142,7 @@ import java.util.ArrayList; ...@@ -143,7 +142,7 @@ import java.util.ArrayList;
// dropped frames allowed, this is not desired behavior. Hence we skip (rather than drop) // dropped frames allowed, this is not desired behavior. Hence we skip (rather than drop)
// frames up to the current playback position [Internal: b/66494991]. // frames up to the current playback position [Internal: b/66494991].
skipToPositionBeforeRenderingFirstFrame = getState() == Renderer.STATE_STARTED; skipToPositionBeforeRenderingFirstFrame = getState() == Renderer.STATE_STARTED;
super.configureCodec(codecInfo, codecAdapter, format, crypto, operatingRate); super.configureCodec(codecInfo, codec, format, crypto, operatingRate);
} }
@Override @Override
...@@ -200,7 +199,7 @@ import java.util.ArrayList; ...@@ -200,7 +199,7 @@ import java.util.ArrayList;
protected boolean processOutputBuffer( protected boolean processOutputBuffer(
long positionUs, long positionUs,
long elapsedRealtimeUs, long elapsedRealtimeUs,
@Nullable MediaCodec codec, @Nullable MediaCodecAdapter codec,
ByteBuffer buffer, ByteBuffer buffer,
int bufferIndex, int bufferIndex,
int bufferFlags, int bufferFlags,
...@@ -231,7 +230,7 @@ import java.util.ArrayList; ...@@ -231,7 +230,7 @@ import java.util.ArrayList;
} }
@Override @Override
protected void renderOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) { protected void renderOutputBuffer(MediaCodecAdapter codec, int index, long presentationTimeUs) {
skipToPositionBeforeRenderingFirstFrame = false; skipToPositionBeforeRenderingFirstFrame = false;
super.renderOutputBuffer(codec, index, presentationTimeUs); super.renderOutputBuffer(codec, index, presentationTimeUs);
} }
...@@ -239,7 +238,7 @@ import java.util.ArrayList; ...@@ -239,7 +238,7 @@ import java.util.ArrayList;
@RequiresApi(21) @RequiresApi(21)
@Override @Override
protected void renderOutputBufferV21( protected void renderOutputBufferV21(
MediaCodec codec, int index, long presentationTimeUs, long releaseTimeNs) { MediaCodecAdapter codec, int index, long presentationTimeUs, long releaseTimeNs) {
skipToPositionBeforeRenderingFirstFrame = false; skipToPositionBeforeRenderingFirstFrame = false;
super.renderOutputBufferV21(codec, index, presentationTimeUs, releaseTimeNs); super.renderOutputBufferV21(codec, index, presentationTimeUs, releaseTimeNs);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment