Skip to content

Commit

Permalink
Fix sending negative bufferedDurationUs to CmcdData.Factory
Browse files Browse the repository at this point in the history
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: #888

#minor-release

PiperOrigin-RevId: 591099785
  • Loading branch information
rohitjoins authored and copybara-github committed Dec 15, 2023
1 parent 0baf777 commit 7f6596b
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 4 deletions.
4 changes: 4 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
* Fix issue where track selections after seek to zero in a live stream
incorrectly let the stream start at its default position
([#9347](https://github.com/google/ExoPlayer/issues/9347)).
* Fix the issue where new instances of `CmcdData.Factory` were receiving
negative values for `bufferedDurationUs` from chunk sources, resulting
in an `IllegalArgumentException`
([#888](https://github.com/androidx/media/issues/888)).
* Transformer:
* Add support for flattening H.265/HEVC SEF slow motion videos.
* Increase transmuxing speed, especially for 'remove video' edits.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ public static final class Factory {
* and this one, {@code false} otherwise.
* @param isBufferEmpty {@code true} if the queue of buffered chunks is empty, {@code false}
* otherwise.
* @throws IllegalArgumentException If {@code bufferedDurationUs} is negative.
* @throws IllegalArgumentException If {@code bufferedDurationUs} is negative or {@code
* playbackRate} is non-positive.
*/
public Factory(
CmcdConfiguration cmcdConfiguration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ public void getNextChunk(
: new CmcdData.Factory(
cmcdConfiguration,
trackSelection,
bufferedDurationUs,
max(0, bufferedDurationUs),
/* playbackRate= */ loadingInfo.playbackSpeed,
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_DASH,
/* isLive= */ manifest.dynamic,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,23 @@ public void getNextChunk_chunkSourceWithDefaultCmcdConfiguration_setsCmcdHttpReq
"bl=1000,dl=800,mtp=1000,nor=\"..%2Fvideo_8000_700000.m4s\",nrr=\"0-\"",
"CMCD-Session",
"cid=\"mediaId\",pr=1.25,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");

// Playing mid-chunk, where loadPositionUs is less than playbackPositionUs
chunkSource.getNextChunk(
new LoadingInfo.Builder().setPlaybackPositionUs(5_000_000).setPlaybackSpeed(1.25f).build(),
/* loadPositionUs= */ 4_000_000,
/* queue= */ ImmutableList.of((MediaChunk) output.chunk),
output);

// buffer length is set to 0 when bufferedDurationUs is negative
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=700,d=4000,ot=v,tb=1300",
"CMCD-Request",
"bl=0,dl=0,mtp=1000,nor=\"..%2Fvideo_12000_700000.m4s\",nrr=\"0-\"",
"CMCD-Session",
"cid=\"mediaId\",pr=1.25,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ public void getNextChunk(
new CmcdData.Factory(
cmcdConfiguration,
trackSelection,
bufferedDurationUs,
max(0, bufferedDurationUs),
/* playbackRate= */ loadingInfo.playbackSpeed,
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_HLS,
/* isLive= */ !playlist.hasEndTag,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,24 @@ public void getNextChunk_chunkSourceWithDefaultCmcdConfiguration_setsCmcdHttpReq
"bl=1000,dl=800,nor=\"..%2F3.mp4\",nrr=\"0-\"",
"CMCD-Session",
"cid=\"mediaId\",pr=1.25,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");

// Playing mid-chunk, where loadPositionUs is less than playbackPositionUs
testChunkSource.getNextChunk(
new LoadingInfo.Builder().setPlaybackPositionUs(5_000_000).setPlaybackSpeed(1.25f).build(),
/* loadPositionUs= */ 4_000_000,
/* queue= */ ImmutableList.of((HlsMediaChunk) output.chunk),
/* allowEndOfStream= */ true,
output);

// buffer length is set to 0 when bufferedDurationUs is negative
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=800,d=4000,ot=v,tb=800",
"CMCD-Request",
"bl=0,dl=0,nor=\"..%2F3.mp4\",nrr=\"0-\"",
"CMCD-Session",
"cid=\"mediaId\",pr=1.25,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package androidx.media3.exoplayer.smoothstreaming;

import static androidx.media3.exoplayer.trackselection.TrackSelectionUtil.createFallbackOptions;
import static java.lang.Math.max;

import android.net.Uri;
import android.os.SystemClock;
Expand Down Expand Up @@ -319,7 +320,7 @@ public final void getNextChunk(
new CmcdData.Factory(
cmcdConfiguration,
trackSelection,
bufferedDurationUs,
max(0, bufferedDurationUs),
/* playbackRate= */ loadingInfo.playbackSpeed,
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_SS,
/* isLive= */ manifest.isLive,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ public void getNextChunk_chunkSourceWithDefaultCmcdConfiguration_setsCmcdHttpReq
"bl=1000,dl=500,mtp=1000,nor=\"..%2FFragments(video%3D28660000)\"",
"CMCD-Session",
"cid=\"mediaId\",pr=2.00,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");

// Playing mid-chunk, where loadPositionUs is less than playbackPositionUs
chunkSource.getNextChunk(
new LoadingInfo.Builder().setPlaybackPositionUs(5_000_000).setPlaybackSpeed(2.0f).build(),
/* loadPositionUs= */ 4_000_000,
/* queue= */ ImmutableList.of((MediaChunk) output.chunk),
output);

// buffer length is set to 0 when bufferedDurationUs is negative
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=308,d=898,ot=v,tb=1536",
"CMCD-Request",
"bl=0,dl=0,mtp=1000",
"CMCD-Session",
"cid=\"mediaId\",pr=2.00,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
}

@Test
Expand Down

0 comments on commit 7f6596b

Please sign in to comment.