Allow LoadControl to configure the back-buffer.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=175833398
This commit is contained in:
olly 2017-11-15 09:08:32 -08:00 committed by Oliver Woodman
parent bd0bc03f64
commit 28693ac7d6
3 changed files with 52 additions and 3 deletions

View file

@ -25,7 +25,7 @@ import com.google.android.exoplayer2.util.Util;
/**
* The default {@link LoadControl} implementation.
*/
public final class DefaultLoadControl implements LoadControl {
public class DefaultLoadControl implements LoadControl {
/**
* The default minimum duration of media that the player will attempt to ensure is buffered at all
@ -163,6 +163,16 @@ public final class DefaultLoadControl implements LoadControl {
return allocator;
}
@Override
public long getBackBufferDurationUs() {
return 0;
}
@Override
public boolean retainBackBufferFromKeyframe() {
return false;
}
@Override
public boolean shouldStartPlayback(long bufferedDurationUs, boolean rebuffering) {
long minBufferDurationUs = rebuffering ? bufferForPlaybackAfterRebufferUs : bufferForPlaybackUs;

View file

@ -107,6 +107,8 @@ import java.io.IOException;
private final Timeline.Window window;
private final Timeline.Period period;
private final MediaPeriodInfoSequence mediaPeriodInfoSequence;
private final long backBufferDurationUs;
private final boolean retainBackBufferFromKeyframe;
private PlaybackInfo playbackInfo;
private PlaybackParameters playbackParameters;
@ -147,6 +149,9 @@ import java.io.IOException;
this.state = Player.STATE_IDLE;
this.player = player;
backBufferDurationUs = loadControl.getBackBufferDurationUs();
retainBackBufferFromKeyframe = loadControl.retainBackBufferFromKeyframe();
playbackInfo = new PlaybackInfo(null, null, 0, C.TIME_UNSET);
rendererCapabilities = new RendererCapabilities[renderers.length];
for (int i = 0; i < renderers.length; i++) {
@ -541,7 +546,8 @@ import java.io.IOException;
TraceUtil.beginSection("doSomeWork");
updatePlaybackPositions();
playingPeriodHolder.mediaPeriod.discardBuffer(playbackInfo.positionUs, false);
playingPeriodHolder.mediaPeriod.discardBuffer(playbackInfo.positionUs - backBufferDurationUs,
retainBackBufferFromKeyframe);
boolean allRenderersEnded = true;
boolean allRenderersReadyOrEnded = true;
@ -732,7 +738,8 @@ import java.io.IOException;
setPlayingPeriodHolder(newPlayingPeriodHolder);
if (playingPeriodHolder.hasEnabledTracks) {
periodPositionUs = playingPeriodHolder.mediaPeriod.seekToUs(periodPositionUs);
playingPeriodHolder.mediaPeriod.discardBuffer(periodPositionUs, false);
playingPeriodHolder.mediaPeriod.discardBuffer(periodPositionUs - backBufferDurationUs,
retainBackBufferFromKeyframe);
}
resetRendererPosition(periodPositionUs);
maybeContinueLoading();

View file

@ -55,6 +55,38 @@ public interface LoadControl {
*/
Allocator getAllocator();
/**
* Returns the duration of media to retain in the buffer prior to the current playback position,
* for fast backward seeking.
* <p>
* Note: If {@link #retainBackBufferFromKeyframe()} is false then seeking in the back-buffer will
* only be fast if the back-buffer contains a keyframe prior to the seek position.
* <p>
* Note: Implementations should return a single value. Dynamic changes to the back-buffer are not
* currently supported.
*
* @return The duration of media to retain in the buffer prior to the current playback position,
* in microseconds.
*/
long getBackBufferDurationUs();
/**
* Returns whether media should be retained from the keyframe before the current playback position
* minus {@link #getBackBufferDurationUs()}, rather than any sample before or at that position.
* <p>
* Warning: Returning true will cause the back-buffer size to depend on the spacing of keyframes
* in the media being played. Returning true is not recommended unless you control the media and
* are comfortable with the back-buffer size exceeding {@link #getBackBufferDurationUs()} by as
* much as the maximum duration between adjacent keyframes in the media.
* <p>
* Note: Implementations should return a single value. Dynamic changes to the back-buffer are not
* currently supported.
*
* @return Whether media should be retained from the keyframe before the current playback position
* minus {@link #getBackBufferDurationUs()}, rather than any sample before or at that position.
*/
boolean retainBackBufferFromKeyframe();
/**
* Called by the player to determine whether sufficient media is buffered for playback to be
* started or resumed.