Remove MediaCodecOperationMode

Remove MediaCodecOperationMode and replace it with a boolean
flag to enable/disable asynchronous queueing.

PiperOrigin-RevId: 333504817
This commit is contained in:
christosts 2020-09-24 14:50:43 +01:00 committed by kim-vde
parent dd99d23621
commit 3b14b05d93
3 changed files with 17 additions and 112 deletions

View File

@ -28,7 +28,6 @@ import com.google.android.exoplayer2.audio.AudioSink;
import com.google.android.exoplayer2.audio.DefaultAudioSink; import com.google.android.exoplayer2.audio.DefaultAudioSink;
import com.google.android.exoplayer2.audio.DefaultAudioSink.DefaultAudioProcessorChain; import com.google.android.exoplayer2.audio.DefaultAudioSink.DefaultAudioProcessorChain;
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer; import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer;
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector; import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
import com.google.android.exoplayer2.metadata.MetadataOutput; import com.google.android.exoplayer2.metadata.MetadataOutput;
import com.google.android.exoplayer2.metadata.MetadataRenderer; import com.google.android.exoplayer2.metadata.MetadataRenderer;
@ -92,8 +91,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
private long allowedVideoJoiningTimeMs; private long allowedVideoJoiningTimeMs;
private boolean enableDecoderFallback; private boolean enableDecoderFallback;
private MediaCodecSelector mediaCodecSelector; private MediaCodecSelector mediaCodecSelector;
private @MediaCodecRenderer.MediaCodecOperationMode int audioMediaCodecOperationMode; private boolean enableAsyncQueueing;
private @MediaCodecRenderer.MediaCodecOperationMode int videoMediaCodecOperationMode;
private boolean enableFloatOutput; private boolean enableFloatOutput;
private boolean enableAudioTrackPlaybackParams; private boolean enableAudioTrackPlaybackParams;
private boolean enableOffload; private boolean enableOffload;
@ -104,8 +102,6 @@ public class DefaultRenderersFactory implements RenderersFactory {
extensionRendererMode = EXTENSION_RENDERER_MODE_OFF; extensionRendererMode = EXTENSION_RENDERER_MODE_OFF;
allowedVideoJoiningTimeMs = DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS; allowedVideoJoiningTimeMs = DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS;
mediaCodecSelector = MediaCodecSelector.DEFAULT; mediaCodecSelector = MediaCodecSelector.DEFAULT;
audioMediaCodecOperationMode = MediaCodecRenderer.OPERATION_MODE_SYNCHRONOUS;
videoMediaCodecOperationMode = MediaCodecRenderer.OPERATION_MODE_SYNCHRONOUS;
} }
/** /**
@ -151,48 +147,16 @@ public class DefaultRenderersFactory implements RenderersFactory {
} }
/** /**
* Set the {@link MediaCodecRenderer.MediaCodecOperationMode} of {@link MediaCodecAudioRenderer} * Enable asynchronous buffer queueing for both {@link MediaCodecAudioRenderer} and {@link
* instances. * MediaCodecVideoRenderer} instances.
* *
* <p>This method is experimental, and will be renamed or removed in a future release. * <p>This method is experimental, and will be renamed or removed in a future release.
* *
* @param mode The {@link MediaCodecRenderer.MediaCodecOperationMode} to set. * @param enabled Whether asynchronous queueing is enabled.
* @return This factory, for convenience. * @return This factory, for convenience.
*/ */
public DefaultRenderersFactory experimentalSetAudioMediaCodecOperationMode( public DefaultRenderersFactory experimentalEnableAsynchronousBufferQueueing(boolean enabled) {
@MediaCodecRenderer.MediaCodecOperationMode int mode) { enableAsyncQueueing = enabled;
audioMediaCodecOperationMode = mode;
return this;
}
/**
* Set the {@link MediaCodecRenderer.MediaCodecOperationMode} of {@link MediaCodecVideoRenderer}
* instances.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*
* @param mode The {@link MediaCodecRenderer.MediaCodecOperationMode} to set.
* @return This factory, for convenience.
*/
public DefaultRenderersFactory experimentalSetVideoMediaCodecOperationMode(
@MediaCodecRenderer.MediaCodecOperationMode int mode) {
videoMediaCodecOperationMode = mode;
return this;
}
/**
* Set the {@link MediaCodecRenderer.MediaCodecOperationMode} for both {@link
* MediaCodecAudioRenderer} {@link MediaCodecVideoRenderer} instances.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*
* @param mode The {@link MediaCodecRenderer.MediaCodecOperationMode} to set.
* @return This factory, for convenience.
*/
public DefaultRenderersFactory experimentalSetMediaCodecOperationMode(
@MediaCodecRenderer.MediaCodecOperationMode int mode) {
experimentalSetAudioMediaCodecOperationMode(mode);
experimentalSetVideoMediaCodecOperationMode(mode);
return this; return this;
} }
@ -372,7 +336,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
eventHandler, eventHandler,
eventListener, eventListener,
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY); MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
videoRenderer.experimentalSetMediaCodecOperationMode(videoMediaCodecOperationMode); videoRenderer.experimentalEnableAsynchronousBufferQueueing(enableAsyncQueueing);
out.add(videoRenderer); out.add(videoRenderer);
if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) { if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) {
@ -497,7 +461,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
eventHandler, eventHandler,
eventListener, eventListener,
audioSink); audioSink);
audioRenderer.experimentalSetMediaCodecOperationMode(audioMediaCodecOperationMode); audioRenderer.experimentalEnableAsynchronousBufferQueueing(enableAsyncQueueing);
out.add(audioRenderer); out.add(audioRenderer);
if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) { if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) {

View File

@ -22,13 +22,12 @@ import android.media.MediaFormat;
import android.view.Surface; import android.view.Surface;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.decoder.CryptoInfo; import com.google.android.exoplayer2.decoder.CryptoInfo;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.MediaCodecOperationMode;
/** /**
* Abstracts {@link MediaCodec} operations. * Abstracts {@link MediaCodec} operations.
* *
* <p>{@code MediaCodecAdapter} offers a common interface to interact with a {@link MediaCodec} * <p>{@code MediaCodecAdapter} offers a common interface to interact with a {@link MediaCodec}
* regardless of the {@link MediaCodecOperationMode} the {@link MediaCodec} is operating in. * regardless of the mode the {@link MediaCodec} is operating in.
*/ */
public interface MediaCodecAdapter { public interface MediaCodecAdapter {

View File

@ -54,10 +54,8 @@ import com.google.android.exoplayer2.util.TimedValueQueue;
import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.ArrayDeque; import java.util.ArrayDeque;
@ -69,44 +67,6 @@ import java.util.List;
*/ */
public abstract class MediaCodecRenderer extends BaseRenderer { public abstract class MediaCodecRenderer extends BaseRenderer {
/**
* The modes to operate the {@link MediaCodec}.
*
* <p>Allowed values:
*
* <ul>
* <li>{@link #OPERATION_MODE_SYNCHRONOUS}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING}
* </ul>
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@IntDef({
OPERATION_MODE_SYNCHRONOUS,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING,
})
public @interface MediaCodecOperationMode {}
// TODO: Refactor these constants once internal evaluation completed.
// Do not assign values 1, 3 and 5 to a new operation mode until the evaluation is completed,
// otherwise existing clients may operate one of the dropped modes.
// [Internal ref: b/132684114]
/** Operates the {@link MediaCodec} in synchronous mode. */
public static final int OPERATION_MODE_SYNCHRONOUS = 0;
/**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback}
* callbacks to a dedicated thread.
*/
public static final int OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD = 2;
/**
* Same as {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}, and offloads queueing to another
* thread.
*/
public static final int OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING = 4;
/** Thrown when a failure occurs instantiating a decoder. */ /** Thrown when a failure occurs instantiating a decoder. */
public static class DecoderInitializationException extends Exception { public static class DecoderInitializationException extends Exception {
@ -408,7 +368,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private boolean outputStreamEnded; private boolean outputStreamEnded;
private boolean waitingForFirstSampleInFormat; private boolean waitingForFirstSampleInFormat;
private boolean pendingOutputEndOfStream; private boolean pendingOutputEndOfStream;
@MediaCodecOperationMode private int mediaCodecOperationMode; private boolean enableAsynchronousBufferQueueing;
@Nullable private ExoPlaybackException pendingPlaybackException; @Nullable private ExoPlaybackException pendingPlaybackException;
protected DecoderCounters decoderCounters; protected DecoderCounters decoderCounters;
private long outputStreamStartPositionUs; private long outputStreamStartPositionUs;
@ -441,7 +401,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
decodeOnlyPresentationTimestamps = new ArrayList<>(); decodeOnlyPresentationTimestamps = new ArrayList<>();
outputBufferInfo = new MediaCodec.BufferInfo(); outputBufferInfo = new MediaCodec.BufferInfo();
operatingRate = 1f; operatingRate = 1f;
mediaCodecOperationMode = OPERATION_MODE_SYNCHRONOUS;
pendingOutputStreamStartPositionsUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT]; pendingOutputStreamStartPositionsUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT];
pendingOutputStreamOffsetsUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT]; pendingOutputStreamOffsetsUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT];
pendingOutputStreamSwitchTimesUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT]; pendingOutputStreamSwitchTimesUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT];
@ -452,28 +411,16 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} }
/** /**
* Set the mode of operation of the underlying {@link MediaCodec}. * Enable asynchronous input buffer queueing.
*
* <p>Operates the underlying {@link MediaCodec} in asynchronous mode and submits input buffers
* from a separate thread to unblock the playback thread.
* *
* <p>This method is experimental, and will be renamed or removed in a future release. It should * <p>This method is experimental, and will be renamed or removed in a future release. It should
* only be called before the renderer is used. * only be called before the renderer is used.
*
* @param mode The mode of the MediaCodec. The supported modes are:
* <ul>
* <li>{@link #OPERATION_MODE_SYNCHRONOUS}: The {@link MediaCodec} will operate in
* synchronous mode.
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}: The {@link MediaCodec} will
* operate in asynchronous mode and {@link MediaCodec.Callback} callbacks will be routed
* to a dedicated thread. This mode requires API level &ge; 23; if the API level is &le;
* 22, the operation mode will be set to {@link #OPERATION_MODE_SYNCHRONOUS}.
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING}: Same as
* {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD} and, in addition, input buffers
* will be submitted to the {@link MediaCodec} in a separate thread.
* </ul>
* By default, the operation mode is set to {@link
* MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}.
*/ */
public void experimentalSetMediaCodecOperationMode(@MediaCodecOperationMode int mode) { public void experimentalEnableAsynchronousBufferQueueing(boolean enabled) {
mediaCodecOperationMode = mode; enableAsynchronousBufferQueueing = enabled;
} }
@Override @Override
@ -1108,12 +1055,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecInitializingTimestamp = SystemClock.elapsedRealtime(); codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createCodec:" + codecName); TraceUtil.beginSection("createCodec:" + codecName);
codec = MediaCodec.createByCodecName(codecName); codec = MediaCodec.createByCodecName(codecName);
if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD if (enableAsynchronousBufferQueueing && Util.SDK_INT >= 23) {
&& Util.SDK_INT >= 23) {
codecAdapter = new AsynchronousMediaCodecAdapter(codec, getTrackType());
} else if (mediaCodecOperationMode
== OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING
&& Util.SDK_INT >= 23) {
codecAdapter = codecAdapter =
new AsynchronousMediaCodecAdapter( new AsynchronousMediaCodecAdapter(
codec, /* enableAsynchronousQueueing= */ true, getTrackType()); codec, /* enableAsynchronousQueueing= */ true, getTrackType());