Fix bug unseekable FMP4
The seek start position was set to the first mdat but this box was always skipped because the moof box was not read. PiperOrigin-RevId: 318762126
This commit is contained in:
parent
c9717f67ea
commit
8e09cf45c0
@ -374,16 +374,16 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
fragment.auxiliaryDataPosition = atomPosition;
|
fragment.auxiliaryDataPosition = atomPosition;
|
||||||
fragment.dataPosition = atomPosition;
|
fragment.dataPosition = atomPosition;
|
||||||
}
|
}
|
||||||
|
if (!haveOutputSeekMap) {
|
||||||
|
// This must be the first moof in the stream.
|
||||||
|
extractorOutput.seekMap(new SeekMap.Unseekable(durationUs, atomPosition));
|
||||||
|
haveOutputSeekMap = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomType == Atom.TYPE_mdat) {
|
if (atomType == Atom.TYPE_mdat) {
|
||||||
currentTrackBundle = null;
|
currentTrackBundle = null;
|
||||||
endOfMdatPosition = atomPosition + atomSize;
|
endOfMdatPosition = atomPosition + atomSize;
|
||||||
if (!haveOutputSeekMap) {
|
|
||||||
// This must be the first mdat in the stream.
|
|
||||||
extractorOutput.seekMap(new SeekMap.Unseekable(durationUs, atomPosition));
|
|
||||||
haveOutputSeekMap = true;
|
|
||||||
}
|
|
||||||
parserState = STATE_READING_ENCRYPTION_DATA;
|
parserState = STATE_READING_ENCRYPTION_DATA;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = false
|
isSeekable = false
|
||||||
duration = UNSET TIME
|
duration = UNSET TIME
|
||||||
getPosition(0) = [[timeUs=0, position=1828]]
|
getPosition(0) = [[timeUs=0, position=1244]]
|
||||||
numberOfTracks = 2
|
numberOfTracks = 2
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 85933
|
total output bytes = 85933
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = false
|
isSeekable = false
|
||||||
duration = UNSET TIME
|
duration = UNSET TIME
|
||||||
getPosition(0) = [[timeUs=0, position=1828]]
|
getPosition(0) = [[timeUs=0, position=1244]]
|
||||||
numberOfTracks = 2
|
numberOfTracks = 2
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 85933
|
total output bytes = 85933
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = false
|
isSeekable = false
|
||||||
duration = UNSET TIME
|
duration = UNSET TIME
|
||||||
getPosition(0) = [[timeUs=0, position=1828]]
|
getPosition(0) = [[timeUs=0, position=1244]]
|
||||||
numberOfTracks = 3
|
numberOfTracks = 3
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 85933
|
total output bytes = 85933
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = false
|
isSeekable = false
|
||||||
duration = UNSET TIME
|
duration = UNSET TIME
|
||||||
getPosition(0) = [[timeUs=0, position=1828]]
|
getPosition(0) = [[timeUs=0, position=1244]]
|
||||||
numberOfTracks = 3
|
numberOfTracks = 3
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 85933
|
total output bytes = 85933
|
||||||
|
@ -341,21 +341,25 @@ public final class ExtractorAsserts {
|
|||||||
extractorOutput.assertOutput(context, dumpFilesPrefix + ".0" + DUMP_EXTENSION);
|
extractorOutput.assertOutput(context, dumpFilesPrefix + ".0" + DUMP_EXTENSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the SeekMap is seekable, test seeking in the stream.
|
|
||||||
SeekMap seekMap = Assertions.checkNotNull(extractorOutput.seekMap);
|
SeekMap seekMap = Assertions.checkNotNull(extractorOutput.seekMap);
|
||||||
if (seekMap.isSeekable()) {
|
|
||||||
long durationUs = seekMap.getDurationUs();
|
long durationUs = seekMap.getDurationUs();
|
||||||
for (int j = 0; j < 4; j++) {
|
// Only seek to the timeUs=0 if the SeekMap is unseekable or the duration is unknown.
|
||||||
extractorOutput.clearTrackOutputs();
|
int numberSeekTests = seekMap.isSeekable() && durationUs != C.TIME_UNSET ? 4 : 1;
|
||||||
long timeUs = durationUs == C.TIME_UNSET ? 0 : (durationUs * j) / 3;
|
for (int j = 0; j < numberSeekTests; j++) {
|
||||||
|
long timeUs = durationUs * j / 3;
|
||||||
long position = seekMap.getSeekPoints(timeUs).first.position;
|
long position = seekMap.getSeekPoints(timeUs).first.position;
|
||||||
|
if (timeUs == 0 && position == 0) {
|
||||||
|
// Already tested.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
input.reset();
|
input.reset();
|
||||||
input.setPosition((int) position);
|
input.setPosition((int) position);
|
||||||
|
extractorOutput.clearTrackOutputs();
|
||||||
consumeTestData(extractor, input, timeUs, extractorOutput, false);
|
consumeTestData(extractor, input, timeUs, extractorOutput, false);
|
||||||
|
if (simulateUnknownLength && timeUs == 0) {
|
||||||
|
extractorOutput.assertOutput(context, dumpFilesPrefix + UNKNOWN_LENGTH_EXTENSION);
|
||||||
|
} else {
|
||||||
extractorOutput.assertOutput(context, dumpFilesPrefix + '.' + j + DUMP_EXTENSION);
|
extractorOutput.assertOutput(context, dumpFilesPrefix + '.' + j + DUMP_EXTENSION);
|
||||||
if (durationUs == C.TIME_UNSET) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user