diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f0284dcf69..66675195fb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -4,6 +4,10 @@ * Common Library: * ExoPlayer: + * `MediaCodecRenderer.onProcessedStreamChange()` can now be called for + every media item. Previously it was not called for the first one. Use + `MediaCodecRenderer.experimentalEnableProcessedStreamChangedAtStart()` + to enable this. * Transformer: * Track Selection: * Extractors: diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java index f6faa72871..0d87f1c793 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java @@ -411,6 +411,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { private OutputStreamInfo outputStreamInfo; private long lastProcessedOutputBufferTimeUs; private boolean needToNotifyOutputFormatChangeAfterStreamChange; + private boolean experimentalEnableProcessedStreamChangedAtStart; /** * @param trackType The {@link C.TrackType track type} that the renderer handles. @@ -513,6 +514,16 @@ public abstract class MediaCodecRenderer extends BaseRenderer { elapsedRealtimeUs); } + /** + * Enables the renderer to invoke {@link #onProcessedStreamChange()} on the first stream. + * + *
When not enabled, {@link #onProcessedStreamChange()} is invoked from the second stream + * onwards. + */ + public void experimentalEnableProcessedStreamChangedAtStart() { + this.experimentalEnableProcessedStreamChangedAtStart = true; + } + /** * Returns minimum time playback must advance in order for the {@link #render} call to make * progress. @@ -724,6 +735,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer { setOutputStreamInfo( new OutputStreamInfo( /* previousStreamLastBufferTimeUs= */ C.TIME_UNSET, startPositionUs, offsetUs)); + if (experimentalEnableProcessedStreamChangedAtStart) { + onProcessedStreamChange(); + } } else if (pendingOutputStreamChanges.isEmpty() && (largestQueuedPresentationTimeUs == C.TIME_UNSET || (lastProcessedOutputBufferTimeUs != C.TIME_UNSET diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/MediaCodecRendererTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/MediaCodecRendererTest.java index 45c0f177bc..50fefa62fa 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/MediaCodecRendererTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/MediaCodecRendererTest.java @@ -103,6 +103,7 @@ public class MediaCodecRendererTest { InOrder inOrder = inOrder(renderer); inOrder.verify(renderer).onOutputStreamOffsetUsChanged(0); + inOrder.verify(renderer).onProcessedStreamChange(); inOrder.verify(renderer).onOutputFormatChanged(eq(format1), any()); inOrder.verify(renderer).onProcessedOutputBuffer(0); inOrder.verify(renderer).onProcessedOutputBuffer(100); @@ -163,6 +164,7 @@ public class MediaCodecRendererTest { InOrder inOrder = inOrder(renderer); inOrder.verify(renderer).onOutputStreamOffsetUsChanged(0); + inOrder.verify(renderer).onProcessedStreamChange(); inOrder.verify(renderer).onOutputFormatChanged(eq(format1), any()); inOrder.verify(renderer).onProcessedOutputBuffer(0); inOrder.verify(renderer).onProcessedOutputBuffer(100); @@ -226,6 +228,7 @@ public class MediaCodecRendererTest { InOrder inOrder = inOrder(renderer); inOrder.verify(renderer).onOutputStreamOffsetUsChanged(0); + inOrder.verify(renderer).onProcessedStreamChange(); inOrder.verify(renderer).onOutputFormatChanged(eq(format1), any()); inOrder.verify(renderer).onProcessedOutputBuffer(0); inOrder.verify(renderer).onProcessedOutputBuffer(100); @@ -287,6 +290,7 @@ public class MediaCodecRendererTest { InOrder inOrder = inOrder(renderer); inOrder.verify(renderer).onOutputStreamOffsetUsChanged(0); + inOrder.verify(renderer).onProcessedStreamChange(); inOrder.verify(renderer).onOutputStreamOffsetUsChanged(0); inOrder.verify(renderer).onProcessedStreamChange(); inOrder.verify(renderer).onOutputFormatChanged(eq(format2), any()); @@ -356,6 +360,7 @@ public class MediaCodecRendererTest { InOrder inOrder = inOrder(renderer); inOrder.verify(renderer).onOutputStreamOffsetUsChanged(0); + inOrder.verify(renderer).onProcessedStreamChange(); inOrder.verify(renderer).onOutputFormatChanged(eq(format1), any()); inOrder.verify(renderer).onProcessedOutputBuffer(0); inOrder.verify(renderer).onProcessedOutputBuffer(100); @@ -496,6 +501,7 @@ public class MediaCodecRendererTest { /* forceSecure= */ false)), /* enableDecoderFallback= */ false, /* assumedMinimumCodecOperatingRate= */ 44100); + experimentalEnableProcessedStreamChangedAtStart(); } @Override