diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5380548237..8133765530 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -43,6 +43,8 @@ * Text: * Fix garbled CEA-608 subtitles in content with more than one SEI message per sample. + * Fix playback hanging on DASH multi-period streams when CEA-608 subtitles + are enabled ([#1863](https://github.com/androidx/media/issues/1863)). * Metadata: * Image: * DRM: diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/CeaDecoder.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/CeaDecoder.java index 00c4455144..79472f5805 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/CeaDecoder.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/CeaDecoder.java @@ -84,7 +84,9 @@ import java.util.ArrayDeque; public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); CeaInputBuffer ceaInputBuffer = (CeaInputBuffer) inputBuffer; - if (outputStartTimeUs != C.TIME_UNSET && ceaInputBuffer.timeUs < outputStartTimeUs) { + if (ceaInputBuffer.timeUs != C.TIME_END_OF_SOURCE + && outputStartTimeUs != C.TIME_UNSET + && ceaInputBuffer.timeUs < outputStartTimeUs) { // We can start decoding anywhere in CEA formats, so discarding on the input side is fine. releaseInputBuffer(ceaInputBuffer); } else { diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/text/cea/Cea608DecoderTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/text/cea/Cea608DecoderTest.java index 718499a043..e7c222e744 100644 --- a/libraries/extractor/src/test/java/androidx/media3/extractor/text/cea/Cea608DecoderTest.java +++ b/libraries/extractor/src/test/java/androidx/media3/extractor/text/cea/Cea608DecoderTest.java @@ -328,6 +328,26 @@ public class Cea608DecoderTest { assertThat(getOnlyCue(firstSubtitle).text.toString()).isEqualTo("test"); } + // https://github.com/androidx/media/issues/1863 + @Test + public void endOfStreamBuffer_flagPassedThrough() throws Exception { + Cea608Decoder decoder = + new Cea608Decoder( + MimeTypes.APPLICATION_CEA608, + /* accessibilityChannel= */ 1, + Cea608Decoder.MIN_DATA_CHANNEL_TIMEOUT_MS); + + SubtitleInputBuffer inputBuffer = checkNotNull(decoder.dequeueInputBuffer()); + inputBuffer.timeUs = C.TIME_END_OF_SOURCE; + inputBuffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); + decoder.setOutputStartTimeUs(0); + decoder.queueInputBuffer(inputBuffer); + decoder.setPositionUs(123); + SubtitleOutputBuffer outputBuffer = decoder.dequeueOutputBuffer(); + + assertThat(outputBuffer.isEndOfStream()).isTrue(); + } + private static byte[] createPacket(int header, int cc1, int cc2) { return new byte[] { UnsignedBytes.checkedCast(header),