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) {