Add util method BaseRenderer.getStreamOffsetUs
This simplifies the common pattern of saving this offset in onStreamChanged to use it at a later point. PiperOrigin-RevId: 666226263
This commit is contained in:
parent
4ba9f59492
commit
6f0cb539d0
@ -418,6 +418,15 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
||||
return lastResetPositionUs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset added to timestamps of buffers read from the {@link SampleStream}.
|
||||
*
|
||||
* <p>Must only be called if the renderer is at least {@link #STATE_ENABLED}.
|
||||
*/
|
||||
protected final long getStreamOffsetUs() {
|
||||
return streamOffsetUs;
|
||||
}
|
||||
|
||||
/** Returns a clear {@link FormatHolder}. */
|
||||
protected final FormatHolder getFormatHolder() {
|
||||
formatHolder.clear();
|
||||
|
@ -119,7 +119,6 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||
private boolean inputStreamEnded;
|
||||
private boolean outputStreamEnded;
|
||||
@Nullable private Format streamFormat;
|
||||
private long outputStreamOffsetUs;
|
||||
private long lastRendererPositionUs;
|
||||
private long finalStreamEndPositionUs;
|
||||
private boolean legacyDecodingEnabled;
|
||||
@ -159,7 +158,6 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||
new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
formatHolder = new FormatHolder();
|
||||
finalStreamEndPositionUs = C.TIME_UNSET;
|
||||
outputStreamOffsetUs = C.TIME_UNSET;
|
||||
lastRendererPositionUs = C.TIME_UNSET;
|
||||
legacyDecodingEnabled = false;
|
||||
}
|
||||
@ -206,7 +204,6 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||
long startPositionUs,
|
||||
long offsetUs,
|
||||
MediaSource.MediaPeriodId mediaPeriodId) {
|
||||
outputStreamOffsetUs = offsetUs;
|
||||
streamFormat = formats[0];
|
||||
if (!isCuesWithTiming(streamFormat)) {
|
||||
assertLegacyDecodingEnabledIfRequired();
|
||||
@ -462,7 +459,6 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||
streamFormat = null;
|
||||
finalStreamEndPositionUs = C.TIME_UNSET;
|
||||
clearOutput();
|
||||
outputStreamOffsetUs = C.TIME_UNSET;
|
||||
lastRendererPositionUs = C.TIME_UNSET;
|
||||
if (subtitleDecoder != null) {
|
||||
releaseSubtitleDecoder();
|
||||
@ -579,9 +575,7 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||
@SideEffectFree
|
||||
private long getPresentationTimeUs(long positionUs) {
|
||||
checkState(positionUs != C.TIME_UNSET);
|
||||
checkState(outputStreamOffsetUs != C.TIME_UNSET);
|
||||
|
||||
return positionUs - outputStreamOffsetUs;
|
||||
return positionUs - getStreamOffsetUs();
|
||||
}
|
||||
|
||||
@RequiresNonNull("streamFormat")
|
||||
|
@ -153,7 +153,6 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
|
||||
private int consecutiveDroppedFrameCount;
|
||||
private int buffersInCodecCount;
|
||||
private long lastRenderTimeUs;
|
||||
private long outputStreamOffsetUs;
|
||||
|
||||
/** Decoder event counters used for debugging purposes. */
|
||||
protected DecoderCounters decoderCounters;
|
||||
@ -342,10 +341,8 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
|
||||
long offsetUs,
|
||||
MediaSource.MediaPeriodId mediaPeriodId)
|
||||
throws ExoPlaybackException {
|
||||
// TODO: This shouldn't just update the output stream offset as long as there are still buffers
|
||||
// of the previous stream in the decoder. It should also make sure to render the first frame of
|
||||
// the next stream if the playback position reached the new stream.
|
||||
outputStreamOffsetUs = offsetUs;
|
||||
// TODO: This code should make sure to render the first frame of the next stream if the playback
|
||||
// position reached the new stream.
|
||||
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
|
||||
}
|
||||
|
||||
@ -875,7 +872,9 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
|
||||
outputFormat = formatQueue.pollFirst();
|
||||
}
|
||||
|
||||
long presentationTimeUs = bufferTimeUs - outputStreamOffsetUs;
|
||||
// TODO: This shouldn't just use the input stream offset and we should correctly track the
|
||||
// output stream offset after decoding instead.
|
||||
long presentationTimeUs = bufferTimeUs - getStreamOffsetUs();
|
||||
if (shouldForceRender(earlyUs)) {
|
||||
renderOutputBuffer(outputBuffer, presentationTimeUs, checkNotNull(outputFormat));
|
||||
return true;
|
||||
|
@ -28,7 +28,6 @@ import androidx.media3.exoplayer.ExoPlaybackException;
|
||||
import androidx.media3.exoplayer.FormatHolder;
|
||||
import androidx.media3.exoplayer.Renderer;
|
||||
import androidx.media3.exoplayer.RendererCapabilities;
|
||||
import androidx.media3.exoplayer.source.MediaSource;
|
||||
import androidx.media3.exoplayer.source.SampleStream.ReadDataResult;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@ -43,7 +42,6 @@ public final class CameraMotionRenderer extends BaseRenderer {
|
||||
private final DecoderInputBuffer buffer;
|
||||
private final ParsableByteArray scratch;
|
||||
|
||||
private long offsetUs;
|
||||
@Nullable private CameraMotionListener listener;
|
||||
private long lastTimestampUs;
|
||||
|
||||
@ -75,15 +73,6 @@ public final class CameraMotionRenderer extends BaseRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStreamChanged(
|
||||
Format[] formats,
|
||||
long startPositionUs,
|
||||
long offsetUs,
|
||||
MediaSource.MediaPeriodId mediaPeriodId) {
|
||||
this.offsetUs = offsetUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPositionReset(long positionUs, boolean joining) {
|
||||
lastTimestampUs = Long.MIN_VALUE;
|
||||
@ -118,7 +107,7 @@ public final class CameraMotionRenderer extends BaseRenderer {
|
||||
continue;
|
||||
}
|
||||
|
||||
Util.castNonNull(listener).onCameraMotion(lastTimestampUs - offsetUs, rotation);
|
||||
Util.castNonNull(listener).onCameraMotion(lastTimestampUs - getStreamOffsetUs(), rotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,6 @@ public class FakeVideoRenderer extends FakeRenderer {
|
||||
private final AtomicReference<VideoSize> videoSizeRef = new AtomicReference<>();
|
||||
private @MonotonicNonNull Format format;
|
||||
@Nullable private Object output;
|
||||
private long streamOffsetUs;
|
||||
private boolean renderedFirstFrameAfterReset;
|
||||
private boolean mayRenderFirstFrameAfterEnableIfNotStarted;
|
||||
private boolean renderedFirstFrameAfterEnable;
|
||||
@ -73,7 +72,6 @@ public class FakeVideoRenderer extends FakeRenderer {
|
||||
MediaSource.MediaPeriodId mediaPeriodId)
|
||||
throws ExoPlaybackException {
|
||||
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
|
||||
streamOffsetUs = offsetUs;
|
||||
renderedFirstFrameAfterReset = false;
|
||||
}
|
||||
|
||||
@ -150,7 +148,7 @@ public class FakeVideoRenderer extends FakeRenderer {
|
||||
? (getState() == Renderer.STATE_STARTED
|
||||
|| mayRenderFirstFrameAfterEnableIfNotStarted)
|
||||
: !renderedFirstFrameAfterReset);
|
||||
shouldProcess |= shouldRenderFirstFrame && playbackPositionUs >= streamOffsetUs;
|
||||
shouldProcess |= shouldRenderFirstFrame && playbackPositionUs >= getStreamOffsetUs();
|
||||
@Nullable Object output = this.output;
|
||||
if (shouldProcess && !renderedFirstFrameAfterReset && output != null) {
|
||||
@MonotonicNonNull Format format = Assertions.checkNotNull(this.format);
|
||||
|
@ -42,7 +42,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
/* package */ abstract class ExoAssetLoaderBaseRenderer extends BaseRenderer {
|
||||
|
||||
protected long streamStartPositionUs;
|
||||
protected long streamOffsetUs;
|
||||
protected @MonotonicNonNull SampleConsumer sampleConsumer;
|
||||
protected @MonotonicNonNull Codec decoder;
|
||||
protected boolean isEnded;
|
||||
@ -131,7 +130,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
long offsetUs,
|
||||
MediaSource.MediaPeriodId mediaPeriodId) {
|
||||
this.streamStartPositionUs = startPositionUs;
|
||||
this.streamOffsetUs = offsetUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,6 +130,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
ByteBuffer inputBytes = checkNotNull(inputBuffer.data);
|
||||
if (sefVideoSlowMotionFlattener != null) {
|
||||
long streamOffsetUs = getStreamOffsetUs();
|
||||
long presentationTimeUs = inputBuffer.timeUs - streamOffsetUs;
|
||||
boolean shouldDropInputBuffer =
|
||||
sefVideoSlowMotionFlattener.dropOrTransformSample(inputBytes, presentationTimeUs);
|
||||
|
@ -300,7 +300,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
@Nullable private ExoPlaybackException pendingExoPlaybackException;
|
||||
private boolean inputStreamPending;
|
||||
private long streamStartPositionUs;
|
||||
private long streamOffsetUs;
|
||||
private boolean mayRenderStartOfStream;
|
||||
private long offsetToCompositionTimeUs;
|
||||
|
||||
@ -311,7 +310,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
videoSink = checkStateNotNull(sequencePlayerRenderersWrapper.videoSink);
|
||||
videoEffects = ImmutableList.of();
|
||||
streamStartPositionUs = C.TIME_UNSET;
|
||||
streamOffsetUs = C.TIME_UNSET;
|
||||
}
|
||||
|
||||
// ImageRenderer methods
|
||||
@ -397,7 +395,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
checkState(getTimeline().getWindowCount() == 1);
|
||||
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
|
||||
streamStartPositionUs = startPositionUs;
|
||||
streamOffsetUs = offsetUs;
|
||||
int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid);
|
||||
editedMediaItem =
|
||||
sequencePlayerRenderersWrapper.sequence.editedMediaItems.get(mediaItemIndex);
|
||||
@ -429,11 +426,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
long positionUs, long elapsedRealtimeUs, Bitmap outputImage, long timeUs) {
|
||||
if (inputStreamPending) {
|
||||
checkState(streamStartPositionUs != C.TIME_UNSET);
|
||||
checkState(streamOffsetUs != C.TIME_UNSET);
|
||||
videoSink.setPendingVideoEffects(videoEffects);
|
||||
videoSink.setStreamTimestampInfo(
|
||||
streamStartPositionUs,
|
||||
streamOffsetUs,
|
||||
getStreamOffsetUs(),
|
||||
/* bufferTimestampAdjustmentUs= */ offsetToCompositionTimeUs,
|
||||
getLastResetPositionUs());
|
||||
videoSink.onInputStreamChanged(
|
||||
@ -451,6 +447,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
}
|
||||
|
||||
private ConstantRateTimestampIterator createTimestampIterator(long positionUs) {
|
||||
long streamOffsetUs = getStreamOffsetUs();
|
||||
long imageBaseTimestampUs = streamOffsetUs + offsetToCompositionTimeUs;
|
||||
long positionWithinImage = positionUs - streamOffsetUs;
|
||||
long firstBitmapTimeUs = imageBaseTimestampUs + positionWithinImage;
|
||||
|
Loading…
x
Reference in New Issue
Block a user