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
effbc22a
authored
Nov 04, 2020
by
tonihei
Committed by
Andrew Lewis
Nov 06, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Increase target live offset when rebuffering.
Issue: #4904 PiperOrigin-RevId: 340654178
parent
2416d998
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
68 additions
and
10 deletions
library/core/src/main/java/com/google/android/exoplayer2/DefaultLivePlaybackSpeedControl.java
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.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
View file @
effbc22a
...
@@ -33,6 +33,10 @@ import com.google.android.exoplayer2.util.Util;
...
@@ -33,6 +33,10 @@ import com.google.android.exoplayer2.util.Util;
* fallback values set with {@link Builder#setFallbackMinPlaybackSpeed(float)} and {@link
* fallback values set with {@link Builder#setFallbackMinPlaybackSpeed(float)} and {@link
* Builder#setFallbackMaxPlaybackSpeed(float)} or the {@link #DEFAULT_FALLBACK_MIN_PLAYBACK_SPEED
* Builder#setFallbackMaxPlaybackSpeed(float)} or the {@link #DEFAULT_FALLBACK_MIN_PLAYBACK_SPEED
* minimum} and {@link #DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED maximum} fallback default values.
* minimum} and {@link #DEFAULT_FALLBACK_MAX_PLAYBACK_SPEED maximum} fallback default values.
*
* <p>When the player rebuffers, the target live offset {@link
* Builder#setTargetLiveOffsetIncrementOnRebufferMs(long) is increased} to adjust to the reduced
* network capabilities.
*/
*/
public
final
class
DefaultLivePlaybackSpeedControl
implements
LivePlaybackSpeedControl
{
public
final
class
DefaultLivePlaybackSpeedControl
implements
LivePlaybackSpeedControl
{
...
@@ -61,6 +65,12 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -61,6 +65,12 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
public
static
final
float
DEFAULT_PROPORTIONAL_CONTROL_FACTOR
=
0.05f
;
public
static
final
float
DEFAULT_PROPORTIONAL_CONTROL_FACTOR
=
0.05f
;
/**
/**
* The default increment applied to the target live offset each time the player is rebuffering, in
* milliseconds
*/
public
static
final
long
DEFAULT_TARGET_LIVE_OFFSET_INCREMENT_ON_REBUFFER_MS
=
500
;
/**
* The maximum difference between the current live offset and the target live offset for which
* The maximum difference between the current live offset and the target live offset for which
* unit speed (1.0f) is used.
* unit speed (1.0f) is used.
*/
*/
...
@@ -73,6 +83,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -73,6 +83,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
targetLiveOffsetIncrementOnRebufferUs
;
/** Creates a builder. */
/** Creates a builder. */
public
Builder
()
{
public
Builder
()
{
...
@@ -80,6 +91,8 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -80,6 +91,8 @@ 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
;
targetLiveOffsetIncrementOnRebufferUs
=
C
.
msToUs
(
DEFAULT_TARGET_LIVE_OFFSET_INCREMENT_ON_REBUFFER_MS
);
}
}
/**
/**
...
@@ -145,13 +158,29 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -145,13 +158,29 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
return
this
;
return
this
;
}
}
/**
* Sets the increment applied to the target live offset each time the player is rebuffering, in
* milliseconds.
*
* @param targetLiveOffsetIncrementOnRebufferMs The increment applied to the target live offset
* when the player is rebuffering, in milliseconds
* @return This builder, for convenience.
*/
public
Builder
setTargetLiveOffsetIncrementOnRebufferMs
(
long
targetLiveOffsetIncrementOnRebufferMs
)
{
Assertions
.
checkArgument
(
targetLiveOffsetIncrementOnRebufferMs
>=
0
);
this
.
targetLiveOffsetIncrementOnRebufferUs
=
C
.
msToUs
(
targetLiveOffsetIncrementOnRebufferMs
);
return
this
;
}
/** Builds an instance. */
/** Builds an instance. */
public
DefaultLivePlaybackSpeedControl
build
()
{
public
DefaultLivePlaybackSpeedControl
build
()
{
return
new
DefaultLivePlaybackSpeedControl
(
return
new
DefaultLivePlaybackSpeedControl
(
fallbackMinPlaybackSpeed
,
fallbackMinPlaybackSpeed
,
fallbackMaxPlaybackSpeed
,
fallbackMaxPlaybackSpeed
,
minUpdateIntervalMs
,
minUpdateIntervalMs
,
proportionalControlFactorUs
);
proportionalControlFactorUs
,
targetLiveOffsetIncrementOnRebufferUs
);
}
}
}
}
...
@@ -159,9 +188,11 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -159,9 +188,11 @@ 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
targetLiveOffsetRebufferDeltaUs
;
private
long
mediaConfigurationTargetLiveOffsetUs
;
private
long
mediaConfigurationTargetLiveOffsetUs
;
private
long
targetLiveOffsetOverrideUs
;
private
long
targetLiveOffsetOverrideUs
;
private
long
idealTargetLiveOffsetUs
;
private
long
minTargetLiveOffsetUs
;
private
long
minTargetLiveOffsetUs
;
private
long
maxTargetLiveOffsetUs
;
private
long
maxTargetLiveOffsetUs
;
private
long
currentTargetLiveOffsetUs
;
private
long
currentTargetLiveOffsetUs
;
...
@@ -175,11 +206,13 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -175,11 +206,13 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
float
fallbackMinPlaybackSpeed
,
float
fallbackMinPlaybackSpeed
,
float
fallbackMaxPlaybackSpeed
,
float
fallbackMaxPlaybackSpeed
,
long
minUpdateIntervalMs
,
long
minUpdateIntervalMs
,
float
proportionalControlFactor
)
{
float
proportionalControlFactor
,
long
targetLiveOffsetRebufferDeltaUs
)
{
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
.
targetLiveOffsetRebufferDeltaUs
=
targetLiveOffsetRebufferDeltaUs
;
mediaConfigurationTargetLiveOffsetUs
=
C
.
TIME_UNSET
;
mediaConfigurationTargetLiveOffsetUs
=
C
.
TIME_UNSET
;
targetLiveOffsetOverrideUs
=
C
.
TIME_UNSET
;
targetLiveOffsetOverrideUs
=
C
.
TIME_UNSET
;
minTargetLiveOffsetUs
=
C
.
TIME_UNSET
;
minTargetLiveOffsetUs
=
C
.
TIME_UNSET
;
...
@@ -188,6 +221,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -188,6 +221,7 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
maxPlaybackSpeed
=
fallbackMaxPlaybackSpeed
;
maxPlaybackSpeed
=
fallbackMaxPlaybackSpeed
;
adjustedPlaybackSpeed
=
1.0f
;
adjustedPlaybackSpeed
=
1.0f
;
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
idealTargetLiveOffsetUs
=
C
.
TIME_UNSET
;
currentTargetLiveOffsetUs
=
C
.
TIME_UNSET
;
currentTargetLiveOffsetUs
=
C
.
TIME_UNSET
;
}
}
...
@@ -214,6 +248,19 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -214,6 +248,19 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
}
}
@Override
@Override
public
void
notifyRebuffer
()
{
if
(
currentTargetLiveOffsetUs
==
C
.
TIME_UNSET
)
{
return
;
}
currentTargetLiveOffsetUs
+=
targetLiveOffsetRebufferDeltaUs
;
if
(
maxTargetLiveOffsetUs
!=
C
.
TIME_UNSET
&&
currentTargetLiveOffsetUs
>
maxTargetLiveOffsetUs
)
{
currentTargetLiveOffsetUs
=
maxTargetLiveOffsetUs
;
}
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
}
@Override
public
float
getAdjustedPlaybackSpeed
(
long
liveOffsetUs
)
{
public
float
getAdjustedPlaybackSpeed
(
long
liveOffsetUs
)
{
if
(
mediaConfigurationTargetLiveOffsetUs
==
C
.
TIME_UNSET
)
{
if
(
mediaConfigurationTargetLiveOffsetUs
==
C
.
TIME_UNSET
)
{
return
1
f
;
return
1
f
;
...
@@ -254,9 +301,10 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
...
@@ -254,9 +301,10 @@ public final class DefaultLivePlaybackSpeedControl implements LivePlaybackSpeedC
idealOffsetUs
=
maxTargetLiveOffsetUs
;
idealOffsetUs
=
maxTargetLiveOffsetUs
;
}
}
}
}
if
(
current
TargetLiveOffsetUs
==
idealOffsetUs
)
{
if
(
ideal
TargetLiveOffsetUs
==
idealOffsetUs
)
{
return
;
return
;
}
}
idealTargetLiveOffsetUs
=
idealOffsetUs
;
currentTargetLiveOffsetUs
=
idealOffsetUs
;
currentTargetLiveOffsetUs
=
idealOffsetUs
;
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
lastPlaybackSpeedUpdateMs
=
C
.
TIME_UNSET
;
}
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java
View file @
effbc22a
...
@@ -189,7 +189,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -189,7 +189,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private
boolean
released
;
private
boolean
released
;
private
boolean
pauseAtEndOfWindow
;
private
boolean
pauseAtEndOfWindow
;
private
boolean
pendingPauseAtEndOfPeriod
;
private
boolean
pendingPauseAtEndOfPeriod
;
private
boolean
r
ebuffering
;
private
boolean
isR
ebuffering
;
private
boolean
shouldContinueLoading
;
private
boolean
shouldContinueLoading
;
@Player
.
RepeatMode
private
int
repeatMode
;
@Player
.
RepeatMode
private
int
repeatMode
;
private
boolean
shuffleModeEnabled
;
private
boolean
shuffleModeEnabled
;
...
@@ -733,7 +733,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -733,7 +733,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
playbackInfoUpdate
.
incrementPendingOperationAcks
(
operationAck
?
1
:
0
);
playbackInfoUpdate
.
incrementPendingOperationAcks
(
operationAck
?
1
:
0
);
playbackInfoUpdate
.
setPlayWhenReadyChangeReason
(
reason
);
playbackInfoUpdate
.
setPlayWhenReadyChangeReason
(
reason
);
playbackInfo
=
playbackInfo
.
copyWithPlayWhenReady
(
playWhenReady
,
playbackSuppressionReason
);
playbackInfo
=
playbackInfo
.
copyWithPlayWhenReady
(
playWhenReady
,
playbackSuppressionReason
);
r
ebuffering
=
false
;
isR
ebuffering
=
false
;
if
(!
shouldPlayWhenReady
())
{
if
(!
shouldPlayWhenReady
())
{
stopRenderers
();
stopRenderers
();
updatePlaybackPositions
();
updatePlaybackPositions
();
...
@@ -811,7 +811,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -811,7 +811,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
private
void
startRenderers
()
throws
ExoPlaybackException
{
private
void
startRenderers
()
throws
ExoPlaybackException
{
r
ebuffering
=
false
;
isR
ebuffering
=
false
;
mediaClock
.
start
();
mediaClock
.
start
();
for
(
Renderer
renderer
:
renderers
)
{
for
(
Renderer
renderer
:
renderers
)
{
if
(
isRendererEnabled
(
renderer
))
{
if
(
isRendererEnabled
(
renderer
))
{
...
@@ -868,6 +868,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -868,6 +868,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Adjust live playback speed to new position.
// Adjust live playback speed to new position.
if
(
playbackInfo
.
playWhenReady
if
(
playbackInfo
.
playWhenReady
&&
playbackInfo
.
playbackState
==
Player
.
STATE_READY
&&
isCurrentPeriodInMovingLiveWindow
()
&&
isCurrentPeriodInMovingLiveWindow
()
&&
playbackInfo
.
playbackParameters
.
speed
==
1
f
)
{
&&
playbackInfo
.
playbackParameters
.
speed
==
1
f
)
{
float
adjustedSpeed
=
float
adjustedSpeed
=
...
@@ -960,8 +961,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -960,8 +961,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
}
else
if
(
playbackInfo
.
playbackState
==
Player
.
STATE_READY
}
else
if
(
playbackInfo
.
playbackState
==
Player
.
STATE_READY
&&
!(
enabledRendererCount
==
0
?
isTimelineReady
()
:
renderersAllowPlayback
))
{
&&
!(
enabledRendererCount
==
0
?
isTimelineReady
()
:
renderersAllowPlayback
))
{
r
ebuffering
=
shouldPlayWhenReady
();
isR
ebuffering
=
shouldPlayWhenReady
();
setState
(
Player
.
STATE_BUFFERING
);
setState
(
Player
.
STATE_BUFFERING
);
livePlaybackSpeedControl
.
notifyRebuffer
();
stopRenderers
();
stopRenderers
();
}
}
...
@@ -1168,7 +1170,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -1168,7 +1170,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
boolean
forceBufferingState
)
boolean
forceBufferingState
)
throws
ExoPlaybackException
{
throws
ExoPlaybackException
{
stopRenderers
();
stopRenderers
();
r
ebuffering
=
false
;
isR
ebuffering
=
false
;
if
(
forceBufferingState
||
playbackInfo
.
playbackState
==
Player
.
STATE_READY
)
{
if
(
forceBufferingState
||
playbackInfo
.
playbackState
==
Player
.
STATE_READY
)
{
setState
(
Player
.
STATE_BUFFERING
);
setState
(
Player
.
STATE_BUFFERING
);
}
}
...
@@ -1311,7 +1313,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -1311,7 +1313,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
boolean
releaseMediaSourceList
,
boolean
releaseMediaSourceList
,
boolean
resetError
)
{
boolean
resetError
)
{
handler
.
removeMessages
(
MSG_DO_SOME_WORK
);
handler
.
removeMessages
(
MSG_DO_SOME_WORK
);
r
ebuffering
=
false
;
isR
ebuffering
=
false
;
mediaClock
.
stop
();
mediaClock
.
stop
();
rendererPositionUs
=
0
;
rendererPositionUs
=
0
;
for
(
Renderer
renderer
:
renderers
)
{
for
(
Renderer
renderer
:
renderers
)
{
...
@@ -1701,7 +1703,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
...
@@ -1701,7 +1703,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
||
loadControl
.
shouldStartPlayback
(
||
loadControl
.
shouldStartPlayback
(
getTotalBufferedDurationUs
(),
getTotalBufferedDurationUs
(),
mediaClock
.
getPlaybackParameters
().
speed
,
mediaClock
.
getPlaybackParameters
().
speed
,
r
ebuffering
,
isR
ebuffering
,
targetLiveOffsetUs
);
targetLiveOffsetUs
);
}
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/LivePlaybackSpeedControl.java
View file @
effbc22a
...
@@ -41,6 +41,14 @@ public interface LivePlaybackSpeedControl {
...
@@ -41,6 +41,14 @@ public interface LivePlaybackSpeedControl {
void
setTargetLiveOffsetOverrideUs
(
long
liveOffsetUs
);
void
setTargetLiveOffsetOverrideUs
(
long
liveOffsetUs
);
/**
/**
* Notifies the live playback speed control that a rebuffer occurred.
*
* <p>A rebuffer is defined to be caused by buffer depletion rather than a user action. Hence this
* method is not called during initial or when buffering as a result of a seek operation.
*/
void
notifyRebuffer
();
/**
* Returns the adjusted playback speed in order get closer towards the {@link
* Returns the adjusted playback speed in order get closer towards the {@link
* #getTargetLiveOffsetUs() target live offset}.
* #getTargetLiveOffsetUs() target live offset}.
*
*
...
...
library/core/src/test/java/com/google/android/exoplayer2/DefaultLivePlaybackSpeedControlTest.java
View file @
effbc22a
This diff is collapsed.
Click to expand it.
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