Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
867d27fa
authored
Oct 13, 2020
by
christosts
Committed by
kim-vde
Oct 13, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add LivePlaybackSpeedControl interface and default implementation.
Issue: #4904 PiperOrigin-RevId: 336839908
parent
13f1f3b3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
596 additions
and
0 deletions
library/core/src/main/java/com/google/android/exoplayer2/DefaultLivePlaybackSpeedControl.java
library/core/src/main/java/com/google/android/exoplayer2/LivePlaybackSpeedControl.java
library/core/src/test/java/com/google/android/exoplayer2/DefaultLivePlaybackSpeedControlTest.java
library/core/src/main/java/com/google/android/exoplayer2/DefaultLivePlaybackSpeedControl.java
0 → 100644
View file @
867d27fa
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
;
import
android.os.SystemClock
;
import
com.google.android.exoplayer2.MediaItem.LiveConfiguration
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Util
;
/**
* A {@link LivePlaybackSpeedControl} that adjusts the playback speed using a proportional
* controller.
*
* <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
* currentLiveOffsetSec} is marginally close to {@code targetLiveOffsetSec}, i.e. {@code
* |currentLiveOffsetSec - targetLiveOffsetSec| <= MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED}.
*
* <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
* Builder#setFallbackMaxPlaybackSpeed(float)} or the {@link #DEFAULT_FALLBACK_MIN_PLAYBACK_SPEED
* minimum} and {@link #DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED maximum} fallback default values.
*/
public
final
class
DefaultLivePlaybackSpeedControl
implements
LivePlaybackSpeedControl
{
/**
* The default minimum playback speed that should be used if no minimum playback speed is defined
* by the media.
*/
public
static
final
float
DEFAULT_FALLBACK_MIN_PLAYBACK_SPEED
=
0.97f
;
/**
* The default maximum playback speed that should be used if no maximum playback speed is defined
* by the media.
*/
public
static
final
float
DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED
=
1.03f
;
/**
* The default {@link Builder#setMinUpdateIntervalMs(long) minimum interval} between playback
* speed changes, in milliseconds.
*/
public
static
final
long
DEFAULT_MIN_UPDATE_INTERVAL_MS
=
500
;
/**
* The default {@link Builder#setProportionalControlFactor(float) proportional control factor}
* used to adjust the playback speed.
*/
public
static
final
float
DEFAULT_PROPORTIONAL_CONTROL_FACTOR
=
0.05f
;
/**
* The maximum difference between the current live offset and the target live offset for which
* unit speed (1.0f) is used.
*/
public
static
final
long
MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED
=
5_000
;
/** Builder for a {@link DefaultLivePlaybackSpeedControl}. */
public
static
final
class
Builder
{
private
float
fallbackMinPlaybackSpeed
;
private
float
fallbackMaxPlaybackSpeed
;
private
long
minUpdateIntervalMs
;
private
float
proportionalControlFactorUs
;
/** Creates a builder. */
public
Builder
()
{
fallbackMinPlaybackSpeed
=
DEFAULT_FALLBACK_MIN_PLAYBACK_SPEED
;
fallbackMaxPlaybackSpeed
=
DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED
;
minUpdateIntervalMs
=
DEFAULT_MIN_UPDATE_INTERVAL_MS
;
proportionalControlFactorUs
=
DEFAULT_PROPORTIONAL_CONTROL_FACTOR
/
C
.
MICROS_PER_SECOND
;
}
/**
* Sets the minimum playback speed that should be used if no minimum playback speed is defined
* by the media.
*
* <p>The default is {@link #DEFAULT_FALLBACK_MIN_PLAYBACK_SPEED}.
*
* @param fallbackMinPlaybackSpeed The fallback minimum playback speed.
* @return This builder, for convenience.
*/
public
Builder
setFallbackMinPlaybackSpeed
(
float
fallbackMinPlaybackSpeed
)
{
Assertions
.
checkArgument
(
0
<
fallbackMinPlaybackSpeed
&&
fallbackMinPlaybackSpeed
<=
1
f
);
this
.
fallbackMinPlaybackSpeed
=
fallbackMinPlaybackSpeed
;
return
this
;
}
/**
* Sets the maximum playback speed that should be used if no maximum playback speed is defined
* by the media.
*
* <p>The default is {@link #DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED}.
*
* @param fallbackMaxPlaybackSpeed The fallback maximum playback speed.
* @return This builder, for convenience.
*/
public
Builder
setFallbackMaxPlaybackSpeed
(
float
fallbackMaxPlaybackSpeed
)
{
Assertions
.
checkArgument
(
fallbackMaxPlaybackSpeed
>=
1
f
);
this
.
fallbackMaxPlaybackSpeed
=
fallbackMaxPlaybackSpeed
;
return
this
;
}
/**
* Sets the minimum interval between playback speed changes, in milliseconds.
*
* <p>The default is {@link #DEFAULT_MIN_UPDATE_INTERVAL_MS}.
*
* @param minUpdateIntervalMs The minimum interval between playback speed changes, in
* milliseconds.
* @return This builder, for convenience.
*/
public
Builder
setMinUpdateIntervalMs
(
long
minUpdateIntervalMs
)
{
Assertions
.
checkArgument
(
minUpdateIntervalMs
>=
0
);
this
.
minUpdateIntervalMs
=
minUpdateIntervalMs
;
return
this
;
}
/**
* Sets the proportional control factor used to adjust the playback speed.
*
* <p>The adjusted playback speed is calculated as {@code 1.0 + proportionalControlFactor x
* (currentLiveOffsetSec - targetLiveOffsetSec)}.
*
* <p>The default is {@link #DEFAULT_PROPORTIONAL_CONTROL_FACTOR}.
*
* @param proportionalControlFactor The proportional control factor used to adjust the playback
* speed.
* @return This builder, for convenience.
*/
public
Builder
setProportionalControlFactor
(
float
proportionalControlFactor
)
{
Assertions
.
checkArgument
(
proportionalControlFactor
>
0
);
this
.
proportionalControlFactorUs
=
proportionalControlFactor
/
C
.
MICROS_PER_SECOND
;
return
this
;
}
/** Builds an instance. */
public
DefaultLivePlaybackSpeedControl
build
()
{
return
new
DefaultLivePlaybackSpeedControl
(
fallbackMinPlaybackSpeed
,
fallbackMaxPlaybackSpeed
,
minUpdateIntervalMs
,
proportionalControlFactorUs
);
}
}
private
final
float
fallbackMinPlaybackSpeed
;
private
final
float
fallbackMaxPlaybackSpeed
;
private
final
long
minUpdateIntervalMs
;
private
final
float
proportionalControlFactor
;
private
LiveConfiguration
mediaConfiguration
;
private
long
targetLiveOffsetOverrideUs
;
private
float
adjustedPlaybackSpeed
;
private
long
lastPlaybackSpeedUpdateMs
;
private
DefaultLivePlaybackSpeedControl
(
float
fallbackMinPlaybackSpeed
,
float
fallbackMaxPlaybackSpeed
,
long
minUpdateIntervalMs
,
float
proportionalControlFactor
)
{
this
.
fallbackMinPlaybackSpeed
=
fallbackMinPlaybackSpeed
;
this
.
fallbackMaxPlaybackSpeed
=
fallbackMaxPlaybackSpeed
;
this
.
minUpdateIntervalMs
=
minUpdateIntervalMs
;
this
.
proportionalControlFactor
=
proportionalControlFactor
;
mediaConfiguration
=
LiveConfiguration
.
UNSET
;
targetLiveOffsetOverrideUs
=
C
.
TIME_UNSET
;
adjustedPlaybackSpeed
=
1.0f
;
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
}
@Override
public
void
updateLiveConfiguration
(
LiveConfiguration
liveConfiguration
)
{
this
.
mediaConfiguration
=
liveConfiguration
;
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
}
@Override
public
void
overrideTargetLiveOffsetUs
(
long
liveOffsetUs
)
{
this
.
targetLiveOffsetOverrideUs
=
liveOffsetUs
;
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
}
@Override
public
float
adjustPlaybackSpeed
(
long
liveOffsetUs
)
{
long
targetLiveOffsetUs
=
getTargetLiveOffsetUs
();
if
(
targetLiveOffsetUs
==
C
.
TIME_UNSET
)
{
return
1
f
;
}
if
(
lastPlaybackSpeedUpdateMs
!=
C
.
TIME_UNSET
&&
SystemClock
.
elapsedRealtime
()
-
lastPlaybackSpeedUpdateMs
<
minUpdateIntervalMs
)
{
return
adjustedPlaybackSpeed
;
}
lastPlaybackSpeedUpdateMs
=
SystemClock
.
elapsedRealtime
();
long
liveOffsetErrorUs
=
liveOffsetUs
-
targetLiveOffsetUs
;
if
(
Math
.
abs
(
liveOffsetErrorUs
)
<
MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED
)
{
adjustedPlaybackSpeed
=
1
f
;
}
else
{
float
calculatedSpeed
=
1
f
+
proportionalControlFactor
*
liveOffsetErrorUs
;
adjustedPlaybackSpeed
=
Util
.
constrainValue
(
calculatedSpeed
,
getMinPlaybackSpeed
(),
getMaxPlaybackSpeed
());
}
return
adjustedPlaybackSpeed
;
}
@Override
public
long
getTargetLiveOffsetUs
()
{
return
targetLiveOffsetOverrideUs
!=
C
.
TIME_UNSET
&&
mediaConfiguration
.
targetLiveOffsetMs
!=
C
.
TIME_UNSET
?
targetLiveOffsetOverrideUs
:
C
.
msToUs
(
mediaConfiguration
.
targetLiveOffsetMs
);
}
private
float
getMinPlaybackSpeed
()
{
return
mediaConfiguration
.
minPlaybackSpeed
!=
C
.
RATE_UNSET
?
mediaConfiguration
.
minPlaybackSpeed
:
fallbackMinPlaybackSpeed
;
}
private
float
getMaxPlaybackSpeed
()
{
return
mediaConfiguration
.
maxPlaybackSpeed
!=
C
.
RATE_UNSET
?
mediaConfiguration
.
maxPlaybackSpeed
:
fallbackMaxPlaybackSpeed
;
}
}
library/core/src/main/java/com/google/android/exoplayer2/LivePlaybackSpeedControl.java
0 → 100644
View file @
867d27fa
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
;
import
com.google.android.exoplayer2.MediaItem.LiveConfiguration
;
/**
* Controls the playback speed while playing live content in order to maintain a steady target live
* offset.
*/
public
interface
LivePlaybackSpeedControl
{
/**
* Updates the live configuration defined by the media.
*
* @param liveConfiguration The {@link LiveConfiguration} as defined by the media.
*/
void
updateLiveConfiguration
(
LiveConfiguration
liveConfiguration
);
/**
* Overrides the {@link #updateLiveConfiguration configured} target live offset in microseconds,
* or {@code C.TIME_UNSET} to delete a previous override.
*
* <p>If no target live offset is configured by {@link #updateLiveConfiguration}, this override
* has no effect.
*/
void
overrideTargetLiveOffsetUs
(
long
liveOffsetUs
);
/**
* Returns the adjusted playback speed in order get closer towards the {@link
* #getTargetLiveOffsetUs() target live offset}.
*
* @param liveOffsetUs The current live offset, in microseconds.
* @return The adjusted playback speed.
*/
float
adjustPlaybackSpeed
(
long
liveOffsetUs
);
/**
* Returns the current target live offset, in microseconds, or {@link C#TIME_UNSET} if no target
* live offset is defined for the current media.
*/
long
getTargetLiveOffsetUs
();
}
library/core/src/test/java/com/google/android/exoplayer2/DefaultLivePlaybackSpeedControlTest.java
0 → 100644
View file @
867d27fa
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.MediaItem.LiveConfiguration
;
import
java.time.Duration
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.robolectric.shadows.ShadowSystemClock
;
/** Unit test for {@link DefaultLivePlaybackSpeedControl}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
DefaultLivePlaybackSpeedControlTest
{
@Test
public
void
getTargetLiveOffsetUs_returnsUnset
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
build
();
assertThat
(
defaultLivePlaybackSpeedControl
.
getTargetLiveOffsetUs
()).
isEqualTo
(
C
.
TIME_UNSET
);
}
@Test
public
void
getTargetLiveOffsetUs_afterUpdateLiveConfiguration_usesMediaLiveOffset
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
42
,
/* minPlaybackSpeed= */
1
f
,
/* maxPlaybackSpeed= */
1
f
));
assertThat
(
defaultLivePlaybackSpeedControl
.
getTargetLiveOffsetUs
()).
isEqualTo
(
42_000
);
}
@Test
public
void
getTargetLiveOffsetUs_withOverrideTargetLiveOffsetUs_usesOverride
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
build
();
defaultLivePlaybackSpeedControl
.
overrideTargetLiveOffsetUs
(
123_456_789
);
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
42
,
/* minPlaybackSpeed= */
1
f
,
/* maxPlaybackSpeed= */
1
f
));
long
targetLiveOffsetUs
=
defaultLivePlaybackSpeedControl
.
getTargetLiveOffsetUs
();
assertThat
(
targetLiveOffsetUs
).
isEqualTo
(
123_456_789
);
}
@Test
public
void
getTargetLiveOffsetUs_afterOverrideTargetLiveOffset_withoutMediaConfiguration_returnsUnset
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
build
();
defaultLivePlaybackSpeedControl
.
overrideTargetLiveOffsetUs
(
123_456_789
);
long
targetLiveOffsetUs
=
defaultLivePlaybackSpeedControl
.
getTargetLiveOffsetUs
();
assertThat
(
targetLiveOffsetUs
).
isEqualTo
(
C
.
TIME_UNSET
);
}
@Test
public
void
getTargetLiveOffsetUs_afterOverrideTargetLiveOffsetUsWithTimeUnset_usesMediaLiveOffset
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
build
();
defaultLivePlaybackSpeedControl
.
overrideTargetLiveOffsetUs
(
123_456_789
);
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
42
,
/* minPlaybackSpeed= */
1
f
,
/* maxPlaybackSpeed= */
1
f
));
defaultLivePlaybackSpeedControl
.
overrideTargetLiveOffsetUs
(
C
.
TIME_UNSET
);
long
targetLiveOffsetUs
=
defaultLivePlaybackSpeedControl
.
getTargetLiveOffsetUs
();
assertThat
(
targetLiveOffsetUs
).
isEqualTo
(
42_000
);
}
@Test
public
void
adjustPlaybackSpeed_liveOffsetMatchesTargetOffset_returnsUnitSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_000_000
);
assertThat
(
adjustedSpeed
).
isEqualTo
(
1
f
);
}
@Test
public
void
adjustPlaybackSpeed_liveOffsetWithinAcceptableErrorMargin_returnsUnitSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeedJustAboveLowerErrorMargin
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_000_000
-
DefaultLivePlaybackSpeedControl
.
MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED
+
1
);
float
adjustedSpeedJustBelowUpperErrorMargin
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_000_000
+
DefaultLivePlaybackSpeedControl
.
MAXIMUM_LIVE_OFFSET_ERROR_US_FOR_UNIT_SPEED
-
1
);
assertThat
(
adjustedSpeedJustAboveLowerErrorMargin
).
isEqualTo
(
1
f
);
assertThat
(
adjustedSpeedJustBelowUpperErrorMargin
).
isEqualTo
(
1
f
);
}
@Test
public
void
adjustPlaybackSpeed_withLiveOffsetGreaterThanTargetOffset_returnsAdjustedSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setProportionalControlFactor
(
0.01f
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_500_000
);
float
expectedSpeedAccordingToDocumentation
=
1
f
+
0.01f
*
(
2.5f
-
2
f
);
assertThat
(
adjustedSpeed
).
isEqualTo
(
expectedSpeedAccordingToDocumentation
);
assertThat
(
adjustedSpeed
).
isGreaterThan
(
1
f
);
}
@Test
public
void
adjustPlaybackSpeed_withLiveOffsetLowerThanTargetOffset_returnsAdjustedSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setProportionalControlFactor
(
0.01f
).
build
();
defaultLivePlaybackSpeedControl
.
overrideTargetLiveOffsetUs
(
2_000_000
);
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
1_500_000
);
float
expectedSpeedAccordingToDocumentation
=
1
f
+
0.01f
*
(
1.5f
-
2
f
);
assertThat
(
adjustedSpeed
).
isEqualTo
(
expectedSpeedAccordingToDocumentation
);
assertThat
(
adjustedSpeed
).
isLessThan
(
1
f
);
}
@Test
public
void
adjustPlaybackSpeed_withLiveOffsetGreaterThanTargetOffset_clampedToFallbackMaximumSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setFallbackMaxPlaybackSpeed
(
1.5f
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
999_999_999_999L
);
assertThat
(
adjustedSpeed
).
isEqualTo
(
1.5f
);
}
@Test
public
void
adjustPlaybackSpeed_withLiveOffsetLowerThanTargetOffset_clampedToFallbackMinimumSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setFallbackMinPlaybackSpeed
(
0.5f
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
-
999_999_999_999L
);
assertThat
(
adjustedSpeed
).
isEqualTo
(
0.5f
);
}
@Test
public
void
adjustPlaybackSpeed_andMediaProvidedMaxSpeedWithLiveOffsetGreaterThanTargetOffset_clampedToMediaMaxSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setFallbackMaxPlaybackSpeed
(
1.5f
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
2
f
));
float
adjustedSpeed
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
999_999_999_999L
);
assertThat
(
adjustedSpeed
).
isEqualTo
(
2
f
);
}
@Test
public
void
adjustPlaybackSpeed_andMediaProvidedMinSpeedWithLiveOffsetLowerThanTargetOffset_clampedToMediaMinSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setFallbackMinPlaybackSpeed
(
0.5f
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
0.2f
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
-
999_999_999_999L
);
assertThat
(
adjustedSpeed
).
isEqualTo
(
0.2f
);
}
@Test
public
void
adjustPlaybackSpeed_repeatedCallWithinMinUpdateInterval_returnsSameAdjustedSpeed
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setMinUpdateIntervalMs
(
123
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed1
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
1_500_000
);
ShadowSystemClock
.
advanceBy
(
Duration
.
ofMillis
(
122
));
float
adjustedSpeed2
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_500_000
);
ShadowSystemClock
.
advanceBy
(
Duration
.
ofMillis
(
2
));
float
adjustedSpeed3
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_500_000
);
assertThat
(
adjustedSpeed1
).
isEqualTo
(
adjustedSpeed2
);
assertThat
(
adjustedSpeed3
).
isNotEqualTo
(
adjustedSpeed2
);
}
@Test
public
void
adjustPlaybackSpeed_repeatedCallAfterUpdateLiveConfiguration_updatesSpeedAgain
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setMinUpdateIntervalMs
(
123
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed1
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
1_500_000
);
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed2
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_500_000
);
assertThat
(
adjustedSpeed1
).
isNotEqualTo
(
adjustedSpeed2
);
}
@Test
public
void
adjustPlaybackSpeed_repeatedCallAfterNewTargetLiveOffset_updatesSpeedAgain
()
{
DefaultLivePlaybackSpeedControl
defaultLivePlaybackSpeedControl
=
new
DefaultLivePlaybackSpeedControl
.
Builder
().
setMinUpdateIntervalMs
(
123
).
build
();
defaultLivePlaybackSpeedControl
.
updateLiveConfiguration
(
new
LiveConfiguration
(
/* targetLiveOffsetMs= */
2_000
,
/* minPlaybackSpeed= */
C
.
RATE_UNSET
,
/* maxPlaybackSpeed= */
C
.
RATE_UNSET
));
float
adjustedSpeed1
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
1_500_000
);
defaultLivePlaybackSpeedControl
.
overrideTargetLiveOffsetUs
(
2_000_001
);
float
adjustedSpeed2
=
defaultLivePlaybackSpeedControl
.
adjustPlaybackSpeed
(
/* liveOffsetUs= */
2_500_000
);
assertThat
(
adjustedSpeed1
).
isNotEqualTo
(
adjustedSpeed2
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment