Remove MediaCodecOperationMode
Remove MediaCodecOperationMode and replace it with a boolean flag to enable/disable asynchronous queueing. PiperOrigin-RevId: 333504817
This commit is contained in:
parent
dd99d23621
commit
3b14b05d93
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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 ≥ 23; if the API level is ≤
|
|
||||||
* 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());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user