Skip to content

Commit 9cfaf78

Browse files
microkatztonihei
authored andcommitted
Do not enable offload scheduling while preparing next media
ExoPlayer disables sleeping for offload when the reading period advances and re-evaluates turning it back on when the playing period advances. For playlists of short items where the reading period could advance much further than the playing period, sleeping should still be disabled until the playing period advances to match the current reading period. Issue: #1920 PiperOrigin-RevId: 743503063 (cherry picked from commit 8327a2a)
1 parent cb80fe4 commit 9cfaf78

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

RELEASENOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
* DataSource:
4040
* Audio:
4141
* Allow constant power upmixing/downmixing in DefaultAudioMixer.
42+
* Fix offload issue where position might get stuck when playing a playlist
43+
of short content
44+
([#1920](https://github.com/androidx/media/issues/1920)).
4245
* Video:
4346
* Add experimental `ExoPlayer` API to include the
4447
`MediaCodec.BUFFER_FLAG_DECODE_ONLY` flag when queuing decode-only input

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,6 +2783,10 @@ private void maybeHandlePrewarmingTransition() throws ExoPlaybackException {
27832783
private void maybeUpdateOffloadScheduling() {
27842784
// If playing period is audio-only with offload mode preference to enable, then offload
27852785
// scheduling should be enabled.
2786+
if (queue.getPlayingPeriod() != queue.getReadingPeriod()) {
2787+
// Do not enable offload scheduling when starting to process the next media item.
2788+
return;
2789+
}
27862790
@Nullable MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
27872791
if (playingPeriodHolder != null) {
27882792
TrackSelectorResult trackSelectorResult = playingPeriodHolder.getTrackSelectorResult();

libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11786,6 +11786,54 @@ public void enableOffloadScheduling_whenOffloadIsDisabled_renderingResumes() thr
1178611786
player.release();
1178711787
}
1178811788

11789+
@Test
11790+
public void enablingOffload_withFastReadingPeriodAdvancement_playerDoesNotSleep()
11791+
throws Exception {
11792+
FakeSleepRenderer sleepRenderer = new FakeSleepRenderer(C.TRACK_TYPE_AUDIO);
11793+
AtomicInteger sleepingForOffloadCounter = new AtomicInteger();
11794+
ExoPlayer player =
11795+
parameterizeTestExoPlayerBuilder(
11796+
new TestExoPlayerBuilder(context).setRenderers(sleepRenderer))
11797+
.build();
11798+
ExoPlayer.AudioOffloadListener listener =
11799+
new ExoPlayer.AudioOffloadListener() {
11800+
@Override
11801+
public void onSleepingForOffloadChanged(boolean sleepingForOffload) {
11802+
if (sleepingForOffload) {
11803+
sleepingForOffloadCounter.getAndIncrement();
11804+
}
11805+
}
11806+
};
11807+
player.addAudioOffloadListener(listener);
11808+
// Set a playlist of multiple, short audio-only items such that the reading period quickly
11809+
// advances past the playing period.
11810+
Timeline timeline = new FakeTimeline();
11811+
player.setMediaSources(
11812+
ImmutableList.of(
11813+
new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT),
11814+
new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT),
11815+
new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT)));
11816+
player.setTrackSelectionParameters(
11817+
player
11818+
.getTrackSelectionParameters()
11819+
.buildUpon()
11820+
.setAudioOffloadPreferences(
11821+
new AudioOffloadPreferences.Builder()
11822+
.setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_REQUIRED)
11823+
.build())
11824+
.build());
11825+
player.prepare();
11826+
player.play();
11827+
advance(player).untilStartOfMediaItem(/* mediaItemIndex= */ 1);
11828+
11829+
sleepRenderer.sleepOnNextRender();
11830+
runUntilPlaybackState(player, Player.STATE_ENDED);
11831+
11832+
assertThat(sleepingForOffloadCounter.get()).isEqualTo(0);
11833+
11834+
player.release();
11835+
}
11836+
1178911837
@Test
1179011838
public void wakeupListenerWhileSleepingForOffload_isWokenUp_renderingResumes() throws Exception {
1179111839
FakeSleepRenderer sleepRenderer = new FakeSleepRenderer(C.TRACK_TYPE_AUDIO).sleepOnNextRender();

0 commit comments

Comments
 (0)