@@ -456,6 +456,9 @@ public static ExtractorsFactory newFactory(SubtitleParser.Factory subtitleParser
456
456
457
457
// Cue related elements.
458
458
private boolean seekForCues ;
459
+ private boolean seekForSeekContent ;
460
+ private long seekPositionAfterSeekingForHead = C .INDEX_UNSET ;
461
+ private long seekHeadContentPosition = C .INDEX_UNSET ;
459
462
private long cuesContentPosition = C .INDEX_UNSET ;
460
463
private long seekPositionAfterBuildingCues = C .INDEX_UNSET ;
461
464
private long clusterTimecodeUs = C .TIME_UNSET ;
@@ -764,6 +767,10 @@ protected void startMasterElement(int id, long contentPosition, long contentSize
764
767
if (seekForCuesEnabled && cuesContentPosition != C .INDEX_UNSET ) {
765
768
// We know where the Cues element is located. Seek to request it.
766
769
seekForCues = true ;
770
+ } else if (seekForCuesEnabled && seekHeadContentPosition != C .INDEX_UNSET ) {
771
+ // We do not know where the cues are located, however we have a seek-head entry
772
+ // we have not yet visited
773
+ seekForSeekContent = true ;
767
774
} else {
768
775
// We don't know where the Cues element is located. It's most likely omitted. Allow
769
776
// playback, but disable seeking.
@@ -816,9 +823,16 @@ protected void endMasterElement(int id) throws ParserException {
816
823
if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C .INDEX_UNSET ) {
817
824
throw ParserException .createForMalformedContainer (
818
825
"Mandatory element SeekID or SeekPosition not found" , /* cause= */ null );
819
- }
820
- if (seekEntryId == ID_CUES ) {
826
+ } else if (seekEntryId == ID_SEEK_HEAD ) {
827
+ seekHeadContentPosition = seekEntryPosition ;
828
+ } else if (seekEntryId == ID_CUES ) {
821
829
cuesContentPosition = seekEntryPosition ;
830
+
831
+ // We are currently seeking from the seek-head, so we seek again to get to the cues
832
+ // instead of waiting for the cluster
833
+ if (seekForCuesEnabled && seekPositionAfterSeekingForHead != C .INDEX_UNSET ) {
834
+ seekForCues = true ;
835
+ }
822
836
}
823
837
break ;
824
838
case ID_CUES :
@@ -1936,6 +1950,13 @@ private SeekMap buildSeekMap(
1936
1950
* @return Whether the seek position was updated.
1937
1951
*/
1938
1952
private boolean maybeSeekForCues (PositionHolder seekPosition , long currentPosition ) {
1953
+ if (seekForSeekContent ) {
1954
+ seekPositionAfterSeekingForHead = currentPosition ;
1955
+ seekPosition .position = seekHeadContentPosition ;
1956
+ seekForSeekContent = false ;
1957
+ return true ;
1958
+ }
1959
+
1939
1960
if (seekForCues ) {
1940
1961
seekPositionAfterBuildingCues = currentPosition ;
1941
1962
seekPosition .position = cuesContentPosition ;
@@ -1949,6 +1970,16 @@ private boolean maybeSeekForCues(PositionHolder seekPosition, long currentPositi
1949
1970
seekPositionAfterBuildingCues = C .INDEX_UNSET ;
1950
1971
return true ;
1951
1972
}
1973
+
1974
+ // After we have seeked back from seekPositionAfterBuildingCues seek back again to parse the
1975
+ // rest of the file. This ends the double jump that is preformed when the beginning metadata
1976
+ // only contains a ID_SEEK_HEAD without a ID_CUES.
1977
+ if (sentSeekMap && seekPositionAfterSeekingForHead != C .INDEX_UNSET ) {
1978
+ seekPosition .position = seekPositionAfterSeekingForHead ;
1979
+ seekPositionAfterSeekingForHead = C .INDEX_UNSET ;
1980
+ return true ;
1981
+ }
1982
+
1952
1983
return false ;
1953
1984
}
1954
1985
0 commit comments