Support renderer joining in CompositionPlayer

Renderers join when they can start processing but not produce output.

In CompositionPlayer before this change, the VideoSink will be flushed when
position is reset regardless. This is useful for seeking, as seeking triggers position reset. But with pre-warming, a video renderer can be joining -  it is
enabled (which also triggers position reset) before the previous image renderer
is disabled. At this moment, as the image renderer is still producing frames,
we should not flush the video sink just now.

PiperOrigin-RevId: 699943882
This commit is contained in:
claincly 2024-11-25 05:12:38 -08:00 committed by Copybara-Service
parent 25a782e10a
commit 7ef1a7ab8b
2 changed files with 10 additions and 6 deletions

View File

@ -805,9 +805,11 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
@Override @Override
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
if (videoSink != null) { if (videoSink != null) {
if (!joining) {
// Flush the video sink first to ensure it stops reading textures that will be owned by // Flush the video sink first to ensure it stops reading textures that will be owned by
// MediaCodec once the codec is flushed. // MediaCodec once the codec is flushed.
videoSink.flush(/* resetPosition= */ true); videoSink.flush(/* resetPosition= */ true);
}
videoSink.setStreamTimestampInfo( videoSink.setStreamTimestampInfo(
getOutputStreamStartPositionUs(), getOutputStreamStartPositionUs(),
getBufferTimestampAdjustmentUs(), getBufferTimestampAdjustmentUs(),

View File

@ -297,11 +297,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
MediaSource.MediaPeriodId mediaPeriodId) MediaSource.MediaPeriodId mediaPeriodId)
throws ExoPlaybackException { throws ExoPlaybackException {
checkState(getTimeline().getWindowCount() == 1); checkState(getTimeline().getWindowCount() == 1);
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
// The media item might have been repeated in the sequence. // The media item might have been repeated in the sequence.
int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid); int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid);
offsetToCompositionTimeUs = getOffsetToCompositionTimeUs(sequence, mediaItemIndex, offsetUs); offsetToCompositionTimeUs = getOffsetToCompositionTimeUs(sequence, mediaItemIndex, offsetUs);
pendingEffect = sequence.editedMediaItems.get(mediaItemIndex).effects.videoEffects; pendingEffect = sequence.editedMediaItems.get(mediaItemIndex).effects.videoEffects;
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
} }
@Override @Override
@ -400,10 +400,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
if (!joining) {
videoSink.flush(/* resetPosition= */ true); videoSink.flush(/* resetPosition= */ true);
super.onPositionReset(positionUs, joining);
timestampIterator = createTimestampIterator(positionUs); timestampIterator = createTimestampIterator(positionUs);
} }
super.onPositionReset(positionUs, joining);
}
@Override @Override
protected void onStarted() throws ExoPlaybackException { protected void onStarted() throws ExoPlaybackException {