mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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:
parent
ef24125d20
commit
23c07e5c4d
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user