mirror of
https://github.com/samsonjs/media.git
synced 2026-03-29 10:05:48 +00:00
Add flag to force synchronization in async queueing
Add experiment flag to force synchronization between queueing threads in AsynchronousMediaCodecAdapter. PiperOrigin-RevId: 341431481
This commit is contained in:
parent
9473fda056
commit
9e98a680da
6 changed files with 71 additions and 8 deletions
|
|
@ -92,6 +92,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||
private boolean enableDecoderFallback;
|
||||
private MediaCodecSelector mediaCodecSelector;
|
||||
private boolean enableAsyncQueueing;
|
||||
private boolean forceAsyncQueueingSynchronizationWorkaround;
|
||||
private boolean enableSynchronizeCodecInteractionsWithQueueing;
|
||||
private boolean enableFloatOutput;
|
||||
private boolean enableAudioTrackPlaybackParams;
|
||||
|
|
@ -161,6 +162,24 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the asynchronous queueing synchronization workaround.
|
||||
*
|
||||
* <p>When enabled, the queueing threads for {@link MediaCodec} instances will synchronize on a
|
||||
* shared lock when submitting buffers to the respective {@link MediaCodec}.
|
||||
*
|
||||
* <p>This method is experimental, and will be renamed or removed in a future release.
|
||||
*
|
||||
* @param enabled Whether the asynchronous queueing synchronization workaround is enabled by
|
||||
* default.
|
||||
* @return This factory, for convenience.
|
||||
*/
|
||||
public DefaultRenderersFactory experimentalSetForceAsyncQueueingSynchronizationWorkaround(
|
||||
boolean enabled) {
|
||||
this.forceAsyncQueueingSynchronizationWorkaround = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable synchronizing codec interactions with asynchronous buffer queueing.
|
||||
*
|
||||
|
|
@ -353,6 +372,8 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||
eventListener,
|
||||
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
|
||||
videoRenderer.experimentalSetAsynchronousBufferQueueingEnabled(enableAsyncQueueing);
|
||||
videoRenderer.experimentalSetForceAsyncQueueingSynchronizationWorkaround(
|
||||
forceAsyncQueueingSynchronizationWorkaround);
|
||||
videoRenderer.experimentalSetSynchronizeCodecInteractionsWithQueueingEnabled(
|
||||
enableSynchronizeCodecInteractionsWithQueueing);
|
||||
out.add(videoRenderer);
|
||||
|
|
@ -480,6 +501,8 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||
eventListener,
|
||||
audioSink);
|
||||
audioRenderer.experimentalSetAsynchronousBufferQueueingEnabled(enableAsyncQueueing);
|
||||
audioRenderer.experimentalSetForceAsyncQueueingSynchronizationWorkaround(
|
||||
forceAsyncQueueingSynchronizationWorkaround);
|
||||
audioRenderer.experimentalSetSynchronizeCodecInteractionsWithQueueingEnabled(
|
||||
enableSynchronizeCodecInteractionsWithQueueing);
|
||||
out.add(audioRenderer);
|
||||
|
|
|
|||
|
|
@ -72,11 +72,15 @@ import java.nio.ByteBuffer;
|
|||
* {@link MediaCodec}.
|
||||
*/
|
||||
/* package */ AsynchronousMediaCodecAdapter(
|
||||
MediaCodec codec, int trackType, boolean synchronizeCodecInteractionsWithQueueing) {
|
||||
MediaCodec codec,
|
||||
int trackType,
|
||||
boolean forceQueueingSynchronizationWorkaround,
|
||||
boolean synchronizeCodecInteractionsWithQueueing) {
|
||||
this(
|
||||
codec,
|
||||
new HandlerThread(createCallbackThreadLabel(trackType)),
|
||||
new HandlerThread(createQueueingThreadLabel(trackType)),
|
||||
forceQueueingSynchronizationWorkaround,
|
||||
synchronizeCodecInteractionsWithQueueing);
|
||||
}
|
||||
|
||||
|
|
@ -85,10 +89,13 @@ import java.nio.ByteBuffer;
|
|||
MediaCodec codec,
|
||||
HandlerThread callbackThread,
|
||||
HandlerThread enqueueingThread,
|
||||
boolean forceQueueingSynchronizationWorkaround,
|
||||
boolean synchronizeCodecInteractionsWithQueueing) {
|
||||
this.codec = codec;
|
||||
this.asynchronousMediaCodecCallback = new AsynchronousMediaCodecCallback(callbackThread);
|
||||
this.bufferEnqueuer = new AsynchronousMediaCodecBufferEnqueuer(codec, enqueueingThread);
|
||||
this.bufferEnqueuer =
|
||||
new AsynchronousMediaCodecBufferEnqueuer(
|
||||
codec, enqueueingThread, forceQueueingSynchronizationWorkaround);
|
||||
this.synchronizeCodecInteractionsWithQueueing = synchronizeCodecInteractionsWithQueueing;
|
||||
this.state = STATE_CREATED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,18 +68,29 @@ class AsynchronousMediaCodecBufferEnqueuer {
|
|||
* @param codec The {@link MediaCodec} to submit input buffers to.
|
||||
* @param queueingThread The {@link HandlerThread} to use for queueing buffers.
|
||||
*/
|
||||
public AsynchronousMediaCodecBufferEnqueuer(MediaCodec codec, HandlerThread queueingThread) {
|
||||
this(codec, queueingThread, /* conditionVariable= */ new ConditionVariable());
|
||||
public AsynchronousMediaCodecBufferEnqueuer(
|
||||
MediaCodec codec,
|
||||
HandlerThread queueingThread,
|
||||
boolean forceQueueingSynchronizationWorkaround) {
|
||||
this(
|
||||
codec,
|
||||
queueingThread,
|
||||
forceQueueingSynchronizationWorkaround,
|
||||
/* conditionVariable= */ new ConditionVariable());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
/* package */ AsynchronousMediaCodecBufferEnqueuer(
|
||||
MediaCodec codec, HandlerThread handlerThread, ConditionVariable conditionVariable) {
|
||||
MediaCodec codec,
|
||||
HandlerThread handlerThread,
|
||||
boolean forceQueueingSynchronizationWorkaround,
|
||||
ConditionVariable conditionVariable) {
|
||||
this.codec = codec;
|
||||
this.handlerThread = handlerThread;
|
||||
this.conditionVariable = conditionVariable;
|
||||
pendingRuntimeException = new AtomicReference<>();
|
||||
needsSynchronizationWorkaround = needsSynchronizationWorkaround();
|
||||
needsSynchronizationWorkaround =
|
||||
forceQueueingSynchronizationWorkaround || needsSynchronizationWorkaround();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
private boolean waitingForFirstSampleInFormat;
|
||||
private boolean pendingOutputEndOfStream;
|
||||
private boolean enableAsynchronousBufferQueueing;
|
||||
private boolean forceAsyncQueueingSynchronizationWorkaround;
|
||||
private boolean enableSynchronizeCodecInteractionsWithQueueing;
|
||||
@Nullable private ExoPlaybackException pendingPlaybackException;
|
||||
protected DecoderCounters decoderCounters;
|
||||
|
|
@ -417,6 +418,19 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
enableAsynchronousBufferQueueing = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the asynchronous queueing synchronization workaround.
|
||||
*
|
||||
* <p>When enabled, the queueing threads for {@link MediaCodec} instance will synchronize on a
|
||||
* shared lock when submitting buffers to the respective {@link MediaCodec}.
|
||||
*
|
||||
* <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.
|
||||
*/
|
||||
public void experimentalSetForceAsyncQueueingSynchronizationWorkaround(boolean enabled) {
|
||||
this.forceAsyncQueueingSynchronizationWorkaround = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable synchronizing codec interactions with asynchronous buffer queueing.
|
||||
*
|
||||
|
|
@ -1068,7 +1082,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
if (enableAsynchronousBufferQueueing && Util.SDK_INT >= 23) {
|
||||
codecAdapter =
|
||||
new AsynchronousMediaCodecAdapter(
|
||||
codec, getTrackType(), enableSynchronizeCodecInteractionsWithQueueing);
|
||||
codec,
|
||||
getTrackType(),
|
||||
forceAsyncQueueingSynchronizationWorkaround,
|
||||
enableSynchronizeCodecInteractionsWithQueueing);
|
||||
} else {
|
||||
codecAdapter = new SynchronousMediaCodecAdapter(codec);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public class AsynchronousMediaCodecAdapterTest {
|
|||
codec,
|
||||
callbackThread,
|
||||
queueingThread,
|
||||
/* forceQueueingSynchronizationWorkaround= */ false,
|
||||
/* synchronizeCodecInteractionsWithQueueing= */ false);
|
||||
bufferInfo = new MediaCodec.BufferInfo();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,11 @@ public class AsynchronousMediaCodecBufferEnqueuerTest {
|
|||
codec.start();
|
||||
handlerThread = new TestHandlerThread("TestHandlerThread");
|
||||
enqueuer =
|
||||
new AsynchronousMediaCodecBufferEnqueuer(codec, handlerThread, mockConditionVariable);
|
||||
new AsynchronousMediaCodecBufferEnqueuer(
|
||||
codec,
|
||||
handlerThread,
|
||||
/* forceQueueingSynchronizationWorkaround= */ false,
|
||||
mockConditionVariable);
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
|||
Loading…
Reference in a new issue