Update buffer-based ABR to not select track in constructor.

This mimicks a similar change in the default AdaptiveTrackSelection.
Also adds an option to cap initial format height.

PiperOrigin-RevId: 229923149
This commit is contained in:
tonihei 2019-01-18 14:57:10 +00:00 committed by Oliver Woodman
parent ef24125d20
commit 23c07e5c4d

View File

@ -43,7 +43,7 @@ public final class BufferSizeAdaptationBuilder {
public interface DynamicFormatFilter {
/** Filter which allows all formats. */
DynamicFormatFilter NO_FILTER = (format, trackBitrate) -> true;
DynamicFormatFilter NO_FILTER = (format, trackBitrate, isInitialSelection) -> true;
/**
* Called when updating the selected track to determine whether a candidate track is allowed. If
@ -52,8 +52,9 @@ public final class BufferSizeAdaptationBuilder {
* @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 isInitialSelection Whether this is for the initial track selection.
*/
boolean isFormatAllowed(Format format, int trackBitrate);
boolean isFormatAllowed(Format format, int trackBitrate, boolean isInitialSelection);
}
/**
@ -344,7 +345,7 @@ public final class BufferSizeAdaptationBuilder {
formatBitrates = new int[length];
maxBitrate = getFormat(/* index= */ 0).bitrate;
minBitrate = getFormat(/* index= */ length - 1).bitrate;
selectionReason = C.SELECTION_REASON_INITIAL;
selectionReason = C.SELECTION_REASON_UNKNOWN;
playbackSpeed = 1.0f;
// We use a log-linear function to map from bitrate to buffer size:
@ -354,9 +355,6 @@ public final class BufferSizeAdaptationBuilder {
(maxBufferUs - hysteresisBufferUs - minBufferUs) / Math.log(maxBitrate / minBitrate);
bitrateToBufferFunctionIntercept =
minBufferUs - bitrateToBufferFunctionSlope * Math.log(minBitrate);
updateFormatBitrates(/* nowMs= */ Long.MIN_VALUE);
selectedIndex = selectIdealIndexUsingBandwidth();
}
@Override
@ -393,6 +391,14 @@ public final class BufferSizeAdaptationBuilder {
List<? extends MediaChunk> queue,
MediaChunkIterator[] mediaChunkIterators) {
updateFormatBitrates(/* nowMs= */ clock.elapsedRealtime());
// Make initial selection
if (selectionReason == C.SELECTION_REASON_UNKNOWN) {
selectionReason = C.SELECTION_REASON_INITIAL;
selectedIndex = selectIdealIndexUsingBandwidth(/* isInitialSelection= */ true);
return;
}
long bufferUs = getCurrentPeriodBufferedDurationUs(playbackPositionUs, bufferedDurationUs);
int oldSelectedIndex = selectedIndex;
if (isInSteadyState) {
@ -428,7 +434,8 @@ public final class BufferSizeAdaptationBuilder {
for (int i = 0; i < formatBitrates.length; i++) {
if (formatBitrates[i] != BITRATE_BLACKLISTED) {
if (getTargetBufferForBitrateUs(formatBitrates[i]) < bufferUs
&& dynamicFormatFilter.isFormatAllowed(getFormat(i), formatBitrates[i])) {
&& dynamicFormatFilter.isFormatAllowed(
getFormat(i), formatBitrates[i], /* isInitialSelection= */ false)) {
return i;
}
lowestBitrateNonBlacklistedIndex = i;
@ -440,7 +447,7 @@ public final class BufferSizeAdaptationBuilder {
// Startup.
private void selectIndexStartUpPhase(long bufferUs) {
int startUpSelectedIndex = selectIdealIndexUsingBandwidth();
int startUpSelectedIndex = selectIdealIndexUsingBandwidth(/* isInitialSelection= */ false);
int steadyStateSelectedIndex = selectIdealIndexUsingBufferSize(bufferUs);
if (steadyStateSelectedIndex <= selectedIndex) {
// Switch to steady state if we have enough buffer to maintain current selection.
@ -457,14 +464,15 @@ public final class BufferSizeAdaptationBuilder {
}
}
private int selectIdealIndexUsingBandwidth() {
private int selectIdealIndexUsingBandwidth(boolean isInitialSelection) {
long effectiveBitrate =
(long) (bandwidthMeter.getBitrateEstimate() * startUpBandwidthFraction);
int lowestBitrateNonBlacklistedIndex = 0;
for (int i = 0; i < formatBitrates.length; i++) {
if (formatBitrates[i] != BITRATE_BLACKLISTED) {
if (Math.round(formatBitrates[i] * playbackSpeed) <= effectiveBitrate
&& dynamicFormatFilter.isFormatAllowed(getFormat(i), formatBitrates[i])) {
&& dynamicFormatFilter.isFormatAllowed(
getFormat(i), formatBitrates[i], isInitialSelection)) {
return i;
}
lowestBitrateNonBlacklistedIndex = i;