From 6f5c7b38a7077d81fe0fd9ff216ce8b5dd34ad09 Mon Sep 17 00:00:00 2001 From: olly Date: Wed, 25 Jan 2017 10:11:58 -0800 Subject: [PATCH] Wait for first sync frame in MediaCodecRenderer For the video renderer, it's not true that the source always provides from a sync frame specifically in the case where the surface has been replaced on the renderer. In this case the source doesn't know that it should be providing from a sync frame. Issue: #2093 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=145562222 --- .../exoplayer2/mediacodec/MediaCodecRenderer.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index 70445466a6..9be1c59baf 100644 --- a/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -201,6 +201,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { private boolean inputStreamEnded; private boolean outputStreamEnded; private boolean waitingForKeys; + private boolean waitingForFirstSyncFrame; protected DecoderCounters decoderCounters; @@ -366,6 +367,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : C.TIME_UNSET; inputIndex = C.INDEX_UNSET; outputIndex = C.INDEX_UNSET; + waitingForFirstSyncFrame = true; decoderCounters.decoderInitCount++; } @@ -504,6 +506,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { codecHotswapDeadlineMs = C.TIME_UNSET; inputIndex = C.INDEX_UNSET; outputIndex = C.INDEX_UNSET; + waitingForFirstSyncFrame = true; waitingForKeys = false; shouldSkipOutputBuffer = false; decodeOnlyPresentationTimestamps.clear(); @@ -633,6 +636,16 @@ public abstract class MediaCodecRenderer extends BaseRenderer { } return false; } + if (waitingForFirstSyncFrame && !buffer.isKeyFrame()) { + buffer.clear(); + if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) { + // The buffer we just cleared contained reconfiguration data. We need to re-write this + // data into a subsequent buffer (if there is one). + codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING; + } + return true; + } + waitingForFirstSyncFrame = false; boolean bufferEncrypted = buffer.isEncrypted(); waitingForKeys = shouldWaitForKeys(bufferEncrypted); if (waitingForKeys) {