Remove VideoSink.setWakeUpListener

This is the last Renderer reference in VideoSink

PiperOrigin-RevId: 742189332
This commit is contained in:
kimvde 2025-03-31 02:25:10 -07:00 committed by Copybara-Service
parent 72f5df582a
commit 427daef350
7 changed files with 47 additions and 65 deletions

View File

@ -839,7 +839,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
throws ExoPlaybackException { throws ExoPlaybackException {
if (messageType == MSG_SET_WAKEUP_LISTENER) { if (messageType == MSG_SET_WAKEUP_LISTENER) {
wakeupListener = checkNotNull((WakeupListener) message); wakeupListener = checkNotNull((WakeupListener) message);
onWakeupListenerSet(wakeupListener);
} else { } else {
super.handleMessage(messageType, message); super.handleMessage(messageType, message);
} }
@ -1546,17 +1545,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
// Do nothing. // Do nothing.
} }
/**
* Called when a {@link WakeupListener} is set.
*
* <p>The default implementation is a no-op.
*
* @param wakeupListener The {@link WakeupListener}.
*/
protected void onWakeupListenerSet(WakeupListener wakeupListener) {
// Do nothing.
}
/** /**
* Called when a new {@link Format} is read from the upstream {@link MediaPeriod}. * Called when a new {@link Format} is read from the upstream {@link MediaPeriod}.
* *

View File

@ -30,7 +30,6 @@ import androidx.media3.common.util.Clock;
import androidx.media3.common.util.Size; import androidx.media3.common.util.Size;
import androidx.media3.common.util.TimestampIterator; import androidx.media3.common.util.TimestampIterator;
import androidx.media3.exoplayer.ExoPlaybackException; import androidx.media3.exoplayer.ExoPlaybackException;
import androidx.media3.exoplayer.Renderer;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
@ -46,7 +45,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* <ul> * <ul>
* <li>Applying video effects * <li>Applying video effects
* <li>Inputting bitmaps * <li>Inputting bitmaps
* <li>Setting a WakeupListener
* </ul> * </ul>
* *
* <p>The {@linkplain #getInputSurface() input} and {@linkplain #setOutputSurfaceInfo(Surface, Size) * <p>The {@linkplain #getInputSurface() input} and {@linkplain #setOutputSurfaceInfo(Surface, Size)
@ -224,6 +222,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
videoFrameHandlers.add(videoFrameHandler); videoFrameHandlers.add(videoFrameHandler);
long bufferPresentationTimeUs = framePresentationTimeUs - bufferTimestampAdjustmentUs; long bufferPresentationTimeUs = framePresentationTimeUs - bufferTimestampAdjustmentUs;
videoFrameRenderControl.onFrameAvailableForRendering(bufferPresentationTimeUs); videoFrameRenderControl.onFrameAvailableForRendering(bufferPresentationTimeUs);
listenerExecutor.execute(() -> listener.onFrameAvailableForRendering());
return true; return true;
} }
@ -246,16 +245,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
} }
/**
* {@inheritDoc}
*
* <p>This method will always throw an {@link UnsupportedOperationException}.
*/
@Override
public void setWakeupListener(Renderer.WakeupListener wakeupListener) {
throw new UnsupportedOperationException();
}
@Override @Override
public void join(boolean renderNextFrameImmediately) { public void join(boolean renderNextFrameImmediately) {
videoFrameReleaseControl.join(renderNextFrameImmediately); videoFrameReleaseControl.join(renderNextFrameImmediately);

View File

@ -883,6 +883,15 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
// have been set on the renderer before creating the VideoSink. // have been set on the renderer before creating the VideoSink.
videoSink.setListener( videoSink.setListener(
new VideoSink.Listener() { new VideoSink.Listener() {
@Override
public void onFrameAvailableForRendering() {
@Nullable WakeupListener wakeupListener = getWakeupListener();
if (wakeupListener != null) {
wakeupListener.onWakeup();
}
}
@Override @Override
public void onFirstFrameRendered() { public void onFirstFrameRendered() {
if (displaySurface != null) { if (displaySurface != null) {
@ -932,10 +941,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
mayRenderStartOfStream mayRenderStartOfStream
? RELEASE_FIRST_FRAME_IMMEDIATELY ? RELEASE_FIRST_FRAME_IMMEDIATELY
: RELEASE_FIRST_FRAME_WHEN_STARTED; : RELEASE_FIRST_FRAME_WHEN_STARTED;
@Nullable WakeupListener wakeupListener = getWakeupListener();
if (wakeupListener != null) {
videoSink.setWakeupListener(wakeupListener);
}
experimentalEnableProcessedStreamChangedAtStart(); experimentalEnableProcessedStreamChangedAtStart();
} else { } else {
videoFrameReleaseControl.setClock(getClock()); videoFrameReleaseControl.setClock(getClock());
@ -1464,13 +1469,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
eventDispatcher.videoCodecError(codecError); eventDispatcher.videoCodecError(codecError);
} }
@Override
protected void onWakeupListenerSet(WakeupListener wakeupListener) {
if (videoSink != null) {
videoSink.setWakeupListener(wakeupListener);
}
}
@Override @Override
@Nullable @Nullable
protected DecoderReuseEvaluation onInputFormatChanged(FormatHolder formatHolder) protected DecoderReuseEvaluation onInputFormatChanged(FormatHolder formatHolder)

View File

@ -55,7 +55,6 @@ import androidx.media3.common.util.TimedValueQueue;
import androidx.media3.common.util.TimestampIterator; import androidx.media3.common.util.TimestampIterator;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.Renderer;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -80,11 +79,15 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
/** Listener for {@link PlaybackVideoGraphWrapper} events. */ /** Listener for {@link PlaybackVideoGraphWrapper} events. */
public interface Listener { public interface Listener {
/** Called when the video frame processor renders the first frame. */
void onFirstFrameRendered();
/** Called when the video frame processor dropped a frame. */ /** Called when an output frame is available for rendering. */
void onFrameDropped(); default void onFrameAvailableForRendering() {}
/** Called when the first output frame is rendered. */
default void onFirstFrameRendered() {}
/** Called when an output frame is dropped. */
default void onFrameDropped() {}
/** /**
* Called before a frame is rendered for the first time since setting the surface, and each time * Called before a frame is rendered for the first time since setting the surface, and each time
@ -92,14 +95,14 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
* *
* @param videoSize The video size. * @param videoSize The video size.
*/ */
void onVideoSizeChanged(VideoSize videoSize); default void onVideoSizeChanged(VideoSize videoSize) {}
/** /**
* Called when the video frame processor encountered an error. * Called when an error occurs.
* *
* @param videoFrameProcessingException The error. * @param videoFrameProcessingException The error.
*/ */
void onError(VideoFrameProcessingException videoFrameProcessingException); default void onError(VideoFrameProcessingException videoFrameProcessingException) {}
} }
/** A builder for {@link PlaybackVideoGraphWrapper} instances. */ /** A builder for {@link PlaybackVideoGraphWrapper} instances. */
@ -288,7 +291,6 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
@Nullable private Pair<Surface, Size> currentSurfaceAndSize; @Nullable private Pair<Surface, Size> currentSurfaceAndSize;
private int pendingFlushCount; private int pendingFlushCount;
private @State int state; private @State int state;
@Nullable private Renderer.WakeupListener wakeupListener;
/** /**
* The buffer presentation time of the frame most recently output by the video graph, in * The buffer presentation time of the frame most recently output by the video graph, in
@ -430,9 +432,9 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
// Ignore available frames while flushing // Ignore available frames while flushing
return; return;
} }
if (wakeupListener != null) { for (PlaybackVideoGraphWrapper.Listener listener : listeners) {
// Wake up the player when not playing to render the frame more promptly. // Wake up the player when not playing to render the frame more promptly.
wakeupListener.onWakeup(); listener.onFrameAvailableForRendering();
} }
long bufferPresentationTimeUs = framePresentationTimeUs - bufferTimestampAdjustmentUs; long bufferPresentationTimeUs = framePresentationTimeUs - bufferTimestampAdjustmentUs;
@ -949,11 +951,6 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
PlaybackVideoGraphWrapper.this.render(positionUs, elapsedRealtimeUs); PlaybackVideoGraphWrapper.this.render(positionUs, elapsedRealtimeUs);
} }
@Override
public void setWakeupListener(Renderer.WakeupListener wakeupListener) {
PlaybackVideoGraphWrapper.this.wakeupListener = wakeupListener;
}
@Override @Override
public void join(boolean renderNextFrameImmediately) { public void join(boolean renderNextFrameImmediately) {
defaultVideoSink.join(renderNextFrameImmediately); defaultVideoSink.join(renderNextFrameImmediately);
@ -966,6 +963,12 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
// PlaybackVideoGraphWrapper.Listener implementation // PlaybackVideoGraphWrapper.Listener implementation
@Override
public void onFrameAvailableForRendering() {
VideoSink.Listener currentListener = listener;
listenerExecutor.execute(currentListener::onFrameAvailableForRendering);
}
@Override @Override
public void onFirstFrameRendered() { public void onFirstFrameRendered() {
VideoSink.Listener currentListener = listener; VideoSink.Listener currentListener = listener;

View File

@ -28,7 +28,6 @@ import androidx.media3.common.VideoSize;
import androidx.media3.common.util.Size; import androidx.media3.common.util.Size;
import androidx.media3.common.util.TimestampIterator; import androidx.media3.common.util.TimestampIterator;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.Renderer;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -56,6 +55,10 @@ public interface VideoSink {
/** Listener for {@link VideoSink} events. */ /** Listener for {@link VideoSink} events. */
interface Listener { interface Listener {
/** Called when an output frame is available for rendering. */
default void onFrameAvailableForRendering() {}
/** Called when the sink renders the first frame on the output surface. */ /** Called when the sink renders the first frame on the output surface. */
default void onFirstFrameRendered() {} default void onFirstFrameRendered() {}
@ -305,9 +308,6 @@ public interface VideoSink {
*/ */
void render(long positionUs, long elapsedRealtimeUs) throws VideoSinkException; void render(long positionUs, long elapsedRealtimeUs) throws VideoSinkException;
/** Sets a {@link Renderer.WakeupListener} on the {@code VideoSink}. */
void setWakeupListener(Renderer.WakeupListener wakeupListener);
/** /**
* Joins the video sink to a new stream. * Joins the video sink to a new stream.
* *

View File

@ -23,7 +23,6 @@ import androidx.media3.common.Effect;
import androidx.media3.common.Format; import androidx.media3.common.Format;
import androidx.media3.common.util.Size; import androidx.media3.common.util.Size;
import androidx.media3.common.util.TimestampIterator; import androidx.media3.common.util.TimestampIterator;
import androidx.media3.exoplayer.Renderer;
import androidx.media3.exoplayer.video.PlaceholderSurface; import androidx.media3.exoplayer.video.PlaceholderSurface;
import androidx.media3.exoplayer.video.VideoFrameMetadataListener; import androidx.media3.exoplayer.video.VideoFrameMetadataListener;
import androidx.media3.exoplayer.video.VideoSink; import androidx.media3.exoplayer.video.VideoSink;
@ -263,11 +262,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
} }
@Override
public void setWakeupListener(Renderer.WakeupListener wakeupListener) {
executeOrDelay(videoSink -> videoSink.setWakeupListener(wakeupListener));
}
@Override @Override
public void join(boolean renderNextFrameImmediately) { public void join(boolean renderNextFrameImmediately) {
executeOrDelay(videoSink -> videoSink.join(renderNextFrameImmediately)); executeOrDelay(videoSink -> videoSink.join(renderNextFrameImmediately));

View File

@ -27,6 +27,7 @@ import static androidx.media3.exoplayer.DefaultRenderersFactory.MAX_DROPPED_VIDE
import static androidx.media3.exoplayer.video.VideoSink.RELEASE_FIRST_FRAME_IMMEDIATELY; import static androidx.media3.exoplayer.video.VideoSink.RELEASE_FIRST_FRAME_IMMEDIATELY;
import static androidx.media3.exoplayer.video.VideoSink.RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED; import static androidx.media3.exoplayer.video.VideoSink.RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED;
import static androidx.media3.exoplayer.video.VideoSink.RELEASE_FIRST_FRAME_WHEN_STARTED; import static androidx.media3.exoplayer.video.VideoSink.RELEASE_FIRST_FRAME_WHEN_STARTED;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -500,6 +501,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private boolean mayRenderStartOfStream; private boolean mayRenderStartOfStream;
private @VideoSink.FirstFrameReleaseInstruction int nextFirstFrameReleaseInstruction; private @VideoSink.FirstFrameReleaseInstruction int nextFirstFrameReleaseInstruction;
private long offsetToCompositionTimeUs; private long offsetToCompositionTimeUs;
private @MonotonicNonNull WakeupListener wakeupListener;
public SequenceImageRenderer( public SequenceImageRenderer(
EditedMediaItemSequence sequence, EditedMediaItemSequence sequence,
@ -523,9 +525,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
mayRenderStartOfStream mayRenderStartOfStream
? RELEASE_FIRST_FRAME_IMMEDIATELY ? RELEASE_FIRST_FRAME_IMMEDIATELY
: RELEASE_FIRST_FRAME_WHEN_STARTED; : RELEASE_FIRST_FRAME_WHEN_STARTED;
// TODO: b/328444280 - Do not set a listener on VideoSink, but MediaCodecVideoRenderer must // TODO: b/328444280 - Unregister as a listener when the renderer is not used anymore
// unregister itself as a listener too. videoSink.setListener(
videoSink.setListener(VideoSink.Listener.NO_OP, /* executor= */ (runnable) -> {}); new VideoSink.Listener() {
@Override
public void onFrameAvailableForRendering() {
if (wakeupListener != null) {
wakeupListener.onWakeup();
}
}
},
directExecutor());
} }
@Override @Override
@ -658,7 +668,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public void handleMessage(@MessageType int messageType, @Nullable Object message) public void handleMessage(@MessageType int messageType, @Nullable Object message)
throws ExoPlaybackException { throws ExoPlaybackException {
if (messageType == MSG_SET_WAKEUP_LISTENER) { if (messageType == MSG_SET_WAKEUP_LISTENER) {
videoSink.setWakeupListener((WakeupListener) checkNotNull(message)); this.wakeupListener = (WakeupListener) checkNotNull(message);
} else { } else {
super.handleMessage(messageType, message); super.handleMessage(messageType, message);
} }