Do not select a track in AdaptiveTrackSelection constructor.

This is not necessary as the track selection needs to be updated with
updateSelectedTrack anyway. It's also error-prone as the selection code
calls into a protected method of a not fully initialized class.

PiperOrigin-RevId: 229331669
This commit is contained in:
tonihei 2019-01-15 09:32:38 +00:00 committed by Oliver Woodman
parent 9ab08bbe5d
commit 1900e94144
2 changed files with 64 additions and 38 deletions

View File

@ -391,7 +391,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
this.minTimeBetweenBufferReevaluationMs = minTimeBetweenBufferReevaluationMs; this.minTimeBetweenBufferReevaluationMs = minTimeBetweenBufferReevaluationMs;
this.clock = clock; this.clock = clock;
playbackSpeed = 1f; playbackSpeed = 1f;
reason = C.SELECTION_REASON_INITIAL; reason = C.SELECTION_REASON_UNKNOWN;
lastBufferEvaluationMs = C.TIME_UNSET; lastBufferEvaluationMs = C.TIME_UNSET;
trackBitrateEstimator = TrackBitrateEstimator.DEFAULT; trackBitrateEstimator = TrackBitrateEstimator.DEFAULT;
formats = new Format[length]; formats = new Format[length];
@ -403,9 +403,6 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
formats[i] = format; formats[i] = format;
formatBitrates[i] = formats[i].bitrate; formatBitrates[i] = formats[i].bitrate;
} }
@SuppressWarnings("nullness:method.invocation.invalid")
int selectedIndex = determineIdealSelectedIndex(Long.MIN_VALUE, formatBitrates);
this.selectedIndex = selectedIndex;
} }
/** /**
@ -453,6 +450,13 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
// Update the estimated track bitrates. // Update the estimated track bitrates.
trackBitrateEstimator.getBitrates(formats, queue, mediaChunkIterators, trackBitrates); trackBitrateEstimator.getBitrates(formats, queue, mediaChunkIterators, trackBitrates);
// Make initial selection
if (reason == C.SELECTION_REASON_UNKNOWN) {
reason = C.SELECTION_REASON_INITIAL;
selectedIndex = determineIdealSelectedIndex(nowMs, trackBitrates);
return;
}
// Stash the current selection, then make a new one. // Stash the current selection, then make a new one.
int currentSelectedIndex = selectedIndex; int currentSelectedIndex = selectedIndex;
selectedIndex = determineIdealSelectedIndex(nowMs, trackBitrates); selectedIndex = determineIdealSelectedIndex(nowMs, trackBitrates);

View File

@ -244,7 +244,14 @@ public final class AdaptiveTrackSelectionTest {
// But TrackBitrateEstimator returns 1500 for 3rd track so it should switch up. // But TrackBitrateEstimator returns 1500 for 3rd track so it should switch up.
TrackBitrateEstimator estimator = mock(TrackBitrateEstimator.class); TrackBitrateEstimator estimator = mock(TrackBitrateEstimator.class);
when(estimator.getBitrates(any(), any(), any(), any())).thenReturn(new int[] {500, 1000, 1500}); when(estimator.getBitrates(any(), any(), any(), any()))
.then(
(invocation) -> {
int[] returnValue = new int[] {500, 1000, 1500};
int[] inputArray = (int[]) invocation.getArguments()[3];
System.arraycopy(returnValue, 0, inputArray, 0, returnValue.length);
return returnValue;
});
adaptiveTrackSelection = adaptiveTrackSelection(trackGroup); adaptiveTrackSelection = adaptiveTrackSelection(trackGroup);
adaptiveTrackSelection.experimental_setTrackBitrateEstimator(estimator); adaptiveTrackSelection.experimental_setTrackBitrateEstimator(estimator);
@ -385,49 +392,64 @@ public final class AdaptiveTrackSelectionTest {
private AdaptiveTrackSelection adaptiveTrackSelectionWithMinDurationForQualityIncreaseMs( private AdaptiveTrackSelection adaptiveTrackSelectionWithMinDurationForQualityIncreaseMs(
TrackGroup trackGroup, long minDurationForQualityIncreaseMs) { TrackGroup trackGroup, long minDurationForQualityIncreaseMs) {
return new AdaptiveTrackSelection( return prepareTrackSelection(
trackGroup, new AdaptiveTrackSelection(
selectedAllTracksInGroup(trackGroup), trackGroup,
mockBandwidthMeter, selectedAllTracksInGroup(trackGroup),
minDurationForQualityIncreaseMs, mockBandwidthMeter,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS, minDurationForQualityIncreaseMs,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS, AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
/* bandwidthFraction= */ 1.0f, AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS,
AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE, /* bandwidthFraction= */ 1.0f,
AdaptiveTrackSelection.DEFAULT_MIN_TIME_BETWEEN_BUFFER_REEVALUTATION_MS, AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE,
fakeClock); AdaptiveTrackSelection.DEFAULT_MIN_TIME_BETWEEN_BUFFER_REEVALUTATION_MS,
fakeClock));
} }
private AdaptiveTrackSelection adaptiveTrackSelectionWithMaxDurationForQualityDecreaseMs( private AdaptiveTrackSelection adaptiveTrackSelectionWithMaxDurationForQualityDecreaseMs(
TrackGroup trackGroup, long maxDurationForQualityDecreaseMs) { TrackGroup trackGroup, long maxDurationForQualityDecreaseMs) {
return new AdaptiveTrackSelection( return prepareTrackSelection(
trackGroup, new AdaptiveTrackSelection(
selectedAllTracksInGroup(trackGroup), trackGroup,
mockBandwidthMeter, selectedAllTracksInGroup(trackGroup),
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS, mockBandwidthMeter,
maxDurationForQualityDecreaseMs, AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS, maxDurationForQualityDecreaseMs,
/* bandwidthFraction= */ 1.0f, AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS,
AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE, /* bandwidthFraction= */ 1.0f,
AdaptiveTrackSelection.DEFAULT_MIN_TIME_BETWEEN_BUFFER_REEVALUTATION_MS, AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE,
fakeClock); AdaptiveTrackSelection.DEFAULT_MIN_TIME_BETWEEN_BUFFER_REEVALUTATION_MS,
fakeClock));
} }
private AdaptiveTrackSelection adaptiveTrackSelectionWithMinTimeBetweenBufferReevaluationMs( private AdaptiveTrackSelection adaptiveTrackSelectionWithMinTimeBetweenBufferReevaluationMs(
TrackGroup trackGroup, TrackGroup trackGroup,
long durationToRetainAfterDiscardMs, long durationToRetainAfterDiscardMs,
long minTimeBetweenBufferReevaluationMs) { long minTimeBetweenBufferReevaluationMs) {
return new AdaptiveTrackSelection( return prepareTrackSelection(
trackGroup, new AdaptiveTrackSelection(
selectedAllTracksInGroup(trackGroup), trackGroup,
mockBandwidthMeter, selectedAllTracksInGroup(trackGroup),
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS, mockBandwidthMeter,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS, AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
durationToRetainAfterDiscardMs, AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
/* bandwidthFraction= */ 1.0f, durationToRetainAfterDiscardMs,
AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE, /* bandwidthFraction= */ 1.0f,
minTimeBetweenBufferReevaluationMs, AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE,
fakeClock); minTimeBetweenBufferReevaluationMs,
fakeClock));
}
private AdaptiveTrackSelection prepareTrackSelection(
AdaptiveTrackSelection adaptiveTrackSelection) {
adaptiveTrackSelection.enable();
adaptiveTrackSelection.updateSelectedTrack(
/* playbackPositionUs= */ 0,
/* bufferedDurationUs= */ 0,
/* availableDurationUs= */ C.TIME_UNSET,
/* queue= */ Collections.emptyList(),
/* mediaChunkIterators= */ THREE_EMPTY_MEDIA_CHUNK_ITERATORS);
return adaptiveTrackSelection;
} }
private int[] selectedAllTracksInGroup(TrackGroup trackGroup) { private int[] selectedAllTracksInGroup(TrackGroup trackGroup) {