From e11e484bc364a5f318dbec466839402bcfa009aa Mon Sep 17 00:00:00 2001 From: jbibik Date: Thu, 20 Jul 2023 15:52:39 +0100 Subject: [PATCH] Do not emit empty cues in SsaParser It is not part of the `SubtitleParser` interface's promise to give events for all changes to do with `Cue` objects. So while in the past, we would have `endTimeUs` of one Cue event being the `startTimeUs` of the next one, now we have that encoded in `durationUs` and can skip event with empty `Cues`. PiperOrigin-RevId: 549629157 --- .../media3/extractor/text/ssa/SsaParser.java | 5 + .../extractor/text/ssa/SsaParserTest.java | 135 ++++++++---------- .../overlapping_ssa_in_mkv.0.dump | 18 +-- .../overlapping_ssa_in_mkv.1.dump | 18 +-- .../overlapping_ssa_in_mkv.2.dump | 18 +-- .../overlapping_ssa_in_mkv.3.dump | 18 +-- ...overlapping_ssa_in_mkv.unknown_length.dump | 18 +-- .../subtitle_transcoding/ssa_in_mkv.0.dump | 8 +- .../subtitle_transcoding/ssa_in_mkv.1.dump | 8 +- .../subtitle_transcoding/ssa_in_mkv.2.dump | 8 +- .../subtitle_transcoding/ssa_in_mkv.3.dump | 8 +- .../ssa_in_mkv.unknown_length.dump | 8 +- ...le_with_overlapping_ssa_subtitles.mkv.dump | 14 +- 13 files changed, 96 insertions(+), 188 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java index 46c8f17a48..b7b74b91e2 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java @@ -138,6 +138,11 @@ public final class SsaParser implements SubtitleParser { ImmutableList.Builder cuesWithStartTimeAndDuration = ImmutableList.builder(); for (int i = 0; i < cues.size(); i++) { List cuesForThisStartTime = cues.get(i); + if (cuesForThisStartTime.isEmpty() && i != 0) { + // An empty cue list has already been implicitly encoded in the duration of the previous + // sample (unless there was no previous sample). + continue; + } long startTimeUs = startTimesUs.get(i); // The duration of the last CuesWithTiming is C.TIME_UNSET by design long durationUs = diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/text/ssa/SsaParserTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/text/ssa/SsaParserTest.java index 0d83c8fa6f..60945b9363 100644 --- a/libraries/extractor/src/test/java/androidx/media3/extractor/text/ssa/SsaParserTest.java +++ b/libraries/extractor/src/test/java/androidx/media3/extractor/text/ssa/SsaParserTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.graphics.Color; import android.text.Layout; import android.text.Spanned; -import androidx.media3.common.C; import androidx.media3.common.text.Cue; import androidx.media3.extractor.text.CuesWithTiming; import androidx.media3.test.utils.TestUtil; @@ -77,7 +76,7 @@ public final class SsaParserTest { TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), EMPTY_STYLE_LINE); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(2); + assertThat(allCues).hasSize(1); Cue cue = Iterables.getOnlyElement(allCues.get(0).cues); SpannedSubject.assertThat((Spanned) cue.text).hasNoSpans(); assertThat(cue.textSize).isEqualTo(Cue.DIMEN_UNSET); @@ -97,7 +96,7 @@ public final class SsaParserTest { byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TYPICAL); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(6); + assertThat(allCues).hasSize(3); // Check position, line, anchors & alignment are set from Alignment Style (2 - bottom-center). Cue firstCue = allCues.get(0).cues.get(0); assertWithMessage("Cue.textAlignment") @@ -112,8 +111,8 @@ public final class SsaParserTest { assertThat(firstCue.line).isEqualTo(0.95f); assertTypicalCue1(allCues.get(0)); - assertTypicalCue2(allCues.get(2)); - assertTypicalCue3(allCues.get(4)); + assertTypicalCue2(allCues.get(1)); + assertTypicalCue3(allCues.get(2)); } @Test @@ -130,10 +129,10 @@ public final class SsaParserTest { TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TYPICAL_DIALOGUE_ONLY); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(6); + assertThat(allCues).hasSize(3); assertTypicalCue1(allCues.get(0)); - assertTypicalCue2(allCues.get(2)); - assertTypicalCue3(allCues.get(4)); + assertTypicalCue2(allCues.get(1)); + assertTypicalCue3(allCues.get(2)); } @Test @@ -152,13 +151,13 @@ public final class SsaParserTest { ImmutableList allCues = parser.parse(bytes, /* offset= */ 10, /* length= */ bytes.length - 30); - assertThat(allCues).hasSize(4); + assertThat(allCues).hasSize(2); // Because of the offset, we skip the first line of dialogue assertTypicalCue2(allCues.get(0)); // Because of the length restriction, we only partially parse the third line of dialogue - assertThat(allCues.get(2).startTimeUs).isEqualTo(4560000); - assertThat(allCues.get(2).durationUs).isEqualTo(8900000 - 4560000); - assertThat(allCues.get(2).cues.get(0).text.toString()).isEqualTo("This is the third subt"); + assertThat(allCues.get(1).startTimeUs).isEqualTo(4560000); + assertThat(allCues.get(1).durationUs).isEqualTo(8900000 - 4560000); + assertThat(allCues.get(1).cues.get(0).text.toString()).isEqualTo("This is the third subt"); } @Test @@ -168,7 +167,7 @@ public final class SsaParserTest { TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TYPICAL_UTF16LE); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(6); + assertThat(allCues).hasSize(3); // Check position, line, anchors & alignment are set from Alignment Style (2 - bottom-center). Cue firstCue = allCues.get(0).cues.get(0); assertWithMessage("Cue.textAlignment") @@ -183,8 +182,8 @@ public final class SsaParserTest { assertThat(firstCue.line).isEqualTo(0.95f); assertTypicalCue1(allCues.get(0)); - assertTypicalCue2(allCues.get(2)); - assertTypicalCue3(allCues.get(4)); + assertTypicalCue2(allCues.get(1)); + assertTypicalCue3(allCues.get(2)); } @Test @@ -194,7 +193,7 @@ public final class SsaParserTest { TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TYPICAL_UTF16BE); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(6); + assertThat(allCues).hasSize(3); // Check position, line, anchors & alignment are set from Alignment Style (2 - bottom-center). Cue firstCue = allCues.get(0).cues.get(0); assertWithMessage("Cue.textAlignment") @@ -209,8 +208,8 @@ public final class SsaParserTest { assertThat(firstCue.line).isEqualTo(0.95f); assertTypicalCue1(allCues.get(0)); - assertTypicalCue2(allCues.get(2)); - assertTypicalCue3(allCues.get(4)); + assertTypicalCue2(allCues.get(1)); + assertTypicalCue3(allCues.get(2)); } @Test @@ -228,7 +227,7 @@ public final class SsaParserTest { String sixthSubtitleText = "Sixth subtitle - fully encompasses seventh"; String seventhSubtitleText = "Seventh subtitle - nested fully inside sixth"; - assertThat(allCues).hasSize(11); + assertThat(allCues).hasSize(8); assertThat(allCues.get(0).startTimeUs).isEqualTo(1_000_000); assertThat(allCues.get(0).durationUs).isEqualTo(1_000_000); assertThat(Iterables.transform(allCues.get(0).cues, cue -> cue.text.toString())) @@ -244,42 +243,30 @@ public final class SsaParserTest { assertThat(Iterables.transform(allCues.get(2).cues, cue -> cue.text.toString())) .containsExactly(secondSubtitleText); - assertThat(allCues.get(3).startTimeUs).isEqualTo(5_230_000); - assertThat(allCues.get(3).durationUs).isEqualTo(770_000); - assertThat(allCues.get(3).cues).isEmpty(); - - assertThat(allCues.get(4).startTimeUs).isEqualTo(6_000_000); - assertThat(allCues.get(4).durationUs).isEqualTo(2_440_000); - assertThat(Iterables.transform(allCues.get(4).cues, cue -> cue.text.toString())) + assertThat(allCues.get(3).startTimeUs).isEqualTo(6_000_000); + assertThat(allCues.get(3).durationUs).isEqualTo(2_440_000); + assertThat(Iterables.transform(allCues.get(3).cues, cue -> cue.text.toString())) .containsExactly(thirdSubtitleText); - assertThat(allCues.get(5).startTimeUs).isEqualTo(8_440_000); - assertThat(allCues.get(5).durationUs).isEqualTo(1_000_000); - assertThat(Iterables.transform(allCues.get(5).cues, cue -> cue.text.toString())) + assertThat(allCues.get(4).startTimeUs).isEqualTo(8_440_000); + assertThat(allCues.get(4).durationUs).isEqualTo(1_000_000); + assertThat(Iterables.transform(allCues.get(4).cues, cue -> cue.text.toString())) .containsExactly(fourthSubtitleText, fifthSubtitleText); - assertThat(allCues.get(6).startTimeUs).isEqualTo(9_440_000); - assertThat(allCues.get(6).durationUs).isEqualTo(1_280_000); - assertThat(allCues.get(6).cues).isEmpty(); - - assertThat(allCues.get(7).startTimeUs).isEqualTo(10_720_000); - assertThat(allCues.get(7).durationUs).isEqualTo(2_500_000); - assertThat(Iterables.transform(allCues.get(7).cues, cue -> cue.text.toString())) + assertThat(allCues.get(5).startTimeUs).isEqualTo(10_720_000); + assertThat(allCues.get(5).durationUs).isEqualTo(2_500_000); + assertThat(Iterables.transform(allCues.get(5).cues, cue -> cue.text.toString())) .containsExactly(sixthSubtitleText); - assertThat(allCues.get(8).startTimeUs).isEqualTo(13_220_000); - assertThat(allCues.get(8).durationUs).isEqualTo(1_000_000); - assertThat(Iterables.transform(allCues.get(8).cues, cue -> cue.text.toString())) + assertThat(allCues.get(6).startTimeUs).isEqualTo(13_220_000); + assertThat(allCues.get(6).durationUs).isEqualTo(1_000_000); + assertThat(Iterables.transform(allCues.get(6).cues, cue -> cue.text.toString())) .containsExactly(sixthSubtitleText, seventhSubtitleText); - assertThat(allCues.get(9).startTimeUs).isEqualTo(14_220_000); - assertThat(allCues.get(9).durationUs).isEqualTo(1_430_000); - assertThat(Iterables.transform(allCues.get(9).cues, cue -> cue.text.toString())) + assertThat(allCues.get(7).startTimeUs).isEqualTo(14_220_000); + assertThat(allCues.get(7).durationUs).isEqualTo(1_430_000); + assertThat(Iterables.transform(allCues.get(7).cues, cue -> cue.text.toString())) .containsExactly(sixthSubtitleText); - - assertThat(allCues.get(10).startTimeUs).isEqualTo(15_650_000); - assertThat(allCues.get(10).durationUs).isEqualTo(C.TIME_UNSET); - assertThat(allCues.get(10).cues).isEmpty(); } @Test @@ -295,22 +282,22 @@ public final class SsaParserTest { assertThat(firstCue.line).isEqualTo(0.25f); // Check the \pos() doesn't need to be at the start of the line. - Cue secondCue = Iterables.getOnlyElement(allCues.get(2).cues); + Cue secondCue = Iterables.getOnlyElement(allCues.get(1).cues); assertThat(secondCue.position).isEqualTo(0.25f); assertThat(secondCue.line).isEqualTo(0.25f); // Check only the last \pos() value is used. - Cue thirdCue = Iterables.getOnlyElement(allCues.get(4).cues); + Cue thirdCue = Iterables.getOnlyElement(allCues.get(2).cues); assertThat(thirdCue.position).isEqualTo(0.25f); // Check \move() is treated as \pos() - Cue fourthCue = Iterables.getOnlyElement(allCues.get(6).cues); + Cue fourthCue = Iterables.getOnlyElement(allCues.get(3).cues); assertThat(fourthCue.position).isEqualTo(0.5f); assertThat(fourthCue.line).isEqualTo(0.25f); // Check alignment override in a separate brace (to bottom-center) affects textAlignment and // both line & position anchors. - Cue fifthCue = Iterables.getOnlyElement(allCues.get(8).cues); + Cue fifthCue = Iterables.getOnlyElement(allCues.get(4).cues); assertThat(fifthCue.position).isEqualTo(0.5f); assertThat(fifthCue.line).isEqualTo(0.5f); assertWithMessage("Cue.positionAnchor") @@ -323,7 +310,7 @@ public final class SsaParserTest { // Check alignment override in the same brace (to top-right) affects textAlignment and both line // & position anchors. - Cue sixthCue = Iterables.getOnlyElement(allCues.get(10).cues); + Cue sixthCue = Iterables.getOnlyElement(allCues.get(5).cues); assertThat(sixthCue.position).isEqualTo(0.5f); assertThat(sixthCue.line).isEqualTo(0.5f); assertWithMessage("Cue.positionAnchor") @@ -349,13 +336,13 @@ public final class SsaParserTest { assertThat(firstCue.line).isEqualTo(0.5f); // Negative parameter to \move() - fall back to the positions implied by middle-left alignment. - Cue secondCue = Iterables.getOnlyElement(allCues.get(2).cues); + Cue secondCue = Iterables.getOnlyElement(allCues.get(1).cues); assertThat(secondCue.position).isEqualTo(0.05f); assertThat(secondCue.lineType).isEqualTo(Cue.LINE_TYPE_FRACTION); assertThat(secondCue.line).isEqualTo(0.5f); // Check invalid alignment override (11) is skipped and style-provided one is used (4). - Cue thirdCue = Iterables.getOnlyElement(allCues.get(4).cues); + Cue thirdCue = Iterables.getOnlyElement(allCues.get(2).cues); assertWithMessage("Cue.positionAnchor") .that(thirdCue.positionAnchor) .isEqualTo(Cue.ANCHOR_TYPE_START); @@ -365,7 +352,7 @@ public final class SsaParserTest { .isEqualTo(Layout.Alignment.ALIGN_NORMAL); // No braces - fall back to the positions implied by middle-left alignment - Cue fourthCue = Iterables.getOnlyElement(allCues.get(6).cues); + Cue fourthCue = Iterables.getOnlyElement(allCues.get(3).cues); assertThat(fourthCue.position).isEqualTo(0.05f); assertThat(fourthCue.lineType).isEqualTo(Cue.LINE_TYPE_FRACTION); assertThat(fourthCue.line).isEqualTo(0.5f); @@ -395,8 +382,8 @@ public final class SsaParserTest { TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), INVALID_TIMECODES); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(2); - assertTypicalCue3(allCues.get(0)); + assertThat(allCues).hasSize(1); + assertTypicalCue3(Iterables.getOnlyElement(allCues)); } @Test @@ -405,38 +392,38 @@ public final class SsaParserTest { byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_PRIMARY_COLOR); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(14); + assertThat(allCues).hasSize(7); // &H000000FF (AABBGGRR) -> #FFFF0000 (AARRGGBB) Spanned firstCueText = (Spanned) Iterables.getOnlyElement(allCues.get(0).cues).text; SpannedSubject.assertThat(firstCueText) .hasForegroundColorSpanBetween(0, firstCueText.length()) .withColor(Color.RED); // &H0000FFFF (AABBGGRR) -> #FFFFFF00 (AARRGGBB) - Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(2).cues).text; + Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(1).cues).text; SpannedSubject.assertThat(secondCueText) .hasForegroundColorSpanBetween(0, secondCueText.length()) .withColor(Color.YELLOW); // &HFF00 (GGRR) -> #FF00FF00 (AARRGGBB) - Spanned thirdCueText = (Spanned) Iterables.getOnlyElement(allCues.get(4).cues).text; + Spanned thirdCueText = (Spanned) Iterables.getOnlyElement(allCues.get(2).cues).text; SpannedSubject.assertThat(thirdCueText) .hasForegroundColorSpanBetween(0, thirdCueText.length()) .withColor(Color.GREEN); // &HA00000FF (AABBGGRR) -> #5FFF0000 (AARRGGBB) - Spanned fourthCueText = (Spanned) Iterables.getOnlyElement(allCues.get(6).cues).text; + Spanned fourthCueText = (Spanned) Iterables.getOnlyElement(allCues.get(3).cues).text; SpannedSubject.assertThat(fourthCueText) .hasForegroundColorSpanBetween(0, fourthCueText.length()) .withColor(0x5FFF0000); // 16711680 (AABBGGRR) -> &H00FF0000 (AABBGGRR) -> #FF0000FF (AARRGGBB) - Spanned fifthCueText = (Spanned) Iterables.getOnlyElement(allCues.get(8).cues).text; + Spanned fifthCueText = (Spanned) Iterables.getOnlyElement(allCues.get(4).cues).text; SpannedSubject.assertThat(fifthCueText) .hasForegroundColorSpanBetween(0, fifthCueText.length()) .withColor(0xFF0000FF); // 2164195328 (AABBGGRR) -> &H80FF0000 (AABBGGRR) -> #7F0000FF (AARRGGBB) - Spanned sixthCueText = (Spanned) Iterables.getOnlyElement(allCues.get(10).cues).text; + Spanned sixthCueText = (Spanned) Iterables.getOnlyElement(allCues.get(5).cues).text; SpannedSubject.assertThat(sixthCueText) .hasForegroundColorSpanBetween(0, sixthCueText.length()) .withColor(0x7F0000FF); - Spanned seventhCueText = (Spanned) Iterables.getOnlyElement(allCues.get(12).cues).text; + Spanned seventhCueText = (Spanned) Iterables.getOnlyElement(allCues.get(6).cues).text; SpannedSubject.assertThat(seventhCueText) .hasNoForegroundColorSpanBetween(0, seventhCueText.length()); } @@ -447,14 +434,14 @@ public final class SsaParserTest { byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_OUTLINE_COLOR); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(4); + assertThat(allCues).hasSize(2); Spanned firstCueText = (Spanned) Iterables.getOnlyElement(allCues.get(0).cues).text; SpannedSubject.assertThat(firstCueText) .hasBackgroundColorSpanBetween(0, firstCueText.length()) .withColor(Color.BLUE); // OutlineColour should be treated as background only when BorderStyle=3 - Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(2).cues).text; + Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(1).cues).text; SpannedSubject.assertThat(secondCueText) .hasNoBackgroundColorSpanBetween(0, secondCueText.length()); } @@ -465,12 +452,12 @@ public final class SsaParserTest { byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_FONT_SIZE); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(4); + assertThat(allCues).hasSize(2); Cue firstCue = Iterables.getOnlyElement(allCues.get(0).cues); assertThat(firstCue.textSize).isWithin(1.0e-8f).of(30f / 720f); assertThat(firstCue.textSizeType).isEqualTo(Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING); - Cue secondCue = Iterables.getOnlyElement(allCues.get(2).cues); + Cue secondCue = Iterables.getOnlyElement(allCues.get(1).cues); assertThat(secondCue.textSize).isWithin(1.0e-8f).of(72.2f / 720f); assertThat(secondCue.textSizeType).isEqualTo(Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING); } @@ -481,13 +468,13 @@ public final class SsaParserTest { byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_BOLD_ITALIC); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(6); + assertThat(allCues).hasSize(3); Spanned firstCueText = (Spanned) Iterables.getOnlyElement(allCues.get(0).cues).text; SpannedSubject.assertThat(firstCueText).hasBoldSpanBetween(0, firstCueText.length()); - Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(2).cues).text; + Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(1).cues).text; SpannedSubject.assertThat(secondCueText).hasItalicSpanBetween(0, secondCueText.length()); - Spanned thirdCueText = (Spanned) Iterables.getOnlyElement(allCues.get(4).cues).text; + Spanned thirdCueText = (Spanned) Iterables.getOnlyElement(allCues.get(2).cues).text; SpannedSubject.assertThat(thirdCueText).hasBoldItalicSpanBetween(0, thirdCueText.length()); } @@ -497,11 +484,11 @@ public final class SsaParserTest { byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_UNDERLINE); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(4); + assertThat(allCues).hasSize(2); Spanned firstCueText = (Spanned) Iterables.getOnlyElement(allCues.get(0).cues).text; SpannedSubject.assertThat(firstCueText).hasUnderlineSpanBetween(0, firstCueText.length()); - Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(2).cues).text; + Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(1).cues).text; SpannedSubject.assertThat(secondCueText).hasNoUnderlineSpanBetween(0, secondCueText.length()); } @@ -511,11 +498,11 @@ public final class SsaParserTest { byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_STRIKEOUT); List allCues = parser.parse(bytes); - assertThat(allCues).hasSize(4); + assertThat(allCues).hasSize(2); Spanned firstCueText = (Spanned) Iterables.getOnlyElement(allCues.get(0).cues).text; SpannedSubject.assertThat(firstCueText).hasStrikethroughSpanBetween(0, firstCueText.length()); - Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(2).cues).text; + Spanned secondCueText = (Spanned) Iterables.getOnlyElement(allCues.get(1).cues).text; SpannedSubject.assertThat(secondCueText) .hasNoStrikethroughSpanBetween(0, secondCueText.length()); } diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.0.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.0.dump index 81e2b277f2..94b4a0ba5e 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.0.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 3746 - sample count = 6 + total output bytes = 3002 + sample count = 3 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -283,23 +283,11 @@ track 3: flags = 1 data = length 997, hash A1198858 sample 1: - time = 330000 - flags = 1 - data = length 248, hash FD751B3 - sample 2: time = 150000 flags = 1 data = length 1002, hash E686A781 - sample 3: - time = 550000 - flags = 1 - data = length 248, hash FD751B3 - sample 4: + sample 2: time = 200000 flags = 1 data = length 1003, hash 27A316D2 - sample 5: - time = 450000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.1.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.1.dump index 81e2b277f2..94b4a0ba5e 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.1.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 3746 - sample count = 6 + total output bytes = 3002 + sample count = 3 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -283,23 +283,11 @@ track 3: flags = 1 data = length 997, hash A1198858 sample 1: - time = 330000 - flags = 1 - data = length 248, hash FD751B3 - sample 2: time = 150000 flags = 1 data = length 1002, hash E686A781 - sample 3: - time = 550000 - flags = 1 - data = length 248, hash FD751B3 - sample 4: + sample 2: time = 200000 flags = 1 data = length 1003, hash 27A316D2 - sample 5: - time = 450000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.2.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.2.dump index 81e2b277f2..94b4a0ba5e 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.2.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 3746 - sample count = 6 + total output bytes = 3002 + sample count = 3 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -283,23 +283,11 @@ track 3: flags = 1 data = length 997, hash A1198858 sample 1: - time = 330000 - flags = 1 - data = length 248, hash FD751B3 - sample 2: time = 150000 flags = 1 data = length 1002, hash E686A781 - sample 3: - time = 550000 - flags = 1 - data = length 248, hash FD751B3 - sample 4: + sample 2: time = 200000 flags = 1 data = length 1003, hash 27A316D2 - sample 5: - time = 450000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.3.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.3.dump index 81e2b277f2..94b4a0ba5e 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.3.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.3.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 3746 - sample count = 6 + total output bytes = 3002 + sample count = 3 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -283,23 +283,11 @@ track 3: flags = 1 data = length 997, hash A1198858 sample 1: - time = 330000 - flags = 1 - data = length 248, hash FD751B3 - sample 2: time = 150000 flags = 1 data = length 1002, hash E686A781 - sample 3: - time = 550000 - flags = 1 - data = length 248, hash FD751B3 - sample 4: + sample 2: time = 200000 flags = 1 data = length 1003, hash 27A316D2 - sample 5: - time = 450000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.unknown_length.dump index 81e2b277f2..94b4a0ba5e 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/overlapping_ssa_in_mkv.unknown_length.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 3746 - sample count = 6 + total output bytes = 3002 + sample count = 3 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -283,23 +283,11 @@ track 3: flags = 1 data = length 997, hash A1198858 sample 1: - time = 330000 - flags = 1 - data = length 248, hash FD751B3 - sample 2: time = 150000 flags = 1 data = length 1002, hash E686A781 - sample 3: - time = 550000 - flags = 1 - data = length 248, hash FD751B3 - sample 4: + sample 2: time = 200000 flags = 1 data = length 1003, hash 27A316D2 - sample 5: - time = 450000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.0.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.0.dump index 3f55dc346c..4d8153458d 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.0.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 1528 - sample count = 2 + total output bytes = 1280 + sample count = 1 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -282,8 +282,4 @@ track 3: time = 0 flags = 1 data = length 1280, hash EEF152A1 - sample 1: - time = 500000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.1.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.1.dump index 3f55dc346c..4d8153458d 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.1.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 1528 - sample count = 2 + total output bytes = 1280 + sample count = 1 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -282,8 +282,4 @@ track 3: time = 0 flags = 1 data = length 1280, hash EEF152A1 - sample 1: - time = 500000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.2.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.2.dump index 3f55dc346c..4d8153458d 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.2.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 1528 - sample count = 2 + total output bytes = 1280 + sample count = 1 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -282,8 +282,4 @@ track 3: time = 0 flags = 1 data = length 1280, hash EEF152A1 - sample 1: - time = 500000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.3.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.3.dump index 3f55dc346c..4d8153458d 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.3.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.3.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 1528 - sample count = 2 + total output bytes = 1280 + sample count = 1 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -282,8 +282,4 @@ track 3: time = 0 flags = 1 data = length 1280, hash EEF152A1 - sample 1: - time = 500000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.unknown_length.dump index 3f55dc346c..4d8153458d 100644 --- a/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/subtitle_transcoding/ssa_in_mkv.unknown_length.dump @@ -267,8 +267,8 @@ track 2: flags = 1 data = length 418, hash 56AB8D37 track 3: - total output bytes = 1528 - sample count = 2 + total output bytes = 1280 + sample count = 1 format 0: id = 3 sampleMimeType = text/x-exoplayer-cues @@ -282,8 +282,4 @@ track 3: time = 0 flags = 1 data = length 1280, hash EEF152A1 - sample 1: - time = 500000 - flags = 1 - data = length 248, hash FD751B3 tracksEnded = true diff --git a/libraries/test_data/src/test/assets/playbackdumps/mkv/sample_with_overlapping_ssa_subtitles.mkv.dump b/libraries/test_data/src/test/assets/playbackdumps/mkv/sample_with_overlapping_ssa_subtitles.mkv.dump index 234a3d17e8..645ee825ef 100644 --- a/libraries/test_data/src/test/assets/playbackdumps/mkv/sample_with_overlapping_ssa_subtitles.mkv.dump +++ b/libraries/test_data/src/test/assets/playbackdumps/mkv/sample_with_overlapping_ssa_subtitles.mkv.dump @@ -532,19 +532,15 @@ TextOutput: text = First subtitle - end overlaps second lineType = 0 Subtitle[2]: - presentationTimeUs = 330000 - Cues = [] - Subtitle[3]: presentationTimeUs = 150000 Cue[0]: text = Third subtitle - fully encompasses second lineType = 0 + Subtitle[3]: + presentationTimeUs = 200000 + Cue[0]: + text = Second subtitle - beginning overlaps first + lineType = 0 Subtitle[4]: - presentationTimeUs = 550000 - Cues = [] - Subtitle[5]: - presentationTimeUs = 450000 - Cues = [] - Subtitle[6]: presentationTimeUs = 450000 Cues = []