Skip to content

Commit 7f6596b

Browse files
rohitjoinscopybara-github
authored andcommitted
Fix sending negative bufferedDurationUs to CmcdData.Factory
When track is changed during playback, `playbackPositionUs` may be in middle of a chunk and `loadPositionUs` should be the start of that chunk. In this situation `loadPositionUs` can be less than the current `playbackPositionUs`, resulting into negative `bufferedDurationUs`. It translates to having no buffer and hence we should send `0` for `bufferedDurationUs` when creating new instances of `CmcdData.Factory`. Issue: androidx#888 #minor-release PiperOrigin-RevId: 591099785
1 parent 0baf777 commit 7f6596b

File tree

8 files changed

+62
-4
lines changed

8 files changed

+62
-4
lines changed

RELEASENOTES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
* Fix issue where track selections after seek to zero in a live stream
3737
incorrectly let the stream start at its default position
3838
([#9347](https://github.com/google/ExoPlayer/issues/9347)).
39+
* Fix the issue where new instances of `CmcdData.Factory` were receiving
40+
negative values for `bufferedDurationUs` from chunk sources, resulting
41+
in an `IllegalArgumentException`
42+
([#888](https://github.com/androidx/media/issues/888)).
3943
* Transformer:
4044
* Add support for flattening H.265/HEVC SEF slow motion videos.
4145
* Increase transmuxing speed, especially for 'remove video' edits.

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdData.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ public static final class Factory {
121121
* and this one, {@code false} otherwise.
122122
* @param isBufferEmpty {@code true} if the queue of buffered chunks is empty, {@code false}
123123
* otherwise.
124-
* @throws IllegalArgumentException If {@code bufferedDurationUs} is negative.
124+
* @throws IllegalArgumentException If {@code bufferedDurationUs} is negative or {@code
125+
* playbackRate} is non-positive.
125126
*/
126127
public Factory(
127128
CmcdConfiguration cmcdConfiguration,

libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DefaultDashChunkSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public void getNextChunk(
410410
: new CmcdData.Factory(
411411
cmcdConfiguration,
412412
trackSelection,
413-
bufferedDurationUs,
413+
max(0, bufferedDurationUs),
414414
/* playbackRate= */ loadingInfo.playbackSpeed,
415415
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_DASH,
416416
/* isLive= */ manifest.dynamic,

libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DefaultDashChunkSourceTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,23 @@ public void getNextChunk_chunkSourceWithDefaultCmcdConfiguration_setsCmcdHttpReq
339339
"bl=1000,dl=800,mtp=1000,nor=\"..%2Fvideo_8000_700000.m4s\",nrr=\"0-\"",
340340
"CMCD-Session",
341341
"cid=\"mediaId\",pr=1.25,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
342+
343+
// Playing mid-chunk, where loadPositionUs is less than playbackPositionUs
344+
chunkSource.getNextChunk(
345+
new LoadingInfo.Builder().setPlaybackPositionUs(5_000_000).setPlaybackSpeed(1.25f).build(),
346+
/* loadPositionUs= */ 4_000_000,
347+
/* queue= */ ImmutableList.of((MediaChunk) output.chunk),
348+
output);
349+
350+
// buffer length is set to 0 when bufferedDurationUs is negative
351+
assertThat(output.chunk.dataSpec.httpRequestHeaders)
352+
.containsExactly(
353+
"CMCD-Object",
354+
"br=700,d=4000,ot=v,tb=1300",
355+
"CMCD-Request",
356+
"bl=0,dl=0,mtp=1000,nor=\"..%2Fvideo_12000_700000.m4s\",nrr=\"0-\"",
357+
"CMCD-Session",
358+
"cid=\"mediaId\",pr=1.25,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
342359
}
343360

344361
@Test

libraries/exoplayer_hls/src/main/java/androidx/media3/exoplayer/hls/HlsChunkSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ public void getNextChunk(
495495
new CmcdData.Factory(
496496
cmcdConfiguration,
497497
trackSelection,
498-
bufferedDurationUs,
498+
max(0, bufferedDurationUs),
499499
/* playbackRate= */ loadingInfo.playbackSpeed,
500500
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_HLS,
501501
/* isLive= */ !playlist.hasEndTag,

libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsChunkSourceTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,24 @@ public void getNextChunk_chunkSourceWithDefaultCmcdConfiguration_setsCmcdHttpReq
234234
"bl=1000,dl=800,nor=\"..%2F3.mp4\",nrr=\"0-\"",
235235
"CMCD-Session",
236236
"cid=\"mediaId\",pr=1.25,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
237+
238+
// Playing mid-chunk, where loadPositionUs is less than playbackPositionUs
239+
testChunkSource.getNextChunk(
240+
new LoadingInfo.Builder().setPlaybackPositionUs(5_000_000).setPlaybackSpeed(1.25f).build(),
241+
/* loadPositionUs= */ 4_000_000,
242+
/* queue= */ ImmutableList.of((HlsMediaChunk) output.chunk),
243+
/* allowEndOfStream= */ true,
244+
output);
245+
246+
// buffer length is set to 0 when bufferedDurationUs is negative
247+
assertThat(output.chunk.dataSpec.httpRequestHeaders)
248+
.containsExactly(
249+
"CMCD-Object",
250+
"br=800,d=4000,ot=v,tb=800",
251+
"CMCD-Request",
252+
"bl=0,dl=0,nor=\"..%2F3.mp4\",nrr=\"0-\"",
253+
"CMCD-Session",
254+
"cid=\"mediaId\",pr=1.25,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
237255
}
238256

239257
@Test

libraries/exoplayer_smoothstreaming/src/main/java/androidx/media3/exoplayer/smoothstreaming/DefaultSsChunkSource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package androidx.media3.exoplayer.smoothstreaming;
1717

1818
import static androidx.media3.exoplayer.trackselection.TrackSelectionUtil.createFallbackOptions;
19+
import static java.lang.Math.max;
1920

2021
import android.net.Uri;
2122
import android.os.SystemClock;
@@ -319,7 +320,7 @@ public final void getNextChunk(
319320
new CmcdData.Factory(
320321
cmcdConfiguration,
321322
trackSelection,
322-
bufferedDurationUs,
323+
max(0, bufferedDurationUs),
323324
/* playbackRate= */ loadingInfo.playbackSpeed,
324325
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_SS,
325326
/* isLive= */ manifest.isLive,

libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/DefaultSsChunkSourceTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,23 @@ public void getNextChunk_chunkSourceWithDefaultCmcdConfiguration_setsCmcdHttpReq
8989
"bl=1000,dl=500,mtp=1000,nor=\"..%2FFragments(video%3D28660000)\"",
9090
"CMCD-Session",
9191
"cid=\"mediaId\",pr=2.00,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
92+
93+
// Playing mid-chunk, where loadPositionUs is less than playbackPositionUs
94+
chunkSource.getNextChunk(
95+
new LoadingInfo.Builder().setPlaybackPositionUs(5_000_000).setPlaybackSpeed(2.0f).build(),
96+
/* loadPositionUs= */ 4_000_000,
97+
/* queue= */ ImmutableList.of((MediaChunk) output.chunk),
98+
output);
99+
100+
// buffer length is set to 0 when bufferedDurationUs is negative
101+
assertThat(output.chunk.dataSpec.httpRequestHeaders)
102+
.containsExactly(
103+
"CMCD-Object",
104+
"br=308,d=898,ot=v,tb=1536",
105+
"CMCD-Request",
106+
"bl=0,dl=0,mtp=1000",
107+
"CMCD-Session",
108+
"cid=\"mediaId\",pr=2.00,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
92109
}
93110

94111
@Test

0 commit comments

Comments
 (0)