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/media#888 #minor-release PiperOrigin-RevId: 591099785
This commit is contained in:
parent
0baf777c96
commit
7f6596bab2
@ -36,6 +36,10 @@
|
|||||||
* Fix issue where track selections after seek to zero in a live stream
|
* Fix issue where track selections after seek to zero in a live stream
|
||||||
incorrectly let the stream start at its default position
|
incorrectly let the stream start at its default position
|
||||||
([#9347](https://github.com/google/ExoPlayer/issues/9347)).
|
([#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:
|
* Transformer:
|
||||||
* Add support for flattening H.265/HEVC SEF slow motion videos.
|
* Add support for flattening H.265/HEVC SEF slow motion videos.
|
||||||
* Increase transmuxing speed, especially for 'remove video' edits.
|
* Increase transmuxing speed, especially for 'remove video' edits.
|
||||||
|
@ -121,7 +121,8 @@ public final class CmcdData {
|
|||||||
* and this one, {@code false} otherwise.
|
* and this one, {@code false} otherwise.
|
||||||
* @param isBufferEmpty {@code true} if the queue of buffered chunks is empty, {@code false}
|
* @param isBufferEmpty {@code true} if the queue of buffered chunks is empty, {@code false}
|
||||||
* otherwise.
|
* otherwise.
|
||||||
* @throws IllegalArgumentException If {@code bufferedDurationUs} is negative.
|
* @throws IllegalArgumentException If {@code bufferedDurationUs} is negative or {@code
|
||||||
|
* playbackRate} is non-positive.
|
||||||
*/
|
*/
|
||||||
public Factory(
|
public Factory(
|
||||||
CmcdConfiguration cmcdConfiguration,
|
CmcdConfiguration cmcdConfiguration,
|
||||||
|
@ -410,7 +410,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||||||
: new CmcdData.Factory(
|
: new CmcdData.Factory(
|
||||||
cmcdConfiguration,
|
cmcdConfiguration,
|
||||||
trackSelection,
|
trackSelection,
|
||||||
bufferedDurationUs,
|
max(0, bufferedDurationUs),
|
||||||
/* playbackRate= */ loadingInfo.playbackSpeed,
|
/* playbackRate= */ loadingInfo.playbackSpeed,
|
||||||
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_DASH,
|
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_DASH,
|
||||||
/* isLive= */ manifest.dynamic,
|
/* isLive= */ manifest.dynamic,
|
||||||
|
@ -339,6 +339,23 @@ public class DefaultDashChunkSourceTest {
|
|||||||
"bl=1000,dl=800,mtp=1000,nor=\"..%2Fvideo_8000_700000.m4s\",nrr=\"0-\"",
|
"bl=1000,dl=800,mtp=1000,nor=\"..%2Fvideo_8000_700000.m4s\",nrr=\"0-\"",
|
||||||
"CMCD-Session",
|
"CMCD-Session",
|
||||||
"cid=\"mediaId\",pr=1.25,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
|
"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
|
@Test
|
||||||
|
@ -495,7 +495,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
new CmcdData.Factory(
|
new CmcdData.Factory(
|
||||||
cmcdConfiguration,
|
cmcdConfiguration,
|
||||||
trackSelection,
|
trackSelection,
|
||||||
bufferedDurationUs,
|
max(0, bufferedDurationUs),
|
||||||
/* playbackRate= */ loadingInfo.playbackSpeed,
|
/* playbackRate= */ loadingInfo.playbackSpeed,
|
||||||
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_HLS,
|
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_HLS,
|
||||||
/* isLive= */ !playlist.hasEndTag,
|
/* isLive= */ !playlist.hasEndTag,
|
||||||
|
@ -234,6 +234,24 @@ public class HlsChunkSourceTest {
|
|||||||
"bl=1000,dl=800,nor=\"..%2F3.mp4\",nrr=\"0-\"",
|
"bl=1000,dl=800,nor=\"..%2F3.mp4\",nrr=\"0-\"",
|
||||||
"CMCD-Session",
|
"CMCD-Session",
|
||||||
"cid=\"mediaId\",pr=1.25,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
|
"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
|
@Test
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package androidx.media3.exoplayer.smoothstreaming;
|
package androidx.media3.exoplayer.smoothstreaming;
|
||||||
|
|
||||||
import static androidx.media3.exoplayer.trackselection.TrackSelectionUtil.createFallbackOptions;
|
import static androidx.media3.exoplayer.trackselection.TrackSelectionUtil.createFallbackOptions;
|
||||||
|
import static java.lang.Math.max;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
@ -319,7 +320,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||||||
new CmcdData.Factory(
|
new CmcdData.Factory(
|
||||||
cmcdConfiguration,
|
cmcdConfiguration,
|
||||||
trackSelection,
|
trackSelection,
|
||||||
bufferedDurationUs,
|
max(0, bufferedDurationUs),
|
||||||
/* playbackRate= */ loadingInfo.playbackSpeed,
|
/* playbackRate= */ loadingInfo.playbackSpeed,
|
||||||
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_SS,
|
/* streamingFormat= */ CmcdData.Factory.STREAMING_FORMAT_SS,
|
||||||
/* isLive= */ manifest.isLive,
|
/* isLive= */ manifest.isLive,
|
||||||
|
@ -89,6 +89,23 @@ public class DefaultSsChunkSourceTest {
|
|||||||
"bl=1000,dl=500,mtp=1000,nor=\"..%2FFragments(video%3D28660000)\"",
|
"bl=1000,dl=500,mtp=1000,nor=\"..%2FFragments(video%3D28660000)\"",
|
||||||
"CMCD-Session",
|
"CMCD-Session",
|
||||||
"cid=\"mediaId\",pr=2.00,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
|
"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
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user