From 88abb153bb18c9b15be0d8e15ea673cfd9dccf3e Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 2 Jan 2018 06:15:13 -0800 Subject: [PATCH] Force audio renderers to report same position when not started Whilst the previous behavior was WAI and had the advantage of updating the position to be more exact when known, there were a couple of disadvantages: 1. If seeking to the very end of a period in a playlist when paused, the position adjustment could trigger a position discontinuity to the next period. 2. We de-duplicate seeks to the current playback position. The position adjustment can prevent this from being effective. This is particularly important with the new SeekParameters support. When seeking to nearest sync point it's often possible to de-duplicate seeks, but we cannot do so if the playback position adjusts away from the sync point's time. Issue: #2439 Issue: #2882 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=180540736 --- RELEASENOTES.md | 2 + .../audio/MediaCodecAudioRenderer.java | 19 +++++--- .../audio/SimpleDecoderAudioRenderer.java | 45 +++++++++++-------- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 43e860b0007..b0027d75a17 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -78,6 +78,8 @@ ([#3188](https://github.com/google/ExoPlayer/issues/3188)). * CEA-608: Fix handling of row count changes in roll-up mode ([#3513](https://github.com/google/ExoPlayer/issues/3513)). +* Prevent period transitions when seeking to the end of a period when paused + ([#2439](https://github.com/google/ExoPlayer/issues/2439)). ### 2.6.0 ### 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 25ad847f7e1..b4459e42aa4 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 @@ -364,6 +364,7 @@ protected void onStarted() { @Override protected void onStopped() { audioSink.pause(); + updateCurrentPosition(); super.onStopped(); } @@ -393,11 +394,8 @@ public boolean isReady() { @Override public long getPositionUs() { - long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); - if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) { - currentPositionUs = allowPositionDiscontinuity ? newCurrentPositionUs - : Math.max(currentPositionUs, newCurrentPositionUs); - allowPositionDiscontinuity = false; + if (getState() == STATE_STARTED) { + updateCurrentPosition(); } return currentPositionUs; } @@ -466,6 +464,17 @@ public void handleMessage(int messageType, Object message) throws ExoPlaybackExc } } + private void updateCurrentPosition() { + long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); + if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) { + currentPositionUs = + allowPositionDiscontinuity + ? newCurrentPositionUs + : Math.max(currentPositionUs, newCurrentPositionUs); + allowPositionDiscontinuity = false; + } + } + /** * Returns whether the decoder is known to output six audio channels when provided with input with * fewer than six channels. 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 d9ad5491048..16a85fe1f43 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 @@ -459,11 +459,8 @@ public boolean isReady() { @Override public long getPositionUs() { - long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); - if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) { - currentPositionUs = allowPositionDiscontinuity ? newCurrentPositionUs - : Math.max(currentPositionUs, newCurrentPositionUs); - allowPositionDiscontinuity = false; + if (getState() == STATE_STARTED) { + updateCurrentPosition(); } return currentPositionUs; } @@ -510,6 +507,7 @@ protected void onStarted() { @Override protected void onStopped() { audioSink.pause(); + updateCurrentPosition(); } @Override @@ -540,6 +538,22 @@ protected void onDisabled() { } } + @Override + public void handleMessage(int messageType, Object message) throws ExoPlaybackException { + switch (messageType) { + case C.MSG_SET_VOLUME: + audioSink.setVolume((Float) message); + break; + case C.MSG_SET_AUDIO_ATTRIBUTES: + AudioAttributes audioAttributes = (AudioAttributes) message; + audioSink.setAudioAttributes(audioAttributes); + break; + default: + super.handleMessage(messageType, message); + break; + } + } + private void maybeInitDecoder() throws ExoPlaybackException { if (decoder != null) { return; @@ -625,19 +639,14 @@ private void onInputFormatChanged(Format newFormat) throws ExoPlaybackException eventDispatcher.inputFormatChanged(newFormat); } - @Override - public void handleMessage(int messageType, Object message) throws ExoPlaybackException { - switch (messageType) { - case C.MSG_SET_VOLUME: - audioSink.setVolume((Float) message); - break; - case C.MSG_SET_AUDIO_ATTRIBUTES: - AudioAttributes audioAttributes = (AudioAttributes) message; - audioSink.setAudioAttributes(audioAttributes); - break; - default: - super.handleMessage(messageType, message); - break; + private void updateCurrentPosition() { + long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); + if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) { + currentPositionUs = + allowPositionDiscontinuity + ? newCurrentPositionUs + : Math.max(currentPositionUs, newCurrentPositionUs); + allowPositionDiscontinuity = false; } }