Consider udta box as leaf
The MP4 standard considers the udta box as a regular container box. Quicktime, however, considers it as a container (of only leaf atoms) that can have a terminating 32 bit integer with value 0. Since this breaks the principle of not having content in container boxes, this CL considers the udta box as a leaf box that contains other boxes and does the parsing manually. Issue: #1315 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=117237255
This commit is contained in:
parent
bbceb459fd
commit
f5b7ea676d
@ -335,28 +335,46 @@ import java.util.List;
|
||||
* Parses a udta atom.
|
||||
*
|
||||
* @param udtaAtom The udta (user data) atom to parse.
|
||||
* @param isQuickTime True for QuickTime media. False otherwise.
|
||||
* @return Gapless playback information stored in the user data, or {@code null} if not present.
|
||||
*/
|
||||
public static GaplessInfo parseUdta(Atom.ContainerAtom udtaAtom) {
|
||||
Atom.LeafAtom metaAtom = udtaAtom.getLeafAtomOfType(Atom.TYPE_meta);
|
||||
if (metaAtom == null) {
|
||||
public static GaplessInfo parseUdta(Atom.LeafAtom udtaAtom, boolean isQuickTime) {
|
||||
if (isQuickTime) {
|
||||
// Meta boxes are regular boxes rather than full boxes in QuickTime. For now, don't try and
|
||||
// parse one.
|
||||
return null;
|
||||
}
|
||||
ParsableByteArray data = metaAtom.data;
|
||||
data.setPosition(Atom.FULL_HEADER_SIZE);
|
||||
ParsableByteArray udtaData = udtaAtom.data;
|
||||
udtaData.setPosition(Atom.HEADER_SIZE);
|
||||
while (udtaData.bytesLeft() >= Atom.HEADER_SIZE) {
|
||||
int atomSize = udtaData.readInt();
|
||||
int atomType = udtaData.readInt();
|
||||
if (atomType == Atom.TYPE_meta) {
|
||||
udtaData.setPosition(udtaData.getPosition() - Atom.HEADER_SIZE);
|
||||
udtaData.setLimit(udtaData.getPosition() + atomSize);
|
||||
return parseMetaAtom(udtaData);
|
||||
} else {
|
||||
udtaData.skipBytes(atomSize - Atom.HEADER_SIZE);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static GaplessInfo parseMetaAtom(ParsableByteArray data) {
|
||||
data.skipBytes(Atom.FULL_HEADER_SIZE);
|
||||
ParsableByteArray ilst = new ParsableByteArray();
|
||||
while (data.bytesLeft() > 0) {
|
||||
int length = data.readInt() - Atom.HEADER_SIZE;
|
||||
int type = data.readInt();
|
||||
if (type == Atom.TYPE_ilst) {
|
||||
ilst.reset(data.data, data.getPosition() + length);
|
||||
while (data.bytesLeft() >= Atom.HEADER_SIZE) {
|
||||
int payloadSize = data.readInt() - Atom.HEADER_SIZE;
|
||||
int atomType = data.readInt();
|
||||
if (atomType == Atom.TYPE_ilst) {
|
||||
ilst.reset(data.data, data.getPosition() + payloadSize);
|
||||
ilst.setPosition(data.getPosition());
|
||||
GaplessInfo gaplessInfo = parseIlst(ilst);
|
||||
if (gaplessInfo != null) {
|
||||
return gaplessInfo;
|
||||
}
|
||||
}
|
||||
data.skipBytes(length);
|
||||
data.skipBytes(payloadSize);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -293,9 +293,9 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
List<Mp4Track> tracks = new ArrayList<>();
|
||||
long earliestSampleOffset = Long.MAX_VALUE;
|
||||
GaplessInfo gaplessInfo = null;
|
||||
Atom.ContainerAtom udta = moov.getContainerAtomOfType(Atom.TYPE_udta);
|
||||
Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
|
||||
if (udta != null) {
|
||||
gaplessInfo = AtomParsers.parseUdta(udta);
|
||||
gaplessInfo = AtomParsers.parseUdta(udta, isQuickTime);
|
||||
}
|
||||
for (int i = 0; i < moov.containerChildren.size(); i++) {
|
||||
Atom.ContainerAtom atom = moov.containerChildren.get(i);
|
||||
|
Loading…
x
Reference in New Issue
Block a user