From 003738866017d29eb882e8316ff46b928723c393 Mon Sep 17 00:00:00 2001 From: kimvde Date: Tue, 3 Dec 2024 03:26:19 -0800 Subject: [PATCH] Simplify VideoSink.handleInputFrame This method was taking positionUs and elapsedRealtimeUs parameters and throwing a VideoSinkException because it was calling render() to make room for a new input frame. Instead of doing that, this CL makes sure render() is called before handleInputFrame() in the renderer (even though it may not make a significant difference). PiperOrigin-RevId: 702273587 --- .../exoplayer/video/DefaultVideoSink.java | 6 +--- .../video/MediaCodecVideoRenderer.java | 36 ++++++++----------- .../video/PlaybackVideoGraphWrapper.java | 10 +----- .../media3/exoplayer/video/VideoSink.java | 11 +----- .../transformer/BufferingVideoSink.java | 10 ++---- 5 files changed, 20 insertions(+), 53 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/DefaultVideoSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/DefaultVideoSink.java index 847e62f633..4dbb5ef80c 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/DefaultVideoSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/DefaultVideoSink.java @@ -205,11 +205,7 @@ import java.util.concurrent.Executor; @Override public boolean handleInputFrame( - long framePresentationTimeUs, - boolean isLastFrame, - long positionUs, - long elapsedRealtimeUs, - VideoFrameHandler videoFrameHandler) { + long framePresentationTimeUs, boolean isLastFrame, VideoFrameHandler videoFrameHandler) { throw new UnsupportedOperationException(); } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java index e126d171b6..569646c47f 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java @@ -1096,15 +1096,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer @CallSuper @Override public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { - super.render(positionUs, elapsedRealtimeUs); if (videoSink != null) { try { + // Drain the sink to make room for a new input frame. videoSink.render(positionUs, elapsedRealtimeUs); } catch (VideoSink.VideoSinkException e) { throw createRendererException( e, e.format, PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED); } } + super.render(positionUs, elapsedRealtimeUs); } @CallSuper @@ -1464,27 +1465,20 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer if (videoSink != null) { long framePresentationTimeUs = bufferPresentationTimeUs + getBufferTimestampAdjustmentUs(); - try { - return videoSink.handleInputFrame( - framePresentationTimeUs, - isLastBuffer, - positionUs, - elapsedRealtimeUs, - new VideoSink.VideoFrameHandler() { - @Override - public void render(long renderTimestampNs) { - renderOutputBuffer(codec, bufferIndex, presentationTimeUs, renderTimestampNs); - } + return videoSink.handleInputFrame( + framePresentationTimeUs, + isLastBuffer, + new VideoSink.VideoFrameHandler() { + @Override + public void render(long renderTimestampNs) { + renderOutputBuffer(codec, bufferIndex, presentationTimeUs, renderTimestampNs); + } - @Override - public void skip() { - skipOutputBuffer(codec, bufferIndex, presentationTimeUs); - } - }); - } catch (VideoSink.VideoSinkException e) { - throw createRendererException( - e, e.format, PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED); - } + @Override + public void skip() { + skipOutputBuffer(codec, bufferIndex, presentationTimeUs); + } + }); } // The frame release action should be retrieved for all frames (even the ones that will be diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java index 16af85a386..23ba850017 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java @@ -734,12 +734,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video @Override public boolean handleInputFrame( - long framePresentationTimeUs, - boolean isLastFrame, - long positionUs, - long elapsedRealtimeUs, - VideoFrameHandler videoFrameHandler) - throws VideoSinkException { + long framePresentationTimeUs, boolean isLastFrame, VideoFrameHandler videoFrameHandler) { checkState(isInitialized()); // The sink takes in frames with monotonically increasing, non-offset frame @@ -758,9 +753,6 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video return true; } - // Drain the sink to make room for a new input frame. - render(positionUs, elapsedRealtimeUs); - if (checkStateNotNull(videoFrameProcessor).getPendingInputFrameCount() >= videoFrameProcessorMaxPendingFrameCount) { return false; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoSink.java index d0e53b59d6..ddf2408727 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoSink.java @@ -18,7 +18,6 @@ package androidx.media3.exoplayer.video; import static java.lang.annotation.ElementType.TYPE_USE; import android.graphics.Bitmap; -import android.os.SystemClock; import android.view.Surface; import androidx.annotation.FloatRange; import androidx.annotation.IntDef; @@ -270,20 +269,12 @@ public interface VideoSink { * @param isLastFrame Whether this is the last frame of the video stream. This flag is set on a * best effort basis, and any logic relying on it should degrade gracefully to handle cases * where it's not set. - * @param positionUs The current playback position, in microseconds. - * @param elapsedRealtimeUs {@link SystemClock#elapsedRealtime()} in microseconds, taken - * approximately at the time the playback position was {@code positionUs}. * @param videoFrameHandler The {@link VideoFrameHandler} used to handle the input frame. * @return Whether the frame was handled successfully. If {@code false}, the caller can try again * later. */ boolean handleInputFrame( - long framePresentationTimeUs, - boolean isLastFrame, - long positionUs, - long elapsedRealtimeUs, - VideoFrameHandler videoFrameHandler) - throws VideoSinkException; + long framePresentationTimeUs, boolean isLastFrame, VideoFrameHandler videoFrameHandler); /** * Handles an input {@link Bitmap}. diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/BufferingVideoSink.java b/libraries/transformer/src/main/java/androidx/media3/transformer/BufferingVideoSink.java index d37b4e3430..8698501a39 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/BufferingVideoSink.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/BufferingVideoSink.java @@ -217,15 +217,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public boolean handleInputFrame( - long framePresentationTimeUs, - boolean isLastFrame, - long positionUs, - long elapsedRealtimeUs, - VideoFrameHandler videoFrameHandler) - throws VideoSinkException { + long framePresentationTimeUs, boolean isLastFrame, VideoFrameHandler videoFrameHandler) { return videoSink != null - && videoSink.handleInputFrame( - framePresentationTimeUs, isLastFrame, positionUs, elapsedRealtimeUs, videoFrameHandler); + && videoSink.handleInputFrame(framePresentationTimeUs, isLastFrame, videoFrameHandler); } @Override