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
This commit is contained in:
olly 2018-01-02 06:15:13 -08:00 committed by Oliver Woodman
parent 2bd704d833
commit 88abb153bb
3 changed files with 43 additions and 23 deletions

View File

@ -78,6 +78,8 @@
([#3188](https://github.com/google/ExoPlayer/issues/3188)). ([#3188](https://github.com/google/ExoPlayer/issues/3188)).
* CEA-608: Fix handling of row count changes in roll-up mode * CEA-608: Fix handling of row count changes in roll-up mode
([#3513](https://github.com/google/ExoPlayer/issues/3513)). ([#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 ### ### 2.6.0 ###

View File

@ -364,6 +364,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override @Override
protected void onStopped() { protected void onStopped() {
audioSink.pause(); audioSink.pause();
updateCurrentPosition();
super.onStopped(); super.onStopped();
} }
@ -393,11 +394,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override @Override
public long getPositionUs() { public long getPositionUs() {
long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); if (getState() == STATE_STARTED) {
if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) { updateCurrentPosition();
currentPositionUs = allowPositionDiscontinuity ? newCurrentPositionUs
: Math.max(currentPositionUs, newCurrentPositionUs);
allowPositionDiscontinuity = false;
} }
return currentPositionUs; return currentPositionUs;
} }
@ -466,6 +464,17 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
} }
} }
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 * Returns whether the decoder is known to output six audio channels when provided with input with
* fewer than six channels. * fewer than six channels.

View File

@ -459,11 +459,8 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
@Override @Override
public long getPositionUs() { public long getPositionUs() {
long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); if (getState() == STATE_STARTED) {
if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) { updateCurrentPosition();
currentPositionUs = allowPositionDiscontinuity ? newCurrentPositionUs
: Math.max(currentPositionUs, newCurrentPositionUs);
allowPositionDiscontinuity = false;
} }
return currentPositionUs; return currentPositionUs;
} }
@ -510,6 +507,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
@Override @Override
protected void onStopped() { protected void onStopped() {
audioSink.pause(); audioSink.pause();
updateCurrentPosition();
} }
@Override @Override
@ -540,6 +538,22 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
} }
} }
@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 { private void maybeInitDecoder() throws ExoPlaybackException {
if (decoder != null) { if (decoder != null) {
return; return;
@ -625,19 +639,14 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
eventDispatcher.inputFormatChanged(newFormat); eventDispatcher.inputFormatChanged(newFormat);
} }
@Override private void updateCurrentPosition() {
public void handleMessage(int messageType, Object message) throws ExoPlaybackException { long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded());
switch (messageType) { if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) {
case C.MSG_SET_VOLUME: currentPositionUs =
audioSink.setVolume((Float) message); allowPositionDiscontinuity
break; ? newCurrentPositionUs
case C.MSG_SET_AUDIO_ATTRIBUTES: : Math.max(currentPositionUs, newCurrentPositionUs);
AudioAttributes audioAttributes = (AudioAttributes) message; allowPositionDiscontinuity = false;
audioSink.setAudioAttributes(audioAttributes);
break;
default:
super.handleMessage(messageType, message);
break;
} }
} }