Skip to content

Commit

Permalink
Correctly update output info if previous stream has been fully rendered
Browse files Browse the repository at this point in the history
The output info for a new stream is marked pending until the last
sample of the previous stream has been processed. However, this fails
if the previous stream has already been fully processed. We need to
detect this case explicitly to avoid signalling the output change one
sample too late.

#minor-release

PiperOrigin-RevId: 512572854
(cherry picked from commit 7ffcc6f)
  • Loading branch information
tonihei committed Feb 28, 2023
1 parent abf1eb8 commit f011cc8
Showing 1 changed file with 9 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ private static String buildCustomDiagnosticInfo(int errorCode) {
@Nullable private ExoPlaybackException pendingPlaybackException;
protected DecoderCounters decoderCounters;
private OutputStreamInfo outputStreamInfo;
private long lastProcessedOutputBufferTimeUs;

/**
* @param trackType The {@link C.TrackType track type} that the renderer handles.
Expand Down Expand Up @@ -408,6 +409,7 @@ public MediaCodecRenderer(
codecHotswapDeadlineMs = C.TIME_UNSET;
largestQueuedPresentationTimeUs = C.TIME_UNSET;
lastBufferInStreamPresentationTimeUs = C.TIME_UNSET;
lastProcessedOutputBufferTimeUs = C.TIME_UNSET;
codecDrainState = DRAIN_STATE_NONE;
codecDrainAction = DRAIN_ACTION_NONE;
}
Expand Down Expand Up @@ -637,8 +639,11 @@ protected void onEnabled(boolean joining, boolean mayRenderStartOfStream)
@Override
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
throws ExoPlaybackException {
if (outputStreamInfo.streamOffsetUs == C.TIME_UNSET) {
checkState(outputStreamInfo.startPositionUs == C.TIME_UNSET);
if (outputStreamInfo.streamOffsetUs == C.TIME_UNSET
|| (pendingOutputStreamChanges.isEmpty()
&& lastProcessedOutputBufferTimeUs != C.TIME_UNSET
&& lastProcessedOutputBufferTimeUs >= largestQueuedPresentationTimeUs)) {
// This is the first stream, or the previous has been fully output already.
setOutputStreamInfo(
new OutputStreamInfo(
/* previousStreamLastBufferTimeUs= */ C.TIME_UNSET, startPositionUs, offsetUs));
Expand Down Expand Up @@ -871,6 +876,7 @@ protected void resetCodecStateForFlush() {
decodeOnlyPresentationTimestamps.clear();
largestQueuedPresentationTimeUs = C.TIME_UNSET;
lastBufferInStreamPresentationTimeUs = C.TIME_UNSET;
lastProcessedOutputBufferTimeUs = C.TIME_UNSET;
if (c2Mp3TimestampTracker != null) {
c2Mp3TimestampTracker.reset();
}
Expand Down Expand Up @@ -1567,6 +1573,7 @@ protected void onQueueInputBuffer(DecoderInputBuffer buffer) throws ExoPlaybackE
*/
@CallSuper
protected void onProcessedOutputBuffer(long presentationTimeUs) {
lastProcessedOutputBufferTimeUs = presentationTimeUs;
if (!pendingOutputStreamChanges.isEmpty()
&& presentationTimeUs >= pendingOutputStreamChanges.peek().previousStreamLastBufferTimeUs) {
setOutputStreamInfo(pendingOutputStreamChanges.poll());
Expand Down

0 comments on commit f011cc8

Please sign in to comment.