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
6a3e2a64
authored
Mar 28, 2023
by
Googler
Committed by
Tianyi Feng
Mar 30, 2023
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Allow associating LoadControl methods with the relevant MediaPeriod.
PiperOrigin-RevId: 520037412
parent
e44e3377
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
123 additions
and
13 deletions
library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java
library/core/src/main/java/com/google/android/exoplayer2/LoadControl.java
library/core/src/test/java/com/google/android/exoplayer2/DefaultLoadControlTest.java
library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java
View file @
6a3e2a64
...
...
@@ -20,6 +20,7 @@ import static java.lang.Math.max;
import
static
java
.
lang
.
Math
.
min
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.source.MediaPeriodId
;
import
com.google.android.exoplayer2.source.TrackGroupArray
;
import
com.google.android.exoplayer2.trackselection.ExoTrackSelection
;
import
com.google.android.exoplayer2.upstream.Allocator
;
...
...
@@ -327,7 +328,11 @@ public class DefaultLoadControl implements LoadControl {
@Override
public
void
onTracksSelected
(
Renderer
[]
renderers
,
TrackGroupArray
trackGroups
,
ExoTrackSelection
[]
trackSelections
)
{
Timeline
timeline
,
MediaPeriodId
mediaPeriodId
,
Renderer
[]
renderers
,
TrackGroupArray
trackGroups
,
ExoTrackSelection
[]
trackSelections
)
{
targetBufferBytes
=
targetBufferBytesOverwrite
==
C
.
LENGTH_UNSET
?
calculateTargetBufferBytes
(
renderers
,
trackSelections
)
...
...
@@ -389,7 +394,12 @@ public class DefaultLoadControl implements LoadControl {
@Override
public
boolean
shouldStartPlayback
(
long
bufferedDurationUs
,
float
playbackSpeed
,
boolean
rebuffering
,
long
targetLiveOffsetUs
)
{
Timeline
timeline
,
MediaPeriodId
mediaPeriodId
,
long
bufferedDurationUs
,
float
playbackSpeed
,
boolean
rebuffering
,
long
targetLiveOffsetUs
)
{
bufferedDurationUs
=
Util
.
getPlayoutDurationForMediaDuration
(
bufferedDurationUs
,
playbackSpeed
);
long
minBufferDurationUs
=
rebuffering
?
bufferForPlaybackAfterRebufferUs
:
bufferForPlaybackUs
;
if
(
targetLiveOffsetUs
!=
C
.
TIME_UNSET
)
{
...
...
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java
View file @
6a3e2a64
...
...
@@ -1815,8 +1815,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
return
true
;
}
// Renderers are ready and we're loading. Ask the LoadControl whether to transition.
MediaPeriodHolder
playingPeriodHolder
=
queue
.
getPlayingPeriod
();
long
targetLiveOffsetUs
=
shouldUseLivePlaybackSpeedControl
(
playbackInfo
.
timeline
,
queue
.
getPlayingPeriod
()
.
info
.
id
)
shouldUseLivePlaybackSpeedControl
(
playbackInfo
.
timeline
,
playingPeriodHolder
.
info
.
id
)
?
livePlaybackSpeedControl
.
getTargetLiveOffsetUs
()
:
C
.
TIME_UNSET
;
MediaPeriodHolder
loadingHolder
=
queue
.
getLoadingPeriod
();
...
...
@@ -1828,6 +1829,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
return
isBufferedToEnd
||
isAdPendingPreparation
||
loadControl
.
shouldStartPlayback
(
playbackInfo
.
timeline
,
playingPeriodHolder
.
info
.
id
,
getTotalBufferedDurationUs
(),
mediaClock
.
getPlaybackParameters
().
speed
,
isRebuffering
,
...
...
@@ -2283,7 +2286,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
loadingPeriodHolder
.
handlePrepared
(
mediaClock
.
getPlaybackParameters
().
speed
,
playbackInfo
.
timeline
);
updateLoadControlTrackSelection
(
loadingPeriodHolder
.
getTrackGroups
(),
loadingPeriodHolder
.
getTrackSelectorResult
());
loadingPeriodHolder
.
info
.
id
,
loadingPeriodHolder
.
getTrackGroups
(),
loadingPeriodHolder
.
getTrackSelectorResult
());
if
(
loadingPeriodHolder
==
queue
.
getPlayingPeriod
())
{
// This is the first prepared period, so update the position and the renderers.
resetRendererPosition
(
loadingPeriodHolder
.
info
.
startPositionUs
);
...
...
@@ -2568,6 +2573,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
&&
loadingMediaPeriodHolder
!=
null
&&
loadingMediaPeriodHolder
.
prepared
)
{
updateLoadControlTrackSelection
(
loadingMediaPeriodHolder
.
info
.
id
,
loadingMediaPeriodHolder
.
getTrackGroups
(),
loadingMediaPeriodHolder
.
getTrackSelectorResult
());
}
...
...
@@ -2588,8 +2594,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
private
void
updateLoadControlTrackSelection
(
TrackGroupArray
trackGroups
,
TrackSelectorResult
trackSelectorResult
)
{
loadControl
.
onTracksSelected
(
renderers
,
trackGroups
,
trackSelectorResult
.
selections
);
MediaPeriodId
mediaPeriodId
,
TrackGroupArray
trackGroups
,
TrackSelectorResult
trackSelectorResult
)
{
loadControl
.
onTracksSelected
(
playbackInfo
.
timeline
,
mediaPeriodId
,
renderers
,
trackGroups
,
trackSelectorResult
.
selections
);
}
private
boolean
shouldPlayWhenReady
()
{
...
...
library/core/src/main/java/com/google/android/exoplayer2/LoadControl.java
View file @
6a3e2a64
...
...
@@ -15,6 +15,8 @@
*/
package
com
.
google
.
android
.
exoplayer2
;
import
com.google.android.exoplayer2.source.MediaPeriod
;
import
com.google.android.exoplayer2.source.MediaPeriodId
;
import
com.google.android.exoplayer2.source.TrackGroup
;
import
com.google.android.exoplayer2.source.TrackGroupArray
;
import
com.google.android.exoplayer2.trackselection.ExoTrackSelection
;
...
...
@@ -23,18 +25,49 @@ import com.google.android.exoplayer2.upstream.Allocator;
/** Controls buffering of media. */
public
interface
LoadControl
{
/**
* @deprecated Used as a placeholder when MediaPeriodId is unknown. Only used when the deprecated
* methods {@link #onTracksSelected(Renderer[], TrackGroupArray, ExoTrackSelection[])} or
* {@link #shouldStartPlayback(long, float, boolean, long)} are called.
*/
@Deprecated
MediaPeriodId
EMPTY_MEDIA_PERIOD_ID
=
new
MediaPeriodId
(
/* periodUid= */
new
Object
());
/** Called by the player when prepared with a new source. */
void
onPrepared
();
/**
* Called by the player when a track selection occurs.
*
* @param timeline The current {@link Timeline} in ExoPlayer. Can be {@link Timeline#EMPTY} only
* when the deprecated {@link #onTracksSelected(Renderer[], TrackGroupArray,
* ExoTrackSelection[])} was called.
* @param mediaPeriodId Identifies (in the current timeline) the {@link MediaPeriod} for which the
* selection was made. Will be {@link #EMPTY_MEDIA_PERIOD_ID} when {@code timeline} is empty.
* @param renderers The renderers.
* @param trackGroups The {@link TrackGroup}s from which the selection was made.
* @param trackSelections The track selections that were made.
*/
void
onTracksSelected
(
Renderer
[]
renderers
,
TrackGroupArray
trackGroups
,
ExoTrackSelection
[]
trackSelections
);
@SuppressWarnings
(
"deprecation"
)
// Calling deprecated version of this method.
default
void
onTracksSelected
(
Timeline
timeline
,
MediaPeriodId
mediaPeriodId
,
Renderer
[]
renderers
,
TrackGroupArray
trackGroups
,
ExoTrackSelection
[]
trackSelections
)
{
onTracksSelected
(
renderers
,
trackGroups
,
trackSelections
);
}
/**
* @deprecated Implement {@link #onTracksSelected(Timeline, MediaPeriodId, Renderer[],
* TrackGroupArray, ExoTrackSelection[])} instead.
*/
@Deprecated
default
void
onTracksSelected
(
Renderer
[]
renderers
,
TrackGroupArray
trackGroups
,
ExoTrackSelection
[]
trackSelections
)
{
onTracksSelected
(
Timeline
.
EMPTY
,
EMPTY_MEDIA_PERIOD_ID
,
renderers
,
trackGroups
,
trackSelections
);
}
/** Called by the player when stopped. */
void
onStopped
();
...
...
@@ -80,7 +113,9 @@ public interface LoadControl {
boolean
retainBackBufferFromKeyframe
();
/**
* Called by the player to determine whether it should continue to load the source.
* Called by the player to determine whether it should continue to load the source. If this method
* returns true, the {@link MediaPeriod} identified in the most recent {@link #onTracksSelected}
* call will continue being loaded.
*
* @param playbackPositionUs The current playback position in microseconds, relative to the start
* of the {@link Timeline.Period period} that will continue to be loaded if this method
...
...
@@ -100,6 +135,10 @@ public interface LoadControl {
* determines whether playback is actually started. The load control may opt to return {@code
* false} until some condition has been met (e.g. a certain amount of media is buffered).
*
* @param timeline The current {@link Timeline} in ExoPlayer. Can be {@link Timeline#EMPTY} only
* when the deprecated {@link #shouldStartPlayback(long, float, boolean, long)} was called.
* @param mediaPeriodId Identifies (in the current timeline) the {@link MediaPeriod} for which
* playback will start. Will be {@link #EMPTY_MEDIA_PERIOD_ID} when {@code timeline} is empty.
* @param bufferedDurationUs The duration of media that's currently buffered.
* @param playbackSpeed The current factor by which playback is sped up.
* @param rebuffering Whether the player is rebuffering. A rebuffer is defined to be caused by
...
...
@@ -110,6 +149,30 @@ public interface LoadControl {
* configured.
* @return Whether playback should be allowed to start or resume.
*/
boolean
shouldStartPlayback
(
long
bufferedDurationUs
,
float
playbackSpeed
,
boolean
rebuffering
,
long
targetLiveOffsetUs
);
@SuppressWarnings
(
"deprecation"
)
// Calling deprecated version of this method.
default
boolean
shouldStartPlayback
(
Timeline
timeline
,
MediaPeriodId
mediaPeriodId
,
long
bufferedDurationUs
,
float
playbackSpeed
,
boolean
rebuffering
,
long
targetLiveOffsetUs
)
{
return
shouldStartPlayback
(
bufferedDurationUs
,
playbackSpeed
,
rebuffering
,
targetLiveOffsetUs
);
}
/**
* @deprecated Implement {@link #shouldStartPlayback(Timeline, MediaPeriodId, long, float,
* boolean, long)} instead.
*/
@Deprecated
default
boolean
shouldStartPlayback
(
long
bufferedDurationUs
,
float
playbackSpeed
,
boolean
rebuffering
,
long
targetLiveOffsetUs
)
{
return
shouldStartPlayback
(
Timeline
.
EMPTY
,
EMPTY_MEDIA_PERIOD_ID
,
bufferedDurationUs
,
playbackSpeed
,
rebuffering
,
targetLiveOffsetUs
);
}
}
library/core/src/test/java/com/google/android/exoplayer2/DefaultLoadControlTest.java
View file @
6a3e2a64
...
...
@@ -178,7 +178,12 @@ public class DefaultLoadControlTest {
@Test
public
void
shouldContinueLoading_withNoSelectedTracks_returnsTrue
()
{
loadControl
=
builder
.
build
();
loadControl
.
onTracksSelected
(
new
Renderer
[
0
],
TrackGroupArray
.
EMPTY
,
new
ExoTrackSelection
[
0
]);
loadControl
.
onTracksSelected
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
new
Renderer
[
0
],
TrackGroupArray
.
EMPTY
,
new
ExoTrackSelection
[
0
]);
assertThat
(
loadControl
.
shouldContinueLoading
(
...
...
@@ -202,6 +207,8 @@ public class DefaultLoadControlTest {
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
MIN_BUFFER_US
,
SPEED
,
/* rebuffering= */
false
,
...
...
@@ -221,6 +228,8 @@ public class DefaultLoadControlTest {
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
2_999_999
,
SPEED
,
/* rebuffering= */
false
,
...
...
@@ -228,6 +237,8 @@ public class DefaultLoadControlTest {
.
isFalse
();
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
3_000_000
,
SPEED
,
/* rebuffering= */
false
,
...
...
@@ -246,6 +257,8 @@ public class DefaultLoadControlTest {
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
499_999
,
SPEED
,
/* rebuffering= */
true
,
...
...
@@ -253,6 +266,8 @@ public class DefaultLoadControlTest {
.
isFalse
();
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
500_000
,
SPEED
,
/* rebuffering= */
true
,
...
...
@@ -272,6 +287,8 @@ public class DefaultLoadControlTest {
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
3_999_999
,
SPEED
,
/* rebuffering= */
true
,
...
...
@@ -279,6 +296,8 @@ public class DefaultLoadControlTest {
.
isFalse
();
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
4_000_000
,
SPEED
,
/* rebuffering= */
true
,
...
...
@@ -297,6 +316,8 @@ public class DefaultLoadControlTest {
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
499_999
,
SPEED
,
/* rebuffering= */
true
,
...
...
@@ -304,6 +325,8 @@ public class DefaultLoadControlTest {
.
isFalse
();
assertThat
(
loadControl
.
shouldStartPlayback
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
/* bufferedDurationUs= */
500_000
,
SPEED
,
/* rebuffering= */
true
,
...
...
@@ -314,7 +337,8 @@ public class DefaultLoadControlTest {
private
void
build
()
{
builder
.
setAllocator
(
allocator
).
setTargetBufferBytes
(
TARGET_BUFFER_BYTES
);
loadControl
=
builder
.
build
();
loadControl
.
onTracksSelected
(
new
Renderer
[
0
],
null
,
null
);
loadControl
.
onTracksSelected
(
Timeline
.
EMPTY
,
LoadControl
.
EMPTY_MEDIA_PERIOD_ID
,
new
Renderer
[
0
],
null
,
null
);
}
private
void
makeSureTargetBufferBytesReached
()
{
...
...
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