mirror of
https://github.com/androidx/media.git
synced 2025-05-14 11:09:53 +08:00
Don't require the existence of the next period to wait for its stream.
We have a workaround for uneven sample stream durarions in playlists that
assumes a renderer allows playback if it's reading ahead or waiting for
the next stream.
652c2f9c18
changed this logic to no longer require to
wait until the next stream is prepared due to a change in how we advance
media periods in the queue. However, the code falsely still requires the
next stream to exist (even if it's not prepared). This can cause a stuck
buffering state when the difference in the duration of the streams is more
than what we buffer ahead because we never create the next stream in such
a case.
Note: DefaultMediaClock.shouldUseStandaloneClock has roughly the same logic
and also doesn't require the next stream to be present.
Also fix a test that seemed to rely on this stuck buffering case to test
stuck buffering detection. Changed the test to not read the end of stream
to ensure it runs into the desired stuck buffering case.
Issue:#7943
PiperOrigin-RevId: 333050285
This commit is contained in:
parent
12e887438b
commit
25e31743d3
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
### dev-v2 (not yet released)
|
### dev-v2 (not yet released)
|
||||||
|
|
||||||
|
* Core library:
|
||||||
|
* Fix bug where streams with highly uneven durations may get stuck in a
|
||||||
|
buffering state
|
||||||
|
([#7943](https://github.com/google/ExoPlayer/issues/7943)).
|
||||||
* Track selection:
|
* Track selection:
|
||||||
* Add option to specify multiple preferred audio or text languages.
|
* Add option to specify multiple preferred audio or text languages.
|
||||||
* Data sources:
|
* Data sources:
|
||||||
|
@ -897,10 +897,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
// tracks in the current period have uneven durations and are still being read by another
|
// tracks in the current period have uneven durations and are still being read by another
|
||||||
// renderer. See: https://github.com/google/ExoPlayer/issues/1874.
|
// renderer. See: https://github.com/google/ExoPlayer/issues/1874.
|
||||||
boolean isReadingAhead = playingPeriodHolder.sampleStreams[i] != renderer.getStream();
|
boolean isReadingAhead = playingPeriodHolder.sampleStreams[i] != renderer.getStream();
|
||||||
boolean isWaitingForNextStream =
|
boolean isWaitingForNextStream = !isReadingAhead && renderer.hasReadStreamToEnd();
|
||||||
!isReadingAhead
|
|
||||||
&& playingPeriodHolder.getNext() != null
|
|
||||||
&& renderer.hasReadStreamToEnd();
|
|
||||||
boolean allowsPlayback =
|
boolean allowsPlayback =
|
||||||
isReadingAhead || isWaitingForNextStream || renderer.isReady() || renderer.isEnded();
|
isReadingAhead || isWaitingForNextStream || renderer.isReady() || renderer.isEnded();
|
||||||
renderersAllowPlayback = renderersAllowPlayback && allowsPlayback;
|
renderersAllowPlayback = renderersAllowPlayback && allowsPlayback;
|
||||||
|
@ -7334,6 +7334,8 @@ public final class ExoPlayerTest {
|
|||||||
new DefaultLoadControl.Builder()
|
new DefaultLoadControl.Builder()
|
||||||
.setTargetBufferBytes(10 * C.DEFAULT_BUFFER_SEGMENT_SIZE)
|
.setTargetBufferBytes(10 * C.DEFAULT_BUFFER_SEGMENT_SIZE)
|
||||||
.build();
|
.build();
|
||||||
|
// Return no end of stream signal to prevent playback from ending.
|
||||||
|
FakeMediaPeriod.TrackDataFactory trackDataWithoutEos = (format, periodId) -> ImmutableList.of();
|
||||||
MediaSource continuouslyAllocatingMediaSource =
|
MediaSource continuouslyAllocatingMediaSource =
|
||||||
new FakeMediaSource(
|
new FakeMediaSource(
|
||||||
new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@ -7348,8 +7350,11 @@ public final class ExoPlayerTest {
|
|||||||
@Nullable TransferListener transferListener) {
|
@Nullable TransferListener transferListener) {
|
||||||
return new FakeMediaPeriod(
|
return new FakeMediaPeriod(
|
||||||
trackGroupArray,
|
trackGroupArray,
|
||||||
TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US,
|
trackDataWithoutEos,
|
||||||
mediaSourceEventDispatcher) {
|
mediaSourceEventDispatcher,
|
||||||
|
drmSessionManager,
|
||||||
|
drmEventDispatcher,
|
||||||
|
/* deferOnPrepared= */ false) {
|
||||||
|
|
||||||
private final List<Allocation> allocations = new ArrayList<>();
|
private final List<Allocation> allocations = new ArrayList<>();
|
||||||
|
|
||||||
@ -7382,14 +7387,8 @@ public final class ExoPlayerTest {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ActionSchedule actionSchedule =
|
|
||||||
new ActionSchedule.Builder(TAG)
|
|
||||||
// Prevent player from ever assuming it finished playing.
|
|
||||||
.setRepeatMode(Player.REPEAT_MODE_ALL)
|
|
||||||
.build();
|
|
||||||
ExoPlayerTestRunner testRunner =
|
ExoPlayerTestRunner testRunner =
|
||||||
new ExoPlayerTestRunner.Builder(context)
|
new ExoPlayerTestRunner.Builder(context)
|
||||||
.setActionSchedule(actionSchedule)
|
|
||||||
.setMediaSources(continuouslyAllocatingMediaSource)
|
.setMediaSources(continuouslyAllocatingMediaSource)
|
||||||
.setLoadControl(loadControl)
|
.setLoadControl(loadControl)
|
||||||
.build();
|
.build();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user