Remove AtomParsers from extractors nullness exclusion list

PiperOrigin-RevId: 322131697
This commit is contained in:
kimvde 2020-07-20 14:33:19 +01:00 committed by Oliver Woodman
parent ecc834d704
commit ee222f7027

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.extractor.mp4; package com.google.android.exoplayer2.extractor.mp4;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.MimeTypes.getMimeTypeFromMp4ObjectType; import static com.google.android.exoplayer2.util.MimeTypes.getMimeTypeFromMp4ObjectType;
import android.util.Pair; import android.util.Pair;
@ -104,7 +105,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Nullable DrmInitData drmInitData, @Nullable DrmInitData drmInitData,
boolean ignoreEditLists, boolean ignoreEditLists,
boolean isQuickTime, boolean isQuickTime,
Function<Track, Track> modifyTrackFunction) Function<@NullableType Track, @NullableType Track> modifyTrackFunction)
throws ParserException { throws ParserException {
List<TrackSampleTable> trackSampleTables = new ArrayList<>(); List<TrackSampleTable> trackSampleTables = new ArrayList<>();
for (int i = 0; i < moov.containerChildren.size(); i++) { for (int i = 0; i < moov.containerChildren.size(); i++) {
@ -117,7 +118,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
modifyTrackFunction.apply( modifyTrackFunction.apply(
parseTrak( parseTrak(
atom, atom,
moov.getLeafAtomOfType(Atom.TYPE_mvhd), checkNotNull(moov.getLeafAtomOfType(Atom.TYPE_mvhd)),
duration, duration,
drmInitData, drmInitData,
ignoreEditLists, ignoreEditLists,
@ -126,9 +127,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
continue; continue;
} }
Atom.ContainerAtom stblAtom = Atom.ContainerAtom stblAtom =
atom.getContainerAtomOfType(Atom.TYPE_mdia) checkNotNull(
.getContainerAtomOfType(Atom.TYPE_minf) checkNotNull(
.getContainerAtomOfType(Atom.TYPE_stbl); checkNotNull(atom.getContainerAtomOfType(Atom.TYPE_mdia))
.getContainerAtomOfType(Atom.TYPE_minf))
.getContainerAtomOfType(Atom.TYPE_stbl));
TrackSampleTable trackSampleTable = parseStbl(track, stblAtom, gaplessInfoHolder); TrackSampleTable trackSampleTable = parseStbl(track, stblAtom, gaplessInfoHolder);
trackSampleTables.add(trackSampleTable); trackSampleTables.add(trackSampleTable);
} }
@ -241,13 +244,14 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
boolean ignoreEditLists, boolean ignoreEditLists,
boolean isQuickTime) boolean isQuickTime)
throws ParserException { throws ParserException {
Atom.ContainerAtom mdia = trak.getContainerAtomOfType(Atom.TYPE_mdia); Atom.ContainerAtom mdia = checkNotNull(trak.getContainerAtomOfType(Atom.TYPE_mdia));
int trackType = getTrackTypeForHdlr(parseHdlr(mdia.getLeafAtomOfType(Atom.TYPE_hdlr).data)); int trackType =
getTrackTypeForHdlr(parseHdlr(checkNotNull(mdia.getLeafAtomOfType(Atom.TYPE_hdlr)).data));
if (trackType == C.TRACK_TYPE_UNKNOWN) { if (trackType == C.TRACK_TYPE_UNKNOWN) {
return null; return null;
} }
TkhdData tkhdData = parseTkhd(trak.getLeafAtomOfType(Atom.TYPE_tkhd).data); TkhdData tkhdData = parseTkhd(checkNotNull(trak.getLeafAtomOfType(Atom.TYPE_tkhd)).data);
if (duration == C.TIME_UNSET) { if (duration == C.TIME_UNSET) {
duration = tkhdData.duration; duration = tkhdData.duration;
} }
@ -258,12 +262,21 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} else { } else {
durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, movieTimescale); durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, movieTimescale);
} }
Atom.ContainerAtom stbl = mdia.getContainerAtomOfType(Atom.TYPE_minf) Atom.ContainerAtom stbl =
.getContainerAtomOfType(Atom.TYPE_stbl); checkNotNull(
checkNotNull(mdia.getContainerAtomOfType(Atom.TYPE_minf))
.getContainerAtomOfType(Atom.TYPE_stbl));
Pair<Long, String> mdhdData = parseMdhd(mdia.getLeafAtomOfType(Atom.TYPE_mdhd).data); Pair<Long, String> mdhdData =
StsdData stsdData = parseStsd(stbl.getLeafAtomOfType(Atom.TYPE_stsd).data, tkhdData.id, parseMdhd(checkNotNull(mdia.getLeafAtomOfType(Atom.TYPE_mdhd)).data);
tkhdData.rotationDegrees, mdhdData.second, drmInitData, isQuickTime); StsdData stsdData =
parseStsd(
checkNotNull(stbl.getLeafAtomOfType(Atom.TYPE_stsd)).data,
tkhdData.id,
tkhdData.rotationDegrees,
mdhdData.second,
drmInitData,
isQuickTime);
@Nullable long[] editListDurations = null; @Nullable long[] editListDurations = null;
@Nullable long[] editListMediaTimes = null; @Nullable long[] editListMediaTimes = null;
if (!ignoreEditLists) { if (!ignoreEditLists) {
@ -323,13 +336,13 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Nullable Atom.LeafAtom chunkOffsetsAtom = stblAtom.getLeafAtomOfType(Atom.TYPE_stco); @Nullable Atom.LeafAtom chunkOffsetsAtom = stblAtom.getLeafAtomOfType(Atom.TYPE_stco);
if (chunkOffsetsAtom == null) { if (chunkOffsetsAtom == null) {
chunkOffsetsAreLongs = true; chunkOffsetsAreLongs = true;
chunkOffsetsAtom = stblAtom.getLeafAtomOfType(Atom.TYPE_co64); chunkOffsetsAtom = checkNotNull(stblAtom.getLeafAtomOfType(Atom.TYPE_co64));
} }
ParsableByteArray chunkOffsets = chunkOffsetsAtom.data; ParsableByteArray chunkOffsets = chunkOffsetsAtom.data;
// Entries are (chunk number, number of samples per chunk, sample description index). // Entries are (chunk number, number of samples per chunk, sample description index).
ParsableByteArray stsc = stblAtom.getLeafAtomOfType(Atom.TYPE_stsc).data; ParsableByteArray stsc = checkNotNull(stblAtom.getLeafAtomOfType(Atom.TYPE_stsc)).data;
// Entries are (number of samples, timestamp delta between those samples). // Entries are (number of samples, timestamp delta between those samples).
ParsableByteArray stts = stblAtom.getLeafAtomOfType(Atom.TYPE_stts).data; ParsableByteArray stts = checkNotNull(stblAtom.getLeafAtomOfType(Atom.TYPE_stts)).data;
// Entries are the indices of samples that are synchronization samples. // Entries are the indices of samples that are synchronization samples.
@Nullable Atom.LeafAtom stssAtom = stblAtom.getLeafAtomOfType(Atom.TYPE_stss); @Nullable Atom.LeafAtom stssAtom = stblAtom.getLeafAtomOfType(Atom.TYPE_stss);
@Nullable ParsableByteArray stss = stssAtom != null ? stssAtom.data : null; @Nullable ParsableByteArray stss = stssAtom != null ? stssAtom.data : null;
@ -454,7 +467,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
flags[i] = C.BUFFER_FLAG_KEY_FRAME; flags[i] = C.BUFFER_FLAG_KEY_FRAME;
remainingSynchronizationSamples--; remainingSynchronizationSamples--;
if (remainingSynchronizationSamples > 0) { if (remainingSynchronizationSamples > 0) {
nextSynchronizationSampleIndex = stss.readUnsignedIntToInt() - 1; nextSynchronizationSampleIndex = checkNotNull(stss).readUnsignedIntToInt() - 1;
} }
} }
@ -481,13 +494,15 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
// If the stbl's child boxes are not consistent the container is malformed, but the stream may // If the stbl's child boxes are not consistent the container is malformed, but the stream may
// still be playable. // still be playable.
boolean isCttsValid = true; boolean isCttsValid = true;
while (remainingTimestampOffsetChanges > 0) { if (ctts != null) {
if (ctts.readUnsignedIntToInt() != 0) { while (remainingTimestampOffsetChanges > 0) {
isCttsValid = false; if (ctts.readUnsignedIntToInt() != 0) {
break; isCttsValid = false;
break;
}
ctts.readInt(); // Ignore offset.
remainingTimestampOffsetChanges--;
} }
ctts.readInt(); // Ignore offset.
remainingTimestampOffsetChanges--;
} }
if (remainingSynchronizationSamples != 0 if (remainingSynchronizationSamples != 0
|| remainingSamplesAtTimestampDelta != 0 || remainingSamplesAtTimestampDelta != 0
@ -530,7 +545,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
if (track.editListDurations.length == 1 if (track.editListDurations.length == 1
&& track.type == C.TRACK_TYPE_AUDIO && track.type == C.TRACK_TYPE_AUDIO
&& timestamps.length >= 2) { && timestamps.length >= 2) {
long editStartTime = track.editListMediaTimes[0]; long editStartTime = checkNotNull(track.editListMediaTimes)[0];
long editEndTime = editStartTime + Util.scaleLargeTimestamp(track.editListDurations[0], long editEndTime = editStartTime + Util.scaleLargeTimestamp(track.editListDurations[0],
track.timescale, track.movieTimescale); track.timescale, track.movieTimescale);
if (canApplyEditWithGaplessInfo(timestamps, duration, editStartTime, editEndTime)) { if (canApplyEditWithGaplessInfo(timestamps, duration, editStartTime, editEndTime)) {
@ -557,7 +572,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
// The current version of the spec leaves handling of an edit with zero segment_duration in // The current version of the spec leaves handling of an edit with zero segment_duration in
// unfragmented files open to interpretation. We handle this as a special case and include all // unfragmented files open to interpretation. We handle this as a special case and include all
// samples in the edit. // samples in the edit.
long editStartTime = track.editListMediaTimes[0]; long editStartTime = checkNotNull(track.editListMediaTimes)[0];
for (int i = 0; i < timestamps.length; i++) { for (int i = 0; i < timestamps.length; i++) {
timestamps[i] = timestamps[i] =
Util.scaleLargeTimestamp( Util.scaleLargeTimestamp(
@ -578,8 +593,9 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
boolean copyMetadata = false; boolean copyMetadata = false;
int[] startIndices = new int[track.editListDurations.length]; int[] startIndices = new int[track.editListDurations.length];
int[] endIndices = new int[track.editListDurations.length]; int[] endIndices = new int[track.editListDurations.length];
long[] editListMediaTimes = checkNotNull(track.editListMediaTimes);
for (int i = 0; i < track.editListDurations.length; i++) { for (int i = 0; i < track.editListDurations.length; i++) {
long editMediaTime = track.editListMediaTimes[i]; long editMediaTime = editListMediaTimes[i];
if (editMediaTime != -1) { if (editMediaTime != -1) {
long editDuration = long editDuration =
Util.scaleLargeTimestamp( Util.scaleLargeTimestamp(
@ -1363,7 +1379,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
// Set the MIME type based on the object type indication (ISO/IEC 14496-1 table 5). // Set the MIME type based on the object type indication (ISO/IEC 14496-1 table 5).
int objectTypeIndication = parent.readUnsignedByte(); int objectTypeIndication = parent.readUnsignedByte();
String mimeType = getMimeTypeFromMp4ObjectType(objectTypeIndication); @Nullable String mimeType = getMimeTypeFromMp4ObjectType(objectTypeIndication);
if (MimeTypes.AUDIO_MPEG.equals(mimeType) if (MimeTypes.AUDIO_MPEG.equals(mimeType)
|| MimeTypes.AUDIO_DTS.equals(mimeType) || MimeTypes.AUDIO_DTS.equals(mimeType)
|| MimeTypes.AUDIO_DTS_HD.equals(mimeType)) { || MimeTypes.AUDIO_DTS_HD.equals(mimeType)) {
@ -1395,8 +1411,9 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
Assertions.checkState(childAtomSize > 0, "childAtomSize should be positive"); Assertions.checkState(childAtomSize > 0, "childAtomSize should be positive");
int childAtomType = parent.readInt(); int childAtomType = parent.readInt();
if (childAtomType == Atom.TYPE_sinf) { if (childAtomType == Atom.TYPE_sinf) {
Pair<Integer, TrackEncryptionBox> result = parseCommonEncryptionSinfFromParent(parent, @Nullable
childPosition, childAtomSize); Pair<Integer, TrackEncryptionBox> result =
parseCommonEncryptionSinfFromParent(parent, childPosition, childAtomSize);
if (result != null) { if (result != null) {
return result; return result;
} }