Skip to content

Commit

Permalink
AsynchronousMediaCodecAdapter: surface queueing errors sooner
Browse files Browse the repository at this point in the history
The AsynchronousMediaCodecAdapter's queuing thread stores any exceptions
raised by MediaCodec and re-throws them on the next call to
queueInputBuffer()/queueSecureInputBuffer(). However, if MediaCodec
raises and error while queueing, it goes into a failed state and does
not announce available input buffers. If there is no input available
input buffer, the MediaCodecRenderer will never call
queueInputBuffer()/queueSecureInputBuffer(), hence playback is stalled.

This change surfaces the queueing error through the adapter's dequeueing
methods.

PiperOrigin-RevId: 508637346
(cherry picked from commit 7064310)
  • Loading branch information
christosts authored and tonihei committed Feb 28, 2023
1 parent 3cc93b1 commit 3696076
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,13 @@ public void releaseOutputBuffer(int index, long renderTimeStampNs) {

@Override
public int dequeueInputBufferIndex() {
bufferEnqueuer.maybeThrowException();
return asynchronousMediaCodecCallback.dequeueInputBufferIndex();
}

@Override
public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) {
bufferEnqueuer.maybeThrowException();
return asynchronousMediaCodecCallback.dequeueOutputBufferIndex(bufferInfo);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ public void waitUntilQueueingComplete() throws InterruptedException {
blockUntilHandlerThreadIsIdle();
}

private void maybeThrowException() {
/** Throw any exception that occurred on the enqueuer's background queueing thread. */
public void maybeThrowException() {
@Nullable RuntimeException exception = pendingRuntimeException.getAndSet(null);
if (exception != null) {
throw exception;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,12 @@ private void flushInternal() {
// else, pendingOutputFormat may already be non-null following a previous flush, and remains
// set in this case.

// mediaCodecException is not reset to null. If the codec has raised an error, then it remains
// in FAILED_STATE even after flushing.
availableInputBuffers.clear();
availableOutputBuffers.clear();
bufferInfos.clear();
formats.clear();
mediaCodecException = null;
}

@GuardedBy("lock")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ public void dequeueInputBufferIndex_withMediaCodecError_throwsException() throws
assertThrows(IllegalStateException.class, () -> adapter.dequeueInputBufferIndex());
}

@Test
public void dequeueInputBufferIndex_withPendingQueueingError_throwsException() {
// Force MediaCodec to throw an error by attempting to queue input buffer -1.
adapter.queueInputBuffer(
/* index= */ -1,
/* offset= */ 0,
/* size= */ 0,
/* presentationTimeUs= */ 0,
/* flags= */ 0);
shadowOf(queueingThread.getLooper()).idle();

assertThrows(IllegalStateException.class, () -> adapter.dequeueInputBufferIndex());
}

@Test
public void dequeueInputBufferIndex_afterShutdown_returnsTryAgainLater() {
adapter.release();
Expand Down Expand Up @@ -123,6 +137,20 @@ public void dequeueOutputBufferIndex_withMediaCodecError_throwsException() throw
assertThrows(IllegalStateException.class, () -> adapter.dequeueOutputBufferIndex(bufferInfo));
}

@Test
public void dequeueOutputBufferIndex_withPendingQueueingError_throwsException() {
// Force MediaCodec to throw an error by attempting to queue input buffer -1.
adapter.queueInputBuffer(
/* index= */ -1,
/* offset= */ 0,
/* size= */ 0,
/* presentationTimeUs= */ 0,
/* flags= */ 0);
shadowOf(queueingThread.getLooper()).idle();

assertThrows(IllegalStateException.class, () -> adapter.dequeueOutputBufferIndex(bufferInfo));
}

@Test
public void dequeueOutputBufferIndex_afterShutdown_returnsTryAgainLater() {
int index = adapter.dequeueInputBufferIndex();
Expand Down

0 comments on commit 3696076

Please sign in to comment.