Tweak DefaultLivePlaybackSpeedControl parameters.

Changing them to have fewer updates when adjusting the playback speed.

PiperOrigin-RevId: 341834423
This commit is contained in:
tonihei 2020-11-11 16:21:47 +00:00 committed by Christos Tsilopoulos
parent 3b8b2f707b
commit 51c8ffbb0e
2 changed files with 35 additions and 17 deletions

View File

@ -30,8 +30,8 @@ import com.google.android.exoplayer2.util.Util;
* *
* <p>The control mechanism calculates the adjusted speed as {@code 1.0 + proportionalControlFactor * <p>The control mechanism calculates the adjusted speed as {@code 1.0 + proportionalControlFactor
* x (currentLiveOffsetSec - targetLiveOffsetSec)}. Unit speed (1.0f) is used, if the {@code * x (currentLiveOffsetSec - targetLiveOffsetSec)}. Unit speed (1.0f) is used, if the {@code
* currentLiveOffsetSec} is marginally close to {@code targetLiveOffsetSec}, i.e. {@code * currentLiveOffsetSec} is closer to {@code targetLiveOffsetSec} than the value set with {@link
* |currentLiveOffsetSec - targetLiveOffsetSec| <= MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED}. * Builder#setMaxLiveOffsetErrorMsForUnitSpeed(long)}.
* *
* <p>The resulting speed is clamped to a minimum and maximum speed defined by the media, the * <p>The resulting speed is clamped to a minimum and maximum speed defined by the media, the
* fallback values set with {@link Builder#setFallbackMinPlaybackSpeed(float)} and {@link * fallback values set with {@link Builder#setFallbackMinPlaybackSpeed(float)} and {@link
@ -63,13 +63,13 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
* The default {@link Builder#setMinUpdateIntervalMs(long) minimum interval} between playback * The default {@link Builder#setMinUpdateIntervalMs(long) minimum interval} between playback
* speed changes, in milliseconds. * speed changes, in milliseconds.
*/ */
public static final long DEFAULT_MIN_UPDATE_INTERVAL_MS = 500; public static final long DEFAULT_MIN_UPDATE_INTERVAL_MS = 1_000;
/** /**
* The default {@link Builder#setProportionalControlFactor(float) proportional control factor} * The default {@link Builder#setProportionalControlFactor(float) proportional control factor}
* used to adjust the playback speed. * used to adjust the playback speed.
*/ */
public static final float DEFAULT_PROPORTIONAL_CONTROL_FACTOR = 0.05f; public static final float DEFAULT_PROPORTIONAL_CONTROL_FACTOR = 0.1f;
/** /**
* The default increment applied to the target live offset each time the player is rebuffering, in * The default increment applied to the target live offset each time the player is rebuffering, in
@ -84,10 +84,10 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
public static final float DEFAULT_MIN_POSSIBLE_LIVE_OFFSET_SMOOTHING_FACTOR = 0.999f; public static final float DEFAULT_MIN_POSSIBLE_LIVE_OFFSET_SMOOTHING_FACTOR = 0.999f;
/** /**
* The maximum difference between the current live offset and the target live offset for which * The default maximum difference between the current live offset and the target live offset, in
* unit speed (1.0f) is used. * milliseconds, for which unit speed (1.0f) is used.
*/ */
public static final long MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED = 5_000; public static final long DEFAULT_MAX_LIVE_OFFSET_ERROR_MS_FOR_UNIT_SPEED = 20;
/** Builder for a {@link DefaultLivePlaybackSpeedControl}. */ /** Builder for a {@link DefaultLivePlaybackSpeedControl}. */
public static final class Builder { public static final class Builder {
@ -96,6 +96,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
private float fallbackMaxPlaybackSpeed; private float fallbackMaxPlaybackSpeed;
private long minUpdateIntervalMs; private long minUpdateIntervalMs;
private float proportionalControlFactorUs; private float proportionalControlFactorUs;
private long maxLiveOffsetErrorUsForUnitSpeed;
private long targetLiveOffsetIncrementOnRebufferUs; private long targetLiveOffsetIncrementOnRebufferUs;
private float minPossibleLiveOffsetSmoothingFactor; private float minPossibleLiveOffsetSmoothingFactor;
@ -105,6 +106,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
fallbackMaxPlaybackSpeed = DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED; fallbackMaxPlaybackSpeed = DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED;
minUpdateIntervalMs = DEFAULT_MIN_UPDATE_INTERVAL_MS; minUpdateIntervalMs = DEFAULT_MIN_UPDATE_INTERVAL_MS;
proportionalControlFactorUs = DEFAULT_PROPORTIONAL_CONTROL_FACTOR / C.MICROS_PER_SECOND; proportionalControlFactorUs = DEFAULT_PROPORTIONAL_CONTROL_FACTOR / C.MICROS_PER_SECOND;
maxLiveOffsetErrorUsForUnitSpeed = C.msToUs(DEFAULT_MAX_LIVE_OFFSET_ERROR_MS_FOR_UNIT_SPEED);
targetLiveOffsetIncrementOnRebufferUs = targetLiveOffsetIncrementOnRebufferUs =
C.msToUs(DEFAULT_TARGET_LIVE_OFFSET_INCREMENT_ON_REBUFFER_MS); C.msToUs(DEFAULT_TARGET_LIVE_OFFSET_INCREMENT_ON_REBUFFER_MS);
minPossibleLiveOffsetSmoothingFactor = DEFAULT_MIN_POSSIBLE_LIVE_OFFSET_SMOOTHING_FACTOR; minPossibleLiveOffsetSmoothingFactor = DEFAULT_MIN_POSSIBLE_LIVE_OFFSET_SMOOTHING_FACTOR;
@ -173,6 +175,22 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
return this; return this;
} }
/**
* Sets the maximum difference between the current live offset and the target live offset, in
* milliseconds, for which unit speed (1.0f) is used.
*
* <p>The default is {@link #DEFAULT_MAX_LIVE_OFFSET_ERROR_MS_FOR_UNIT_SPEED}.
*
* @param maxLiveOffsetErrorMsForUnitSpeed The maximum live offset error for which unit speed is
* used, in milliseconds.
* @return This builder, for convenience.
*/
public Builder setMaxLiveOffsetErrorMsForUnitSpeed(long maxLiveOffsetErrorMsForUnitSpeed) {
Assertions.checkArgument(maxLiveOffsetErrorMsForUnitSpeed > 0);
this.maxLiveOffsetErrorUsForUnitSpeed = C.msToUs(maxLiveOffsetErrorMsForUnitSpeed);
return this;
}
/** /**
* Sets the increment applied to the target live offset each time the player is rebuffering, in * Sets the increment applied to the target live offset each time the player is rebuffering, in
* milliseconds. * milliseconds.
@ -217,6 +235,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
fallbackMaxPlaybackSpeed, fallbackMaxPlaybackSpeed,
minUpdateIntervalMs, minUpdateIntervalMs,
proportionalControlFactorUs, proportionalControlFactorUs,
maxLiveOffsetErrorUsForUnitSpeed,
targetLiveOffsetIncrementOnRebufferUs, targetLiveOffsetIncrementOnRebufferUs,
minPossibleLiveOffsetSmoothingFactor); minPossibleLiveOffsetSmoothingFactor);
} }
@ -226,6 +245,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
private final float fallbackMaxPlaybackSpeed; private final float fallbackMaxPlaybackSpeed;
private final long minUpdateIntervalMs; private final long minUpdateIntervalMs;
private final float proportionalControlFactor; private final float proportionalControlFactor;
private final long maxLiveOffsetErrorUsForUnitSpeed;
private final long targetLiveOffsetRebufferDeltaUs; private final long targetLiveOffsetRebufferDeltaUs;
private final float minPossibleLiveOffsetSmoothingFactor; private final float minPossibleLiveOffsetSmoothingFactor;
@ -249,12 +269,14 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
float fallbackMaxPlaybackSpeed, float fallbackMaxPlaybackSpeed,
long minUpdateIntervalMs, long minUpdateIntervalMs,
float proportionalControlFactor, float proportionalControlFactor,
long maxLiveOffsetErrorUsForUnitSpeed,
long targetLiveOffsetRebufferDeltaUs, long targetLiveOffsetRebufferDeltaUs,
float minPossibleLiveOffsetSmoothingFactor) { float minPossibleLiveOffsetSmoothingFactor) {
this.fallbackMinPlaybackSpeed = fallbackMinPlaybackSpeed; this.fallbackMinPlaybackSpeed = fallbackMinPlaybackSpeed;
this.fallbackMaxPlaybackSpeed = fallbackMaxPlaybackSpeed; this.fallbackMaxPlaybackSpeed = fallbackMaxPlaybackSpeed;
this.minUpdateIntervalMs = minUpdateIntervalMs; this.minUpdateIntervalMs = minUpdateIntervalMs;
this.proportionalControlFactor = proportionalControlFactor; this.proportionalControlFactor = proportionalControlFactor;
this.maxLiveOffsetErrorUsForUnitSpeed = maxLiveOffsetErrorUsForUnitSpeed;
this.targetLiveOffsetRebufferDeltaUs = targetLiveOffsetRebufferDeltaUs; this.targetLiveOffsetRebufferDeltaUs = targetLiveOffsetRebufferDeltaUs;
this.minPossibleLiveOffsetSmoothingFactor = minPossibleLiveOffsetSmoothingFactor; this.minPossibleLiveOffsetSmoothingFactor = minPossibleLiveOffsetSmoothingFactor;
mediaConfigurationTargetLiveOffsetUs = C.TIME_UNSET; mediaConfigurationTargetLiveOffsetUs = C.TIME_UNSET;
@ -322,7 +344,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
adjustTargetLiveOffsetUs(liveOffsetUs); adjustTargetLiveOffsetUs(liveOffsetUs);
long liveOffsetErrorUs = liveOffsetUs - currentTargetLiveOffsetUs; long liveOffsetErrorUs = liveOffsetUs - currentTargetLiveOffsetUs;
if (Math.abs(liveOffsetErrorUs) < MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED) { if (Math.abs(liveOffsetErrorUs) < maxLiveOffsetErrorUsForUnitSpeed) {
adjustedPlaybackSpeed = 1f; adjustedPlaybackSpeed = 1f;
} else { } else {
float calculatedSpeed = 1f + proportionalControlFactor * liveOffsetErrorUs; float calculatedSpeed = 1f + proportionalControlFactor * liveOffsetErrorUs;

View File

@ -512,7 +512,9 @@ public class DefaultLivePlaybackSpeedControlTest {
@Test @Test
public void adjustPlaybackSpeed_liveOffsetWithinAcceptableErrorMargin_returnsUnitSpeed() { public void adjustPlaybackSpeed_liveOffsetWithinAcceptableErrorMargin_returnsUnitSpeed() {
DefaultLivePlaybackSpeedControl defaultLivePlaybackSpeedControl = DefaultLivePlaybackSpeedControl defaultLivePlaybackSpeedControl =
new DefaultLivePlaybackSpeedControl.Builder().build(); new DefaultLivePlaybackSpeedControl.Builder()
.setMaxLiveOffsetErrorMsForUnitSpeed(5)
.build();
defaultLivePlaybackSpeedControl.setLiveConfiguration( defaultLivePlaybackSpeedControl.setLiveConfiguration(
new LiveConfiguration( new LiveConfiguration(
/* targetLiveOffsetMs= */ 2_000, /* targetLiveOffsetMs= */ 2_000,
@ -523,16 +525,10 @@ public class DefaultLivePlaybackSpeedControlTest {
float adjustedSpeedJustAboveLowerErrorMargin = float adjustedSpeedJustAboveLowerErrorMargin =
defaultLivePlaybackSpeedControl.getAdjustedPlaybackSpeed( defaultLivePlaybackSpeedControl.getAdjustedPlaybackSpeed(
/* liveOffsetUs= */ 2_000_000 /* liveOffsetUs= */ 2_000_000 - 5_000 + 1, /* bufferedDurationUs= */ 1_000_000);
- DefaultLivePlaybackSpeedControl.MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED
+ 1,
/* bufferedDurationUs= */ 1_000_000);
float adjustedSpeedJustBelowUpperErrorMargin = float adjustedSpeedJustBelowUpperErrorMargin =
defaultLivePlaybackSpeedControl.getAdjustedPlaybackSpeed( defaultLivePlaybackSpeedControl.getAdjustedPlaybackSpeed(
/* liveOffsetUs= */ 2_000_000 /* liveOffsetUs= */ 2_000_000 + 5_000 - 1, /* bufferedDurationUs= */ 1_000_000);
+ DefaultLivePlaybackSpeedControl.MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED
- 1,
/* bufferedDurationUs= */ 1_000_000);
assertThat(adjustedSpeedJustAboveLowerErrorMargin).isEqualTo(1f); assertThat(adjustedSpeedJustAboveLowerErrorMargin).isEqualTo(1f);
assertThat(adjustedSpeedJustBelowUpperErrorMargin).isEqualTo(1f); assertThat(adjustedSpeedJustBelowUpperErrorMargin).isEqualTo(1f);