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:
kimvde 2020-06-29 08:22:40 +01:00 committed by Oliver Woodman
parent c9717f67ea
commit 8e09cf45c0
6 changed files with 26 additions and 22 deletions

View File

@ -374,16 +374,16 @@ public class FragmentedMp4Extractor implements Extractor {
fragment.auxiliaryDataPosition = 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) {
currentTrackBundle = null;
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;
return true;
}

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=1828]]
getPosition(0) = [[timeUs=0, position=1244]]
numberOfTracks = 2
track 0:
total output bytes = 85933

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=1828]]
getPosition(0) = [[timeUs=0, position=1244]]
numberOfTracks = 2
track 0:
total output bytes = 85933

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=1828]]
getPosition(0) = [[timeUs=0, position=1244]]
numberOfTracks = 3
track 0:
total output bytes = 85933

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=1828]]
getPosition(0) = [[timeUs=0, position=1244]]
numberOfTracks = 3
track 0:
total output bytes = 85933

View File

@ -341,21 +341,25 @@ public final class ExtractorAsserts {
extractorOutput.assertOutput(context, dumpFilesPrefix + ".0" + DUMP_EXTENSION);
}
// If the SeekMap is seekable, test seeking in the stream.
SeekMap seekMap = Assertions.checkNotNull(extractorOutput.seekMap);
if (seekMap.isSeekable()) {
long durationUs = seekMap.getDurationUs();
for (int j = 0; j < 4; j++) {
extractorOutput.clearTrackOutputs();
long timeUs = durationUs == C.TIME_UNSET ? 0 : (durationUs * j) / 3;
long position = seekMap.getSeekPoints(timeUs).first.position;
input.reset();
input.setPosition((int) position);
consumeTestData(extractor, input, timeUs, extractorOutput, false);
long durationUs = seekMap.getDurationUs();
// Only seek to the timeUs=0 if the SeekMap is unseekable or the duration is unknown.
int numberSeekTests = seekMap.isSeekable() && durationUs != C.TIME_UNSET ? 4 : 1;
for (int j = 0; j < numberSeekTests; j++) {
long timeUs = durationUs * j / 3;
long position = seekMap.getSeekPoints(timeUs).first.position;
if (timeUs == 0 && position == 0) {
// Already tested.
continue;
}
input.reset();
input.setPosition((int) position);
extractorOutput.clearTrackOutputs();
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);
if (durationUs == C.TIME_UNSET) {
break;
}
}
}
}