handle meta atom as a full box when parsing mp4

Issues: #5698, #5694
PiperOrigin-RevId: 241762106
This commit is contained in:
bachinger 2019-04-03 18:46:57 +01:00 committed by Oliver Woodman
parent 95f65e5258
commit b10f4023f0
2 changed files with 32 additions and 0 deletions

View File

@ -96,6 +96,9 @@
* Use full BCP 47 language tags in `Format`.
* Take byte offset into account when unsynchronizing an id3 frame
([#5673](https://github.com/google/ExoPlayer/issues/5673)).
* Handle meta atom as a full box when parsing mp4
([#5698](https://github.com/google/ExoPlayer/issues/5698),
[#5694](https://github.com/google/ExoPlayer/issues/5694)).
### 2.9.6 ###

View File

@ -309,6 +309,9 @@ public final class Mp4Extractor implements Extractor, SeekMap {
if (atomSize == atomHeaderBytesRead) {
processAtomEnded(endPosition);
} else {
if (atomType == Atom.TYPE_meta) {
maybeSkipRemainingMetaAtomHeaderBytes(input);
}
// Start reading the first child atom.
enterReadingAtomHeaderState();
}
@ -643,6 +646,32 @@ public final class Mp4Extractor implements Extractor, SeekMap {
}
}
/**
* Possibly skips the version and flags fields (1+3 byte) of a full meta atom of the {@code
* input}.
*
* <p>Atoms of type {@link Atom#TYPE_meta} are defined to be full atoms which have four additional
* bytes for a version and a flags field (see 4.2 'Object Structure' in ISO/IEC 14496-12:2005).
* QuickTime do not have such a full box structure. Since some of these files are encoded wrongly,
* we can't rely on the file type though. Instead we must check the 8 bytes after the common
* header bytes ourselves.
*/
private void maybeSkipRemainingMetaAtomHeaderBytes(ExtractorInput input)
throws IOException, InterruptedException {
scratch.reset(8);
// Peek the next 8 bytes which can be either
// (iso) [1 byte version + 3 bytes flags][4 byte size of next atom]
// (qt) [4 byte size of next atom ][4 byte hdlr atom type ]
// In case of (iso) we need to skip the next 4 bytes.
input.peekFully(scratch.data, 0, 8);
scratch.skipBytes(4);
if (scratch.readInt() == Atom.TYPE_hdlr) {
input.resetPeekPosition();
} else {
input.skipFully(4);
}
}
/**
* For each sample of each track, calculates accumulated size of all samples which need to be read
* before this sample can be used.