mirror of
https://github.com/androidx/media.git
synced 2025-04-29 14:26:50 +08:00
Start and stop video rendering from CompositionPlayer
Before, we were starting and stopping video rendering when the renderers were started/stopped. This doesn't work for multi-video sequences though because we shouldn't stop and start rendering at every MediaItem transition in any of the input sequences. PiperOrigin-RevId: 750206410
This commit is contained in:
parent
ab6b0f6e10
commit
fe10ca2c9a
@ -983,6 +983,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
|
||||
Context context, VideoFrameReleaseControl videoFrameReleaseControl) {
|
||||
// TODO: b/391109644 - Add a more explicit API to enable replaying.
|
||||
return new PlaybackVideoGraphWrapper.Builder(context, videoFrameReleaseControl)
|
||||
.setEnablePlaylistMode(true)
|
||||
.setClock(getClock())
|
||||
.build();
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
private VideoGraph.@MonotonicNonNull Factory videoGraphFactory;
|
||||
private List<Effect> compositionEffects;
|
||||
private VideoCompositorSettings compositorSettings;
|
||||
private boolean enablePlaylistMode;
|
||||
private Clock clock;
|
||||
private boolean requestOpenGlToneMapping;
|
||||
private boolean built;
|
||||
@ -185,6 +186,36 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to enable playlist mode.
|
||||
*
|
||||
* <p>The default value is {@code false}.
|
||||
*
|
||||
* <p>This should only be set to {@code true} if there is a single {@linkplain
|
||||
* PlaybackVideoGraphWrapper#getSink(int) input sink}.
|
||||
*
|
||||
* <p>If {@code true}, the {@link VideoGraph} output is considered as a playlist of clips. In
|
||||
* this case, {@link PlaybackVideoGraphWrapper#startRendering()} and {@link
|
||||
* PlaybackVideoGraphWrapper#stopRendering()} are called internally, when the corresponding
|
||||
* methods are caller on the sink.
|
||||
*
|
||||
* <p>If {@code false}, the {@link VideoGraph} output is considered as a single clip. In this
|
||||
* case, the caller is responsible for calling {@link
|
||||
* PlaybackVideoGraphWrapper#startRendering()} and {@link
|
||||
* PlaybackVideoGraphWrapper#stopRendering()}.
|
||||
*
|
||||
* @param enablePlaylistMode Whether to enable playlist mode.
|
||||
* @return This builder, for convenience.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setEnablePlaylistMode(boolean enablePlaylistMode) {
|
||||
// This is set to true for ExoPlayer.setVideoEffects(). It's always false in
|
||||
// CompositionPlayer, even if the Composition has a single sequence, because CompositionPlayer
|
||||
// shouldn't behave differently for single and multi-sequence.
|
||||
this.enablePlaylistMode = enablePlaylistMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Clock} that will be used.
|
||||
*
|
||||
@ -271,6 +302,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
private final SparseArray<InputVideoSink> inputVideoSinks;
|
||||
private final List<Effect> compositionEffects;
|
||||
private final VideoCompositorSettings compositorSettings;
|
||||
private final boolean enablePlaylistMode;
|
||||
private final VideoSink defaultVideoSink;
|
||||
private final VideoSink.VideoFrameHandler videoFrameHandler;
|
||||
private final Clock clock;
|
||||
@ -321,6 +353,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
inputVideoSinks = new SparseArray<>();
|
||||
compositionEffects = builder.compositionEffects;
|
||||
compositorSettings = builder.compositorSettings;
|
||||
enablePlaylistMode = builder.enablePlaylistMode;
|
||||
clock = builder.clock;
|
||||
defaultVideoSink = new DefaultVideoSink(builder.videoFrameReleaseControl, clock);
|
||||
videoFrameHandler =
|
||||
@ -363,6 +396,16 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
/** Starts rendering to the output surface. */
|
||||
public void startRendering() {
|
||||
defaultVideoSink.startRendering();
|
||||
}
|
||||
|
||||
/** Stops rendering to the output surface. */
|
||||
public void stopRendering() {
|
||||
defaultVideoSink.stopRendering();
|
||||
}
|
||||
|
||||
// VideoSinkProvider methods
|
||||
|
||||
@Override
|
||||
@ -704,12 +747,16 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
|
||||
@Override
|
||||
public void startRendering() {
|
||||
defaultVideoSink.startRendering();
|
||||
if (enablePlaylistMode) {
|
||||
PlaybackVideoGraphWrapper.this.startRendering();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopRendering() {
|
||||
defaultVideoSink.stopRendering();
|
||||
if (enablePlaylistMode) {
|
||||
PlaybackVideoGraphWrapper.this.stopRendering();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -743,6 +743,7 @@ public final class CompositionPlayer extends SimpleBasePlayer
|
||||
}
|
||||
} else if (endedCount == players.size()) {
|
||||
playbackState = STATE_ENDED;
|
||||
checkStateNotNull(compositionPlayerInternal).stopRendering();
|
||||
} else {
|
||||
playbackState = STATE_READY;
|
||||
if (oldPlaybackState != STATE_READY && playWhenReady) {
|
||||
|
@ -155,10 +155,10 @@ import androidx.media3.exoplayer.video.PlaybackVideoGraphWrapper;
|
||||
try {
|
||||
switch (message.what) {
|
||||
case MSG_START_RENDERING:
|
||||
playbackAudioGraphWrapper.startRendering();
|
||||
startRenderingInternal();
|
||||
break;
|
||||
case MSG_STOP_RENDERING:
|
||||
playbackAudioGraphWrapper.stopRendering();
|
||||
stopRenderingInternal();
|
||||
break;
|
||||
case MSG_SET_VOLUME:
|
||||
playbackAudioGraphWrapper.setVolume(/* volume= */ (float) message.obj);
|
||||
@ -210,6 +210,16 @@ import androidx.media3.exoplayer.video.PlaybackVideoGraphWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
public void startRenderingInternal() {
|
||||
playbackAudioGraphWrapper.startRendering();
|
||||
playbackVideoGraphWrapper.startRendering();
|
||||
}
|
||||
|
||||
public void stopRenderingInternal() {
|
||||
playbackAudioGraphWrapper.stopRendering();
|
||||
playbackVideoGraphWrapper.stopRendering();
|
||||
}
|
||||
|
||||
private void clearOutputSurfaceInternal() {
|
||||
try {
|
||||
playbackVideoGraphWrapper.clearOutputSurfaceInfo();
|
||||
|
Loading…
x
Reference in New Issue
Block a user