Avoid throwing an exception for sample default values
Allows playback of content when the default value is not valid, but not used for any samples. Issue: #7207 PiperOrigin-RevId: 306631376
This commit is contained in:
parent
bdc0db30fd
commit
2df9491383
@ -1,5 +1,11 @@
|
||||
# Release notes #
|
||||
|
||||
### Next release ###
|
||||
|
||||
* Avoid throwing an exception while parsing fragmented MP4 default sample
|
||||
values where the most-significant bit is set
|
||||
([#7207](https://github.com/google/ExoPlayer/issues/7207)).
|
||||
|
||||
### 2.11.4 (2020-04-08) ###
|
||||
|
||||
* Add `SimpleExoPlayer.setWakeMode` to allow automatic `WifiLock` and `WakeLock`
|
||||
|
@ -664,9 +664,9 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
private static Pair<Integer, DefaultSampleValues> parseTrex(ParsableByteArray trex) {
|
||||
trex.setPosition(Atom.FULL_HEADER_SIZE);
|
||||
int trackId = trex.readInt();
|
||||
int defaultSampleDescriptionIndex = trex.readUnsignedIntToInt() - 1;
|
||||
int defaultSampleDuration = trex.readUnsignedIntToInt();
|
||||
int defaultSampleSize = trex.readUnsignedIntToInt();
|
||||
int defaultSampleDescriptionIndex = trex.readInt() - 1;
|
||||
int defaultSampleDuration = trex.readInt();
|
||||
int defaultSampleSize = trex.readInt();
|
||||
int defaultSampleFlags = trex.readInt();
|
||||
|
||||
return Pair.create(trackId, new DefaultSampleValues(defaultSampleDescriptionIndex,
|
||||
@ -751,8 +751,9 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseTruns(ContainerAtom traf, TrackBundle trackBundle, long decodeTime,
|
||||
@Flags int flags) {
|
||||
private static void parseTruns(
|
||||
ContainerAtom traf, TrackBundle trackBundle, long decodeTime, @Flags int flags)
|
||||
throws ParserException {
|
||||
int trunCount = 0;
|
||||
int totalSampleCount = 0;
|
||||
List<LeafAtom> leafChildren = traf.leafChildren;
|
||||
@ -871,13 +872,20 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
|
||||
int defaultSampleDescriptionIndex =
|
||||
((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
|
||||
? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
|
||||
int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
|
||||
? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
|
||||
int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
|
||||
? tfhd.readUnsignedIntToInt() : defaultSampleValues.size;
|
||||
int defaultSampleFlags = ((atomFlags & 0x20 /* default_sample_flags_present */) != 0)
|
||||
? tfhd.readUnsignedIntToInt() : defaultSampleValues.flags;
|
||||
? tfhd.readInt() - 1
|
||||
: defaultSampleValues.sampleDescriptionIndex;
|
||||
int defaultSampleDuration =
|
||||
((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
|
||||
? tfhd.readInt()
|
||||
: defaultSampleValues.duration;
|
||||
int defaultSampleSize =
|
||||
((atomFlags & 0x10 /* default_sample_size_present */) != 0)
|
||||
? tfhd.readInt()
|
||||
: defaultSampleValues.size;
|
||||
int defaultSampleFlags =
|
||||
((atomFlags & 0x20 /* default_sample_flags_present */) != 0)
|
||||
? tfhd.readInt()
|
||||
: defaultSampleValues.flags;
|
||||
trackBundle.fragment.header = new DefaultSampleValues(defaultSampleDescriptionIndex,
|
||||
defaultSampleDuration, defaultSampleSize, defaultSampleFlags);
|
||||
return trackBundle;
|
||||
@ -910,16 +918,22 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
/**
|
||||
* Parses a trun atom (defined in 14496-12).
|
||||
*
|
||||
* @param trackBundle The {@link TrackBundle} that contains the {@link TrackFragment} into
|
||||
* which parsed data should be placed.
|
||||
* @param trackBundle The {@link TrackBundle} that contains the {@link TrackFragment} into which
|
||||
* parsed data should be placed.
|
||||
* @param index Index of the track run in the fragment.
|
||||
* @param decodeTime The decode time of the first sample in the fragment run.
|
||||
* @param flags Flags to allow any required workaround to be executed.
|
||||
* @param trun The trun atom to decode.
|
||||
* @return The starting position of samples for the next run.
|
||||
*/
|
||||
private static int parseTrun(TrackBundle trackBundle, int index, long decodeTime,
|
||||
@Flags int flags, ParsableByteArray trun, int trackRunStart) {
|
||||
private static int parseTrun(
|
||||
TrackBundle trackBundle,
|
||||
int index,
|
||||
long decodeTime,
|
||||
@Flags int flags,
|
||||
ParsableByteArray trun,
|
||||
int trackRunStart)
|
||||
throws ParserException {
|
||||
trun.setPosition(Atom.HEADER_SIZE);
|
||||
int fullAtom = trun.readInt();
|
||||
int atomFlags = Atom.parseFullAtomFlags(fullAtom);
|
||||
@ -937,7 +951,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
boolean firstSampleFlagsPresent = (atomFlags & 0x04 /* first_sample_flags_present */) != 0;
|
||||
int firstSampleFlags = defaultSampleValues.flags;
|
||||
if (firstSampleFlagsPresent) {
|
||||
firstSampleFlags = trun.readUnsignedIntToInt();
|
||||
firstSampleFlags = trun.readInt();
|
||||
}
|
||||
|
||||
boolean sampleDurationsPresent = (atomFlags & 0x100 /* sample_duration_present */) != 0;
|
||||
@ -972,9 +986,10 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
long cumulativeTime = index > 0 ? fragment.nextFragmentDecodeTime : decodeTime;
|
||||
for (int i = trackRunStart; i < trackRunEnd; i++) {
|
||||
// Use trun values if present, otherwise tfhd, otherwise trex.
|
||||
int sampleDuration = sampleDurationsPresent ? trun.readUnsignedIntToInt()
|
||||
: defaultSampleValues.duration;
|
||||
int sampleSize = sampleSizesPresent ? trun.readUnsignedIntToInt() : defaultSampleValues.size;
|
||||
int sampleDuration =
|
||||
checkNonNegative(sampleDurationsPresent ? trun.readInt() : defaultSampleValues.duration);
|
||||
int sampleSize =
|
||||
checkNonNegative(sampleSizesPresent ? trun.readInt() : defaultSampleValues.size);
|
||||
int sampleFlags = (i == 0 && firstSampleFlagsPresent) ? firstSampleFlags
|
||||
: sampleFlagsPresent ? trun.readInt() : defaultSampleValues.flags;
|
||||
if (sampleCompositionTimeOffsetsPresent) {
|
||||
@ -1000,6 +1015,13 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
return trackRunEnd;
|
||||
}
|
||||
|
||||
private static int checkNonNegative(int value) throws ParserException {
|
||||
if (value < 0) {
|
||||
throw new ParserException("Unexpected negtive value: " + value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static void parseUuid(ParsableByteArray uuid, TrackFragment out,
|
||||
byte[] extendedTypeScratch) throws ParserException {
|
||||
uuid.setPosition(Atom.HEADER_SIZE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user