Wire up experiment to use AdaptiveTrackSelection based selections
LegacyVideoTrackSelection is the previous implementation (unchanged). VideoTrackSelection is rewritten to extend AdaptiveTrackSelection. An experiment is added to allow use of the new VideoTrackSelection implementation. It's envisaged that this transition will be more or less a no-op change. The experiment flag is only in case of bugs during roll-out, and will be removed with LegacyVideoTrackSelection upon successful transition. VideoTrackSelection also implements discard-on-trick-play-exit, which was a TODO in the previous implementation. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=221153827
This commit is contained in:
parent
f5af6e8f16
commit
c20b157bd7
@ -255,7 +255,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
||||
private final Clock clock;
|
||||
private final Format[] formats;
|
||||
private final int[] formatBitrates;
|
||||
private final int[] estimatedBitrates;
|
||||
private final int[] trackBitrates;
|
||||
|
||||
private TrackBitrateEstimator trackBitrateEstimator;
|
||||
private float playbackSpeed;
|
||||
@ -338,7 +338,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
||||
trackBitrateEstimator = TrackBitrateEstimator.DEFAULT;
|
||||
formats = new Format[length];
|
||||
formatBitrates = new int[length];
|
||||
estimatedBitrates = new int[length];
|
||||
trackBitrates = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
@SuppressWarnings("nullness:method.invocation.invalid")
|
||||
Format format = getFormat(i);
|
||||
@ -380,11 +380,12 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
||||
MediaChunkIterator[] mediaChunkIterators) {
|
||||
long nowMs = clock.elapsedRealtime();
|
||||
|
||||
trackBitrateEstimator.getBitrates(formats, queue, mediaChunkIterators, estimatedBitrates);
|
||||
// Update the estimated track bitrates.
|
||||
trackBitrateEstimator.getBitrates(formats, queue, mediaChunkIterators, trackBitrates);
|
||||
|
||||
// Stash the current selection, then make a new one.
|
||||
int currentSelectedIndex = selectedIndex;
|
||||
selectedIndex = determineIdealSelectedIndex(nowMs, estimatedBitrates);
|
||||
selectedIndex = determineIdealSelectedIndex(nowMs, trackBitrates);
|
||||
if (selectedIndex == currentSelectedIndex) {
|
||||
return;
|
||||
}
|
||||
@ -429,10 +430,10 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
||||
@Override
|
||||
public int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue) {
|
||||
long nowMs = clock.elapsedRealtime();
|
||||
if (lastBufferEvaluationMs != C.TIME_UNSET
|
||||
&& nowMs - lastBufferEvaluationMs < minTimeBetweenBufferReevaluationMs) {
|
||||
if (!shouldEvaluateQueueSize(nowMs)) {
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
lastBufferEvaluationMs = nowMs;
|
||||
if (queue.isEmpty()) {
|
||||
return 0;
|
||||
@ -443,6 +444,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
||||
long playoutBufferedDurationBeforeLastChunkUs =
|
||||
Util.getPlayoutDurationForMediaDuration(
|
||||
lastChunk.startTimeUs - playbackPositionUs, playbackSpeed);
|
||||
long minDurationToRetainAfterDiscardUs = getMinDurationToRetainAfterDiscardUs();
|
||||
if (playoutBufferedDurationBeforeLastChunkUs < minDurationToRetainAfterDiscardUs) {
|
||||
return queueSize;
|
||||
}
|
||||
@ -468,19 +470,59 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
||||
return queueSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when updating the selected track to determine whether a candidate track can be selected.
|
||||
*
|
||||
* @param format The {@link Format} of the candidate track.
|
||||
* @param trackBitrate The estimated bitrate of the track. May differ from {@link Format#bitrate}
|
||||
* if a more accurate estimate of the current track bitrate is available.
|
||||
* @param playbackSpeed The current playback speed.
|
||||
* @param effectiveBitrate The bitrate available to this selection.
|
||||
* @return Whether this {@link Format} can be selected.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected boolean canSelectFormat(
|
||||
Format format, int trackBitrate, float playbackSpeed, long effectiveBitrate) {
|
||||
return Math.round(trackBitrate * playbackSpeed) <= effectiveBitrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link #evaluateQueueSize(long, List)} to determine whether an evaluation should be
|
||||
* performed.
|
||||
*
|
||||
* @param nowMs The current value of {@link Clock#elapsedRealtime()}.
|
||||
* @return Whether an evaluation should be performed.
|
||||
*/
|
||||
protected boolean shouldEvaluateQueueSize(long nowMs) {
|
||||
return lastBufferEvaluationMs == C.TIME_UNSET
|
||||
|| nowMs - lastBufferEvaluationMs >= minTimeBetweenBufferReevaluationMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link #evaluateQueueSize(long, List)} to determine the minimum duration of buffer
|
||||
* to retain after discarding chunks.
|
||||
*
|
||||
* @return The minimum duration of buffer to retain after discarding chunks, in microseconds.
|
||||
*/
|
||||
protected long getMinDurationToRetainAfterDiscardUs() {
|
||||
return minDurationToRetainAfterDiscardUs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the ideal selected index ignoring buffer health.
|
||||
*
|
||||
* @param nowMs The current time in the timebase of {@link Clock#elapsedRealtime()}, or {@link
|
||||
* Long#MIN_VALUE} to ignore blacklisting.
|
||||
* @param bitrates Track bitrates.
|
||||
* @param trackBitrates The estimated track bitrates. May differ from format bitrates if more
|
||||
* accurate estimates of the current track bitrates are available.
|
||||
*/
|
||||
private int determineIdealSelectedIndex(long nowMs, int[] bitrates) {
|
||||
private int determineIdealSelectedIndex(long nowMs, int[] trackBitrates) {
|
||||
long effectiveBitrate = (long) (bandwidthMeter.getBitrateEstimate() * bandwidthFraction);
|
||||
int lowestBitrateNonBlacklistedIndex = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (nowMs == Long.MIN_VALUE || !isBlacklisted(i, nowMs)) {
|
||||
if (Math.round(bitrates[i] * playbackSpeed) <= effectiveBitrate) {
|
||||
Format format = getFormat(i);
|
||||
if (canSelectFormat(format, trackBitrates[i], playbackSpeed, effectiveBitrate)) {
|
||||
return i;
|
||||
} else {
|
||||
lowestBitrateNonBlacklistedIndex = i;
|
||||
|
Loading…
x
Reference in New Issue
Block a user