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)).
* 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 ###

View File

@ -364,6 +364,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
protected void onStopped() {
audioSink.pause();
updateCurrentPosition();
super.onStopped();
}
@ -393,11 +394,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@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 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
* fewer than six channels.

View File

@ -459,11 +459,8 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
@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 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
@Override
protected void onStopped() {
audioSink.pause();
updateCurrentPosition();
}
@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 {
if (decoder != null) {
return;
@ -625,19 +639,14 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
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;
}
}