Skip to content

Bugfix: Handle seekhead for cues on mkv files. #2254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public static ImmutableList<String> mediaSamples() {
"sample_with_overlapping_srt.mkv",
"sample_with_vtt_subtitles.mkv",
"sample_with_null_terminated_vtt_subtitles.mkv",
"sample_with_vobsub.mkv");
"sample_with_vobsub.mkv",
"sample_recursive_seekhead.mkv");
}

@ParameterizedRobolectricTestRunner.Parameter public String inputFile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,9 @@ public static ExtractorsFactory newFactory(SubtitleParser.Factory subtitleParser

// Cue related elements.
private boolean seekForCues;
private boolean seekForSeekContent;
private long seekPositionAfterSeekingForHead = C.INDEX_UNSET;
private long seekHeadContentPosition = C.INDEX_UNSET;
private long cuesContentPosition = C.INDEX_UNSET;
private long seekPositionAfterBuildingCues = C.INDEX_UNSET;
private long clusterTimecodeUs = C.TIME_UNSET;
Expand Down Expand Up @@ -764,6 +767,10 @@ protected void startMasterElement(int id, long contentPosition, long contentSize
if (seekForCuesEnabled && cuesContentPosition != C.INDEX_UNSET) {
// We know where the Cues element is located. Seek to request it.
seekForCues = true;
} else if (seekForCuesEnabled && seekHeadContentPosition != C.INDEX_UNSET) {
// We do not know where the cues are located, however we have a seek-head entry
// we have not yet visited
seekForSeekContent = true;
} else {
// We don't know where the Cues element is located. It's most likely omitted. Allow
// playback, but disable seeking.
Expand Down Expand Up @@ -816,9 +823,16 @@ protected void endMasterElement(int id) throws ParserException {
if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C.INDEX_UNSET) {
throw ParserException.createForMalformedContainer(
"Mandatory element SeekID or SeekPosition not found", /* cause= */ null);
}
if (seekEntryId == ID_CUES) {
} else if (seekEntryId == ID_SEEK_HEAD) {
seekHeadContentPosition = seekEntryPosition;
} else if (seekEntryId == ID_CUES) {
cuesContentPosition = seekEntryPosition;

// We are currently seeking from the seek-head, so we seek again to get to the cues
// instead of waiting for the cluster
if (seekForCuesEnabled && seekPositionAfterSeekingForHead != C.INDEX_UNSET) {
seekForCues = true;
}
}
break;
case ID_CUES:
Expand Down Expand Up @@ -1936,6 +1950,13 @@ private SeekMap buildSeekMap(
* @return Whether the seek position was updated.
*/
private boolean maybeSeekForCues(PositionHolder seekPosition, long currentPosition) {
if (seekForSeekContent) {
seekPositionAfterSeekingForHead = currentPosition;
seekPosition.position = seekHeadContentPosition;
seekForSeekContent = false;
return true;
}

if (seekForCues) {
seekPositionAfterBuildingCues = currentPosition;
seekPosition.position = cuesContentPosition;
Expand All @@ -1949,6 +1970,16 @@ private boolean maybeSeekForCues(PositionHolder seekPosition, long currentPositi
seekPositionAfterBuildingCues = C.INDEX_UNSET;
return true;
}

// After we have seeked back from seekPositionAfterBuildingCues seek back again to parse the
// rest of the file. This ends the double jump that is preformed when the beginning metadata
// only contains a ID_SEEK_HEAD without a ID_CUES.
if (sentSeekMap && seekPositionAfterSeekingForHead != C.INDEX_UNSET) {
seekPosition.position = seekPositionAfterSeekingForHead;
seekPositionAfterSeekingForHead = C.INDEX_UNSET;
return true;
}

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ public void mkvSample_withNullTerminatedVttSubtitles() throws Exception {
simulationConfig);
}

// https://github.com/androidx/media/issues/1143
@Test
public void mkvSample_withRecursiveSeekHead() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(subtitlesParsedDuringExtraction),
"media/mkv/sample_recursive_seekhead.mkv",
getAssertionConfigWithPrefix(
"media/mkv/sample_recursive_seekhead.mkv", subtitlesParsedDuringExtraction),
simulationConfig);
}

@Test
public void mkvSample_withVorbisAudio() throws Exception {
ExtractorAsserts.assertBehavior(
Expand Down
Binary file not shown.
Loading