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
This commit is contained in:
kimvde 2024-12-03 03:26:19 -08:00 committed by Copybara-Service
parent 675c1d898a
commit 0037388660
5 changed files with 20 additions and 53 deletions

View File

@ -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();
}

View File

@ -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,12 +1465,9 @@ 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) {
@ -1481,10 +1479,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
skipOutputBuffer(codec, bufferIndex, presentationTimeUs);
}
});
} catch (VideoSink.VideoSinkException e) {
throw createRendererException(
e, e.format, PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED);
}
}
// The frame release action should be retrieved for all frames (even the ones that will be

View File

@ -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;

View File

@ -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}.

View File

@ -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