Skip to content

Commit

Permalink
Make video playback smoother at the beginning
Browse files Browse the repository at this point in the history
Video renderers assume that the player position is advancing linearly while in
the started state. MediaCodecVideoRenderer schedules frames for rendering in the
future in the expectation that the player position is advancing.

This assumption is not currently true when using a position from the AudioTrack:
the player position can be fixed for (in the worst case) up to about 100 ms
before it starts increasing. This leads to an effect where the first frame is
rendered then a few other frames are rendered, then there's a pause before
frames start being rendered smoothly.

Work around this issue by checking whether the position has started advancing
before scheduling frames to be rendered in the future.

It might be preferable to make the audio renderer only become ready when its
timestamp can start advancing, but this is likely to be complicated.

Issue: #3841

-------------
Created by MOE: https:/google/moe
MOE_MIGRATED_REVID=190937429
  • Loading branch information
andrewlewis authored and ojw28 committed Mar 29, 2018
1 parent 7820497 commit 8d47209
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {

private Bitmap bitmap;
private boolean renderedFirstFrame;
private long initialPositionUs;
private long joiningDeadlineMs;
private Surface surface;
private VpxOutputBufferRenderer outputBufferRenderer;
Expand Down Expand Up @@ -303,6 +304,7 @@ protected void onPositionReset(long positionUs, boolean joining) throws ExoPlayb
inputStreamEnded = false;
outputStreamEnded = false;
clearRenderedFirstFrame();
initialPositionUs = C.TIME_UNSET;
consecutiveDroppedFrameCount = 0;
if (decoder != null) {
flushDecoder();
Expand Down Expand Up @@ -809,6 +811,10 @@ private boolean drainOutputBuffer(long positionUs, long elapsedRealtimeUs)
*/
private boolean processOutputBuffer(long positionUs, long elapsedRealtimeUs)
throws ExoPlaybackException {
if (initialPositionUs == C.TIME_UNSET) {
initialPositionUs = positionUs;
}

long earlyUs = outputBuffer.timeUs - positionUs;
if (outputMode == VpxDecoder.OUTPUT_MODE_NONE) {
// Skip frames in sync with playback, so we'll be at the right frame if the mode changes.
Expand All @@ -828,7 +834,7 @@ && shouldForceRenderOutputBuffer(earlyUs, elapsedRealtimeNowUs - lastRenderTimeU
return true;
}

if (!isStarted) {
if (!isStarted || positionUs == initialPositionUs) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@C.VideoScalingMode
private int scalingMode;
private boolean renderedFirstFrame;
private long initialPositionUs;
private long joiningDeadlineMs;
private long droppedFrameAccumulationStartTimeMs;
private int droppedFrames;
Expand Down Expand Up @@ -276,6 +277,7 @@ protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlayba
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
super.onPositionReset(positionUs, joining);
clearRenderedFirstFrame();
initialPositionUs = C.TIME_UNSET;
consecutiveDroppedFrameCount = 0;
if (pendingOutputStreamOffsetCount != 0) {
outputStreamOffsetUs = pendingOutputStreamOffsetsUs[pendingOutputStreamOffsetCount - 1];
Expand Down Expand Up @@ -532,6 +534,10 @@ protected void onOutputFormatChanged(MediaCodec codec, MediaFormat outputFormat)
protected boolean processOutputBuffer(long positionUs, long elapsedRealtimeUs, MediaCodec codec,
ByteBuffer buffer, int bufferIndex, int bufferFlags, long bufferPresentationTimeUs,
boolean shouldSkip) throws ExoPlaybackException {
if (initialPositionUs == C.TIME_UNSET) {
initialPositionUs = positionUs;
}

while (pendingOutputStreamOffsetCount != 0
&& bufferPresentationTimeUs >= pendingOutputStreamOffsetsUs[0]) {
outputStreamOffsetUs = pendingOutputStreamOffsetsUs[0];
Expand Down Expand Up @@ -569,7 +575,7 @@ && shouldForceRenderOutputBuffer(earlyUs, elapsedRealtimeNowUs - lastRenderTimeU
return true;
}

if (!isStarted) {
if (!isStarted || positionUs == initialPositionUs) {
return false;
}

Expand Down

0 comments on commit 8d47209

Please sign in to comment.