Commit 7907f4e0 by tonihei Committed by Ian Baker

Make usage of live minDurationForQualityIncrease more consistent

We have two ways to choose the minDurationForQualityIncreaseMs value in
AdaptiveTrackSelection: use the configured value for non-live or when
enough buffered data is available, or use a fraction of the available
duration to allow switching when playing close to the live edge.

The decision point when to use which value isn't quite consistent because
we compare against availableDurationUs before making the adjustments. This
means there is range of values where no up-switching is possible despite
perfect buffering. Fix this by choosing the minimum of both values.

Issue: google/ExoPlayer#9784

#minor-release

PiperOrigin-RevId: 428474332
parent 1e66483b
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min;
import androidx.annotation.CallSuper; import androidx.annotation.CallSuper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -602,10 +603,8 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { ...@@ -602,10 +603,8 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
} }
private long minDurationForQualityIncreaseUs(long availableDurationUs, long chunkDurationUs) { private long minDurationForQualityIncreaseUs(long availableDurationUs, long chunkDurationUs) {
boolean isAvailableDurationTooShort = if (availableDurationUs == C.TIME_UNSET) {
availableDurationUs != C.TIME_UNSET // We are not in a live stream. Use the configured value.
&& availableDurationUs <= minDurationForQualityIncreaseUs;
if (!isAvailableDurationTooShort) {
return minDurationForQualityIncreaseUs; return minDurationForQualityIncreaseUs;
} }
if (chunkDurationUs != C.TIME_UNSET) { if (chunkDurationUs != C.TIME_UNSET) {
...@@ -616,7 +615,9 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { ...@@ -616,7 +615,9 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
// actually achievable. // actually achievable.
availableDurationUs -= chunkDurationUs; availableDurationUs -= chunkDurationUs;
} }
return (long) (availableDurationUs * bufferedFractionToLiveEdgeForQualityIncrease); long adjustedMinDurationForQualityIncreaseUs =
(long) (availableDurationUs * bufferedFractionToLiveEdgeForQualityIncrease);
return min(adjustedMinDurationForQualityIncreaseUs, minDurationForQualityIncreaseUs);
} }
/** /**
......
...@@ -174,7 +174,9 @@ public final class AdaptiveTrackSelectionTest { ...@@ -174,7 +174,9 @@ public final class AdaptiveTrackSelectionTest {
when(mockBandwidthMeter.getBitrateEstimate()).thenReturn(1000L, 2000L); when(mockBandwidthMeter.getBitrateEstimate()).thenReturn(1000L, 2000L);
AdaptiveTrackSelection adaptiveTrackSelection = AdaptiveTrackSelection adaptiveTrackSelection =
prepareAdaptiveTrackSelectionWithBufferedFractionToLiveEdgeForQualiyIncrease( prepareAdaptiveTrackSelectionWithBufferedFractionToLiveEdgeForQualiyIncrease(
trackGroup, /* bufferedFractionToLiveEdgeForQualityIncrease= */ 0.75f); trackGroup,
/* bufferedFractionToLiveEdgeForQualityIncrease= */ 0.75f,
/* minDurationForQualityIncreaseMs= */ 5000);
// Not buffered close to live edge yet. // Not buffered close to live edge yet.
adaptiveTrackSelection.updateSelectedTrack( adaptiveTrackSelection.updateSelectedTrack(
...@@ -187,6 +189,8 @@ public final class AdaptiveTrackSelectionTest { ...@@ -187,6 +189,8 @@ public final class AdaptiveTrackSelectionTest {
assertThat(adaptiveTrackSelection.getSelectedFormat()).isEqualTo(format2); assertThat(adaptiveTrackSelection.getSelectedFormat()).isEqualTo(format2);
// Buffered all possible chunks (except for newly added chunk of 2 seconds). // Buffered all possible chunks (except for newly added chunk of 2 seconds).
// Intentionally choose a situation where availableDurationUs > minDurationForQualityIncreaseMs
// to ensure the live calculation is used regardless.
adaptiveTrackSelection.updateSelectedTrack( adaptiveTrackSelection.updateSelectedTrack(
/* playbackPositionUs= */ 0, /* playbackPositionUs= */ 0,
/* bufferedDurationUs= */ 3_600_000, /* bufferedDurationUs= */ 3_600_000,
...@@ -767,14 +771,16 @@ public final class AdaptiveTrackSelectionTest { ...@@ -767,14 +771,16 @@ public final class AdaptiveTrackSelectionTest {
private AdaptiveTrackSelection private AdaptiveTrackSelection
prepareAdaptiveTrackSelectionWithBufferedFractionToLiveEdgeForQualiyIncrease( prepareAdaptiveTrackSelectionWithBufferedFractionToLiveEdgeForQualiyIncrease(
TrackGroup trackGroup, float bufferedFractionToLiveEdgeForQualityIncrease) { TrackGroup trackGroup,
float bufferedFractionToLiveEdgeForQualityIncrease,
long minDurationForQualityIncreaseMs) {
return prepareTrackSelection( return prepareTrackSelection(
new AdaptiveTrackSelection( new AdaptiveTrackSelection(
trackGroup, trackGroup,
selectedAllTracksInGroup(trackGroup), selectedAllTracksInGroup(trackGroup),
TrackSelection.TYPE_UNSET, TrackSelection.TYPE_UNSET,
mockBandwidthMeter, mockBandwidthMeter,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS, minDurationForQualityIncreaseMs,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS, AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS, AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS,
AdaptiveTrackSelection.DEFAULT_MAX_WIDTH_TO_DISCARD, AdaptiveTrackSelection.DEFAULT_MAX_WIDTH_TO_DISCARD,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment