Skip to content

Commit

Permalink
Propagate end of stream received from OnFrameRenderedListener
Browse files Browse the repository at this point in the history
Previously the renderer EOS (aka last frame rendered), was reported as soon
as the last encoded frame was queued in the codec renderer.
This leaded to EOS reported too early.

PiperOrigin-RevId: 280456277
  • Loading branch information
krocard authored and ojw28 committed Nov 15, 2019
1 parent c8e7ecd commit 5579cc8
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### dev-v2 (not yet released) ###

* Video tunneling: Fix renderer end-of-stream with `OnFrameRenderedListener`
from API 23, tunneled renderer must send a special timestamp on EOS.
Previously the EOS was reported when the input stream reached EOS.
* Require an end time or duration for SubRip (SRT) and SubStation Alpha
(SSA/ASS) subtitles. This applies to both sidecar files & subtitles
[embedded in Matroska streams](https://matroska.org/technical/specs/subtitles/index.html).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ private static String getDiagnosticInfoV21(Throwable cause) {
private boolean waitingForFirstSyncSample;
private boolean waitingForFirstSampleInFormat;
private boolean skipMediaCodecStopOnRelease;
private boolean pendingOutputEndOfStream;

protected DecoderCounters decoderCounters;

Expand Down Expand Up @@ -603,6 +604,7 @@ protected void onEnabled(boolean joining) throws ExoPlaybackException {
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
inputStreamEnded = false;
outputStreamEnded = false;
pendingOutputEndOfStream = false;
flushOrReinitializeCodec();
formatQueue.clear();
}
Expand Down Expand Up @@ -686,6 +688,10 @@ protected void onStopped() {

@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
if (pendingOutputEndOfStream) {
pendingOutputEndOfStream = false;
processEndOfStream();
}
try {
if (outputStreamEnded) {
renderToEndOfStream();
Expand Down Expand Up @@ -1693,6 +1699,14 @@ private void processEndOfStream() throws ExoPlaybackException {
}
}

/**
* Notifies the renderer that output end of stream is pending and should be handled on the next
* render.
*/
protected final void setPendingOutputEndOfStream() {
pendingOutputEndOfStream = true;
}

private void reinitializeCodec() throws ExoPlaybackException {
releaseCodec();
maybeInitCodec();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
*/
private static final float INITIAL_FORMAT_MAX_INPUT_SIZE_SCALE_FACTOR = 1.5f;

/** Magic frame render timestamp that indicates the EOS in tunneling mode. */
private static final long TUNNELING_EOS_PRESENTATION_TIME_US = Long.MAX_VALUE;

/** A {@link DecoderException} with additional surface information. */
public static final class VideoDecoderException extends DecoderException {

Expand Down Expand Up @@ -604,8 +607,8 @@ protected boolean shouldInitCodec(MediaCodecInfo codecInfo) {

@Override
protected boolean getCodecNeedsEosPropagation() {
// In tunneling mode we can't dequeue an end-of-stream buffer, so propagate it in the renderer.
return tunneling;
// Since API 23, onFrameRenderedListener allows for detection of the renderer EOS.
return tunneling && Util.SDK_INT < 23;
}

@Override
Expand Down Expand Up @@ -946,6 +949,11 @@ protected void onProcessedTunneledBuffer(long presentationTimeUs) {
onProcessedOutputBuffer(presentationTimeUs);
}

/** Called when a output EOS was received in tunneling mode. */
private void onProcessedTunneledEndOfStream() {
setPendingOutputEndOfStream();
}

/**
* Called when an output buffer is successfully processed.
*
Expand Down Expand Up @@ -1754,9 +1762,12 @@ public void onFrameRendered(MediaCodec codec, long presentationTimeUs, long nano
// Stale event.
return;
}
onProcessedTunneledBuffer(presentationTimeUs);
if (presentationTimeUs == TUNNELING_EOS_PRESENTATION_TIME_US) {
onProcessedTunneledEndOfStream();
} else {
onProcessedTunneledBuffer(presentationTimeUs);
}
}

}

}

0 comments on commit 5579cc8

Please sign in to comment.