From 23c07e5c4d1077e67087fa80d8b27d571cf5a60b Mon Sep 17 00:00:00 2001 From: tonihei Date: Fri, 18 Jan 2019 14:57:10 +0000 Subject: [PATCH] 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 --- .../BufferSizeAdaptationBuilder.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BufferSizeAdaptationBuilder.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BufferSizeAdaptationBuilder.java index 5c8350cb1d..ee1d1c62da 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BufferSizeAdaptationBuilder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BufferSizeAdaptationBuilder.java @@ -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 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;