Split VideoSink.setStreamTimestampInfo

This is a step towards merging setStreamStartPositionUs with
onInputStreamChanged, which makes sense as the start position can only
change on stream change.

PiperOrigin-RevId: 735309009
This commit is contained in:
kimvde 2025-03-10 03:22:06 -07:00 committed by Copybara-Service
parent a4442a6cc5
commit 15fa27cd9a
6 changed files with 34 additions and 19 deletions

View File

@ -178,12 +178,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
@Override
public void setStreamTimestampInfo(long streamStartPositionUs, long bufferTimestampAdjustmentUs) {
public void setStreamStartPositionUs(long streamStartPositionUs) {
if (streamStartPositionUs != this.streamStartPositionUs) {
videoFrameRenderControl.onStreamChanged(
RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED, streamStartPositionUs);
this.streamStartPositionUs = streamStartPositionUs;
}
}
@Override
public void setBufferTimestampAdjustmentUs(long bufferTimestampAdjustmentUs) {
this.bufferTimestampAdjustmentUs = bufferTimestampAdjustmentUs;
}

View File

@ -965,8 +965,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (this.startPositionUs == C.TIME_UNSET) {
this.startPositionUs = startPositionUs;
if (videoSink != null) {
videoSink.setStreamTimestampInfo(
getOutputStreamStartPositionUs(), getBufferTimestampAdjustmentUs());
videoSink.setStreamStartPositionUs(getOutputStreamStartPositionUs());
videoSink.setBufferTimestampAdjustmentUs(getBufferTimestampAdjustmentUs());
}
}
updatePeriodDurationUs(mediaPeriodId);
@ -1868,8 +1868,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (videoSink != null) {
// Signaling end of the previous stream.
videoSink.signalEndOfCurrentInputStream();
videoSink.setStreamTimestampInfo(
getOutputStreamStartPositionUs(), getBufferTimestampAdjustmentUs());
videoSink.setStreamStartPositionUs(getOutputStreamStartPositionUs());
videoSink.setBufferTimestampAdjustmentUs(getBufferTimestampAdjustmentUs());
} else {
videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED);
}

View File

@ -441,8 +441,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
streamStartPositionsUs.pollFloor(bufferPresentationTimeUs);
if (newOutputStreamStartPositionUs != null
&& newOutputStreamStartPositionUs != outputStreamStartPositionUs) {
defaultVideoSink.setStreamTimestampInfo(
newOutputStreamStartPositionUs, bufferTimestampAdjustmentUs);
defaultVideoSink.setStreamStartPositionUs(newOutputStreamStartPositionUs);
outputStreamStartPositionUs = newOutputStreamStartPositionUs;
}
boolean isLastFrame =
@ -589,7 +588,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
if (streamStartPositionsUs.size() == 1) {
long lastStartPositionUs = checkNotNull(streamStartPositionsUs.pollFirst());
// defaultVideoSink should use the latest startPositionUs if none is passed after flushing.
defaultVideoSink.setStreamTimestampInfo(lastStartPositionUs, bufferTimestampAdjustmentUs);
defaultVideoSink.setStreamStartPositionUs(lastStartPositionUs);
}
lastOutputBufferPresentationTimeUs = C.TIME_UNSET;
finalBufferPresentationTimeUs = C.TIME_UNSET;
@ -610,8 +609,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
private void setBufferTimestampAdjustment(long bufferTimestampAdjustmentUs) {
this.bufferTimestampAdjustmentUs = bufferTimestampAdjustmentUs;
defaultVideoSink.setStreamTimestampInfo(
outputStreamStartPositionUs, bufferTimestampAdjustmentUs);
defaultVideoSink.setBufferTimestampAdjustmentUs(bufferTimestampAdjustmentUs);
}
private boolean shouldRenderToInputVideoSink() {
@ -795,14 +793,17 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
}
@Override
public void setStreamTimestampInfo(
long streamStartPositionUs, long bufferTimestampAdjustmentUs) {
public void setStreamStartPositionUs(long streamStartPositionUs) {
// Input timestamps should always be positive because they are offset by ExoPlayer. Adding a
// position to the queue with timestamp 0 should therefore always apply it as long as it is
// the only position in the queue.
streamStartPositionsUs.add(
lastBufferPresentationTimeUs == C.TIME_UNSET ? 0 : lastBufferPresentationTimeUs + 1,
streamStartPositionUs);
}
@Override
public void setBufferTimestampAdjustmentUs(long bufferTimestampAdjustmentUs) {
inputBufferTimestampAdjustmentUs = bufferTimestampAdjustmentUs;
// The buffer timestamp adjustment is only allowed to change after a flush to make sure that
// the buffer timestamps are increasing. We can update the buffer timestamp adjustment

View File

@ -211,14 +211,20 @@ public interface VideoSink {
void setVideoEffects(List<Effect> videoEffects);
/**
* Sets information about the timestamps of the current input stream.
* Sets the current stream start position.
*
* @param streamStartPositionUs The start position of the buffer presentation timestamps of the
* current stream, in microseconds.
*/
void setStreamStartPositionUs(long streamStartPositionUs);
/**
* Sets the buffer timestamp adjustment.
*
* @param bufferTimestampAdjustmentUs The timestamp adjustment to add to the buffer presentation
* timestamps to convert them to frame presentation timestamps, in microseconds.
*/
void setStreamTimestampInfo(long streamStartPositionUs, long bufferTimestampAdjustmentUs);
void setBufferTimestampAdjustmentUs(long bufferTimestampAdjustmentUs);
/** Sets the output surface info. */
void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution);

View File

@ -193,10 +193,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
@Override
public void setStreamTimestampInfo(long streamStartPositionUs, long bufferTimestampAdjustmentUs) {
public void setStreamStartPositionUs(long streamStartPositionUs) {
executeOrDelay(videoSink -> videoSink.setStreamStartPositionUs(streamStartPositionUs));
}
@Override
public void setBufferTimestampAdjustmentUs(long bufferTimestampAdjustmentUs) {
executeOrDelay(
videoSink ->
videoSink.setStreamTimestampInfo(streamStartPositionUs, bufferTimestampAdjustmentUs));
videoSink -> videoSink.setBufferTimestampAdjustmentUs(bufferTimestampAdjustmentUs));
}
@Override

View File

@ -587,6 +587,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid);
currentEditedMediaItem = sequence.editedMediaItems.get(mediaItemIndex);
offsetToCompositionTimeUs = getOffsetToCompositionTimeUs(sequence, mediaItemIndex, offsetUs);
videoSink.setBufferTimestampAdjustmentUs(offsetToCompositionTimeUs);
timestampIterator = createTimestampIterator(/* positionUs= */ startPositionUs);
videoEffects = currentEditedMediaItem.effects.videoEffects;
inputStreamPending = true;
@ -614,8 +615,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
long positionUs, long elapsedRealtimeUs, Bitmap outputImage, long timeUs) {
if (inputStreamPending) {
checkState(streamStartPositionUs != C.TIME_UNSET);
videoSink.setStreamTimestampInfo(
streamStartPositionUs, /* bufferTimestampAdjustmentUs= */ offsetToCompositionTimeUs);
videoSink.setStreamStartPositionUs(streamStartPositionUs);
videoSink.onInputStreamChanged(
VideoSink.INPUT_TYPE_BITMAP,
new Format.Builder()