Remove experimental synchronization on async buffer queuing
PiperOrigin-RevId: 591273508
This commit is contained in:
parent
29d7dd1ec9
commit
f47c4e33ec
@ -163,22 +163,6 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable synchronizing codec interactions with asynchronous buffer queueing.
|
|
||||||
*
|
|
||||||
* <p>This method is experimental, and will be renamed or removed in a future release.
|
|
||||||
*
|
|
||||||
* @param enabled Whether codec interactions will be synchronized with asynchronous buffer
|
|
||||||
* queueing.
|
|
||||||
* @return This factory, for convenience.
|
|
||||||
*/
|
|
||||||
@CanIgnoreReturnValue
|
|
||||||
public DefaultRenderersFactory experimentalSetSynchronizeCodecInteractionsWithQueueingEnabled(
|
|
||||||
boolean enabled) {
|
|
||||||
codecAdapterFactory.experimentalSetSynchronizeCodecInteractionsWithQueueingEnabled(enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether to enable fallback to lower-priority decoders if decoder initialization fails.
|
* Sets whether to enable fallback to lower-priority decoders if decoder initialization fails.
|
||||||
* This may result in using a decoder that is less efficient or slower than the primary decoder.
|
* This may result in using a decoder that is less efficient or slower than the primary decoder.
|
||||||
|
@ -53,35 +53,27 @@ import java.nio.ByteBuffer;
|
|||||||
public static final class Factory implements MediaCodecAdapter.Factory {
|
public static final class Factory implements MediaCodecAdapter.Factory {
|
||||||
private final Supplier<HandlerThread> callbackThreadSupplier;
|
private final Supplier<HandlerThread> callbackThreadSupplier;
|
||||||
private final Supplier<HandlerThread> queueingThreadSupplier;
|
private final Supplier<HandlerThread> queueingThreadSupplier;
|
||||||
private final boolean synchronizeCodecInteractionsWithQueueing;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an factory for {@link AsynchronousMediaCodecAdapter} instances.
|
* Creates an factory for {@link AsynchronousMediaCodecAdapter} instances.
|
||||||
*
|
*
|
||||||
* @param trackType One of {@link C#TRACK_TYPE_AUDIO} or {@link C#TRACK_TYPE_VIDEO}. Used for
|
* @param trackType One of {@link C#TRACK_TYPE_AUDIO} or {@link C#TRACK_TYPE_VIDEO}. Used for
|
||||||
* labelling the internal thread accordingly.
|
* labelling the internal thread accordingly.
|
||||||
* @param synchronizeCodecInteractionsWithQueueing Whether the adapter should synchronize {@link
|
|
||||||
* MediaCodec} interactions with asynchronous buffer queueing. When {@code true}, codec
|
|
||||||
* interactions will wait until all input buffers pending queueing wil be submitted to the
|
|
||||||
* {@link MediaCodec}.
|
|
||||||
*/
|
*/
|
||||||
public Factory(@C.TrackType int trackType, boolean synchronizeCodecInteractionsWithQueueing) {
|
public Factory(@C.TrackType int trackType) {
|
||||||
this(
|
this(
|
||||||
/* callbackThreadSupplier= */ () ->
|
/* callbackThreadSupplier= */ () ->
|
||||||
new HandlerThread(createCallbackThreadLabel(trackType)),
|
new HandlerThread(createCallbackThreadLabel(trackType)),
|
||||||
/* queueingThreadSupplier= */ () ->
|
/* queueingThreadSupplier= */ () ->
|
||||||
new HandlerThread(createQueueingThreadLabel(trackType)),
|
new HandlerThread(createQueueingThreadLabel(trackType)));
|
||||||
synchronizeCodecInteractionsWithQueueing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
/* package */ Factory(
|
/* package */ Factory(
|
||||||
Supplier<HandlerThread> callbackThreadSupplier,
|
Supplier<HandlerThread> callbackThreadSupplier,
|
||||||
Supplier<HandlerThread> queueingThreadSupplier,
|
Supplier<HandlerThread> queueingThreadSupplier) {
|
||||||
boolean synchronizeCodecInteractionsWithQueueing) {
|
|
||||||
this.callbackThreadSupplier = callbackThreadSupplier;
|
this.callbackThreadSupplier = callbackThreadSupplier;
|
||||||
this.queueingThreadSupplier = queueingThreadSupplier;
|
this.queueingThreadSupplier = queueingThreadSupplier;
|
||||||
this.synchronizeCodecInteractionsWithQueueing = synchronizeCodecInteractionsWithQueueing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -95,10 +87,7 @@ import java.nio.ByteBuffer;
|
|||||||
codec = MediaCodec.createByCodecName(codecName);
|
codec = MediaCodec.createByCodecName(codecName);
|
||||||
codecAdapter =
|
codecAdapter =
|
||||||
new AsynchronousMediaCodecAdapter(
|
new AsynchronousMediaCodecAdapter(
|
||||||
codec,
|
codec, callbackThreadSupplier.get(), queueingThreadSupplier.get());
|
||||||
callbackThreadSupplier.get(),
|
|
||||||
queueingThreadSupplier.get(),
|
|
||||||
synchronizeCodecInteractionsWithQueueing);
|
|
||||||
TraceUtil.endSection();
|
TraceUtil.endSection();
|
||||||
codecAdapter.initialize(
|
codecAdapter.initialize(
|
||||||
configuration.mediaFormat,
|
configuration.mediaFormat,
|
||||||
@ -130,19 +119,14 @@ 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 final boolean synchronizeCodecInteractionsWithQueueing;
|
|
||||||
private boolean codecReleased;
|
private boolean codecReleased;
|
||||||
private @State int state;
|
private @State int state;
|
||||||
|
|
||||||
private AsynchronousMediaCodecAdapter(
|
private AsynchronousMediaCodecAdapter(
|
||||||
MediaCodec codec,
|
MediaCodec codec, HandlerThread callbackThread, HandlerThread enqueueingThread) {
|
||||||
HandlerThread callbackThread,
|
|
||||||
HandlerThread enqueueingThread,
|
|
||||||
boolean synchronizeCodecInteractionsWithQueueing) {
|
|
||||||
this.codec = codec;
|
this.codec = codec;
|
||||||
this.asynchronousMediaCodecCallback = new AsynchronousMediaCodecCallback(callbackThread);
|
this.asynchronousMediaCodecCallback = new AsynchronousMediaCodecCallback(callbackThread);
|
||||||
this.bufferEnqueuer = new AsynchronousMediaCodecBufferEnqueuer(codec, enqueueingThread);
|
this.bufferEnqueuer = new AsynchronousMediaCodecBufferEnqueuer(codec, enqueueingThread);
|
||||||
this.synchronizeCodecInteractionsWithQueueing = synchronizeCodecInteractionsWithQueueing;
|
|
||||||
this.state = STATE_CREATED;
|
this.state = STATE_CREATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +234,6 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOnFrameRenderedListener(OnFrameRenderedListener listener, Handler handler) {
|
public void setOnFrameRenderedListener(OnFrameRenderedListener listener, Handler handler) {
|
||||||
maybeBlockOnQueueing();
|
|
||||||
codec.setOnFrameRenderedListener(
|
codec.setOnFrameRenderedListener(
|
||||||
(codec, presentationTimeUs, nanoTime) ->
|
(codec, presentationTimeUs, nanoTime) ->
|
||||||
listener.onFrameRendered(
|
listener.onFrameRendered(
|
||||||
@ -260,26 +243,22 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOutputSurface(Surface surface) {
|
public void setOutputSurface(Surface surface) {
|
||||||
maybeBlockOnQueueing();
|
|
||||||
codec.setOutputSurface(surface);
|
codec.setOutputSurface(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setParameters(Bundle params) {
|
public void setParameters(Bundle params) {
|
||||||
maybeBlockOnQueueing();
|
|
||||||
codec.setParameters(params);
|
codec.setParameters(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVideoScalingMode(@C.VideoScalingMode int scalingMode) {
|
public void setVideoScalingMode(@C.VideoScalingMode int scalingMode) {
|
||||||
maybeBlockOnQueueing();
|
|
||||||
codec.setVideoScalingMode(scalingMode);
|
codec.setVideoScalingMode(scalingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@RequiresApi(26)
|
@RequiresApi(26)
|
||||||
public PersistableBundle getMetrics() {
|
public PersistableBundle getMetrics() {
|
||||||
maybeBlockOnQueueing();
|
|
||||||
return codec.getMetrics();
|
return codec.getMetrics();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,19 +272,6 @@ import java.nio.ByteBuffer;
|
|||||||
asynchronousMediaCodecCallback.onOutputFormatChanged(codec, format);
|
asynchronousMediaCodecCallback.onOutputFormatChanged(codec, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeBlockOnQueueing() {
|
|
||||||
if (synchronizeCodecInteractionsWithQueueing) {
|
|
||||||
try {
|
|
||||||
bufferEnqueuer.waitUntilQueueingComplete();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
// The playback thread should not be interrupted. Raising this as an
|
|
||||||
// IllegalStateException.
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String createCallbackThreadLabel(@C.TrackType int trackType) {
|
private static String createCallbackThreadLabel(@C.TrackType int trackType) {
|
||||||
return createThreadLabel(trackType, /* prefix= */ "ExoPlayer:MediaCodecAsyncAdapter:");
|
return createThreadLabel(trackType, /* prefix= */ "ExoPlayer:MediaCodecAsyncAdapter:");
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
|
|||||||
private static final String TAG = "DMCodecAdapterFactory";
|
private static final String TAG = "DMCodecAdapterFactory";
|
||||||
|
|
||||||
private @Mode int asynchronousMode;
|
private @Mode int asynchronousMode;
|
||||||
private boolean enableSynchronizeCodecInteractionsWithQueueing;
|
|
||||||
|
|
||||||
public DefaultMediaCodecAdapterFactory() {
|
public DefaultMediaCodecAdapterFactory() {
|
||||||
asynchronousMode = MODE_DEFAULT;
|
asynchronousMode = MODE_DEFAULT;
|
||||||
@ -84,18 +83,6 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable synchronizing codec interactions with asynchronous buffer queueing.
|
|
||||||
*
|
|
||||||
* <p>This method is experimental, and will be renamed or removed in a future release.
|
|
||||||
*
|
|
||||||
* @param enabled Whether codec interactions will be synchronized with asynchronous buffer
|
|
||||||
* queueing.
|
|
||||||
*/
|
|
||||||
public void experimentalSetSynchronizeCodecInteractionsWithQueueingEnabled(boolean enabled) {
|
|
||||||
enableSynchronizeCodecInteractionsWithQueueing = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configuration)
|
public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configuration)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@ -108,8 +95,7 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
|
|||||||
"Creating an asynchronous MediaCodec adapter for track type "
|
"Creating an asynchronous MediaCodec adapter for track type "
|
||||||
+ Util.getTrackTypeString(trackType));
|
+ Util.getTrackTypeString(trackType));
|
||||||
AsynchronousMediaCodecAdapter.Factory factory =
|
AsynchronousMediaCodecAdapter.Factory factory =
|
||||||
new AsynchronousMediaCodecAdapter.Factory(
|
new AsynchronousMediaCodecAdapter.Factory(trackType);
|
||||||
trackType, enableSynchronizeCodecInteractionsWithQueueing);
|
|
||||||
return factory.createAdapter(configuration);
|
return factory.createAdapter(configuration);
|
||||||
}
|
}
|
||||||
return new SynchronousMediaCodecAdapter.Factory().createAdapter(configuration);
|
return new SynchronousMediaCodecAdapter.Factory().createAdapter(configuration);
|
||||||
|
@ -53,8 +53,7 @@ public class AsynchronousMediaCodecAdapterTest {
|
|||||||
adapter =
|
adapter =
|
||||||
new AsynchronousMediaCodecAdapter.Factory(
|
new AsynchronousMediaCodecAdapter.Factory(
|
||||||
/* callbackThreadSupplier= */ () -> callbackThread,
|
/* callbackThreadSupplier= */ () -> callbackThread,
|
||||||
/* queueingThreadSupplier= */ () -> queueingThread,
|
/* queueingThreadSupplier= */ () -> queueingThread)
|
||||||
/* synchronizeCodecInteractionsWithQueueing= */ false)
|
|
||||||
.createAdapter(configuration);
|
.createAdapter(configuration);
|
||||||
bufferInfo = new MediaCodec.BufferInfo();
|
bufferInfo = new MediaCodec.BufferInfo();
|
||||||
// After starting the MediaCodec, the ShadowMediaCodec offers input buffer 0. We advance the
|
// After starting the MediaCodec, the ShadowMediaCodec offers input buffer 0. We advance the
|
||||||
@ -222,6 +221,6 @@ public class AsynchronousMediaCodecAdapterTest {
|
|||||||
Integer.TYPE, Integer.TYPE, String.class);
|
Integer.TYPE, Integer.TYPE, String.class);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
return constructor.newInstance(
|
return constructor.newInstance(
|
||||||
/* errorCode= */ 0, /* actionCode= */ 0, /* detailMessage= */ "error from codec");
|
/* errorCode */ 0, /* actionCode */ 0, /* detailMessage */ "error from codec");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user