Skip to content

Commit 058db9c

Browse files
authored
Merge branch 'main' into feature/prevent-infinite-reloads-for-ll-hls
2 parents bbe8200 + c8a3361 commit 058db9c

File tree

11 files changed

+389
-55
lines changed

11 files changed

+389
-55
lines changed

RELEASENOTES.md

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@
8080
* Cronet extension:
8181
* RTMP extension:
8282
* HLS extension:
83+
* Fix issue where chunk duration wasn't set in `CmcdData` for HLS media,
84+
causing an assertion failure when processing encrypted media segments
85+
([#2312](https://github.com/androidx/media/issues/2312)).
8386
* Prevent excessive reloads by waiting for half the part target duration
8487
when `CAN-BLOCK-RELOAD=YES` is not honored.
8588
* DASH extension:

libraries/decoder/src/main/java/androidx/media3/decoder/VideoDecoderOutputBuffer.java

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public class VideoDecoderOutputBuffer extends DecoderOutputBuffer {
5656

5757
@Nullable public int[] yuvStrides;
5858
public int colorspace;
59+
public int yStride;
60+
public int uvStride;
5961

6062
/**
6163
* Supplemental data related to the output frame, if {@link #hasSupplementalData()} returns true.
@@ -117,6 +119,8 @@ public boolean initForYuvFrame(int width, int height, int yStride, int uvStride,
117119
this.width = width;
118120
this.height = height;
119121
this.colorspace = colorspace;
122+
this.yStride = yStride;
123+
this.uvStride = uvStride;
120124
int uvHeight = (int) (((long) height + 1) / 2);
121125
if (!isSafeToMultiply(yStride, height) || !isSafeToMultiply(uvStride, uvHeight)) {
122126
return false;

libraries/effect/src/main/java/androidx/media3/effect/ReplayableFrameCacheGlShaderProgram.java

+11
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ public void flush() {
6666
super.flush();
6767
}
6868

69+
@Override
70+
public void signalEndOfCurrentInputStream() {
71+
// TODO: b/391109625 - Support mixed size buffers in the output texture pool to allow
72+
// replaying the last frame in a sequence.
73+
for (int i = 0; i < cacheSize; i++) {
74+
super.releaseOutputFrame(cachedFrames[i].glTextureInfo);
75+
}
76+
cacheSize = 0;
77+
super.signalEndOfCurrentInputStream();
78+
}
79+
6980
/** Returns whether there is no cached frame. */
7081
public boolean isEmpty() {
7182
return cacheSize == 0;

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -731,8 +731,15 @@ public boolean isInitialized() {
731731
@Override
732732
public void redraw() {
733733
checkState(isInitialized());
734+
// Resignal EOS only for the last item.
735+
boolean needsResignalEndOfCurrentInputStream = signaledEndOfStream;
736+
long replayedPresentationTimeUs = lastOutputBufferPresentationTimeUs;
734737
PlaybackVideoGraphWrapper.this.flush(/* resetPosition= */ false);
735738
checkNotNull(videoGraph).redraw();
739+
lastOutputBufferPresentationTimeUs = replayedPresentationTimeUs;
740+
if (needsResignalEndOfCurrentInputStream) {
741+
signalEndOfCurrentInputStream();
742+
}
736743
}
737744

738745
@Override

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoFrameRenderControl.java

+7
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,13 @@ public void onFrameAvailableForRendering(long presentationTimeUs) {
209209
* this method, the end of input signal is ignored.
210210
*/
211211
public void signalEndOfInput() {
212+
if (latestInputPresentationTimeUs == C.TIME_UNSET) {
213+
// If EOS is signalled right after a flush without receiving a frame (could happen with frame
214+
// replaying as available frame is not reported to the render control), set the latest input
215+
// and output timestamp to end of source to ensure isEnded() returns true.
216+
latestInputPresentationTimeUs = C.TIME_END_OF_SOURCE;
217+
latestOutputPresentationTimeUs = C.TIME_END_OF_SOURCE;
218+
}
212219
lastPresentationTimeUs = latestInputPresentationTimeUs;
213220
}
214221

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,8 @@ public void getNextChunk(
517517
.setPlaybackRate(loadingInfo.playbackSpeed)
518518
.setIsLive(!playlist.hasEndTag)
519519
.setDidRebuffer(loadingInfo.rebufferedSince(lastChunkRequestRealtimeMs))
520-
.setIsBufferEmpty(queue.isEmpty());
520+
.setIsBufferEmpty(queue.isEmpty())
521+
.setChunkDurationUs(segmentBaseHolder.segmentBase.durationUs);
521522
long nextMediaSequence =
522523
segmentBaseHolder.partIndex == C.INDEX_UNSET
523524
? segmentBaseHolder.mediaSequence + 1

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ public static HlsMediaChunk createInstance(
112112
.setFlags(segmentBaseHolder.isPreload ? FLAG_MIGHT_NOT_USE_FULL_NETWORK_SPEED : 0)
113113
.build();
114114
if (cmcdDataFactory != null) {
115-
CmcdData cmcdData =
116-
cmcdDataFactory.setChunkDurationUs(mediaSegment.durationUs).createCmcdData();
115+
CmcdData cmcdData = cmcdDataFactory.createCmcdData();
117116
dataSpec = cmcdData.addToDataSpec(dataSpec);
118117
}
119118

0 commit comments

Comments
 (0)