From f2f5aac7c5d1ba7aed0ea03994e604f4088114cf Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 26 Feb 2018 02:02:32 -0800 Subject: [PATCH] Allow audio position to jump on first input buffer Allow the position to jump on receiving the first presentable input buffer, if and only if the buffer timestamp differs significantly from what was expected. This prevents a stuck buffering case for streams that are thought to start at t=0, but actually start at t=large_value. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=186990214 --- .../audio/MediaCodecAudioRenderer.java | 16 ++++++++++++++++ .../audio/SimpleDecoderAudioRenderer.java | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java index a7063e5a7f..33a67554a5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java @@ -29,6 +29,7 @@ import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; @@ -70,6 +71,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media private int encoderDelay; private int encoderPadding; private long currentPositionUs; + private boolean allowFirstBufferPositionDiscontinuity; private boolean allowPositionDiscontinuity; /** @@ -366,6 +368,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media super.onPositionReset(positionUs, joining); audioSink.reset(); currentPositionUs = positionUs; + allowFirstBufferPositionDiscontinuity = true; allowPositionDiscontinuity = true; } @@ -424,6 +427,19 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media return audioSink.getPlaybackParameters(); } + @Override + protected void onQueueInputBuffer(DecoderInputBuffer buffer) { + if (allowFirstBufferPositionDiscontinuity && !buffer.isDecodeOnly()) { + // TODO: Remove this hack once we have a proper fix for [Internal: b/71876314]. + // Allow the position to jump if the first presentable input buffer has a timestamp that + // differs significantly from what was expected. + if (Math.abs(buffer.timeUs - currentPositionUs) > 500000) { + currentPositionUs = buffer.timeUs; + } + allowFirstBufferPositionDiscontinuity = false; + } + } + @Override protected boolean processOutputBuffer(long positionUs, long elapsedRealtimeUs, MediaCodec codec, ByteBuffer buffer, int bufferIndex, int bufferFlags, long bufferPresentationTimeUs, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java index 2f5e7bcf97..83c33ee6d7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java @@ -105,6 +105,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements private boolean audioTrackNeedsConfigure; private long currentPositionUs; + private boolean allowFirstBufferPositionDiscontinuity; private boolean allowPositionDiscontinuity; private boolean inputStreamEnded; private boolean outputStreamEnded; @@ -416,6 +417,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements return false; } inputBuffer.flip(); + onQueueInputBuffer(inputBuffer); decoder.queueInputBuffer(inputBuffer); decoderReceivedBuffers = true; decoderCounters.inputBufferCount++; @@ -504,6 +506,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { audioSink.reset(); currentPositionUs = positionUs; + allowFirstBufferPositionDiscontinuity = true; allowPositionDiscontinuity = true; inputStreamEnded = false; outputStreamEnded = false; @@ -654,6 +657,18 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements eventDispatcher.inputFormatChanged(newFormat); } + private void onQueueInputBuffer(DecoderInputBuffer buffer) { + if (allowFirstBufferPositionDiscontinuity && !buffer.isDecodeOnly()) { + // TODO: Remove this hack once we have a proper fix for [Internal: b/71876314]. + // Allow the position to jump if the first presentable input buffer has a timestamp that + // differs significantly from what was expected. + if (Math.abs(buffer.timeUs - currentPositionUs) > 500000) { + currentPositionUs = buffer.timeUs; + } + allowFirstBufferPositionDiscontinuity = false; + } + } + private void updateCurrentPosition() { long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) {