mirror of
https://github.com/androidx/media.git
synced 2025-05-06 23:20:42 +08:00
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 #
|
# 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) ###
|
### 2.11.4 (2020-04-08) ###
|
||||||
|
|
||||||
* Add `SimpleExoPlayer.setWakeMode` to allow automatic `WifiLock` and `WakeLock`
|
* 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) {
|
private static Pair<Integer, DefaultSampleValues> parseTrex(ParsableByteArray trex) {
|
||||||
trex.setPosition(Atom.FULL_HEADER_SIZE);
|
trex.setPosition(Atom.FULL_HEADER_SIZE);
|
||||||
int trackId = trex.readInt();
|
int trackId = trex.readInt();
|
||||||
int defaultSampleDescriptionIndex = trex.readUnsignedIntToInt() - 1;
|
int defaultSampleDescriptionIndex = trex.readInt() - 1;
|
||||||
int defaultSampleDuration = trex.readUnsignedIntToInt();
|
int defaultSampleDuration = trex.readInt();
|
||||||
int defaultSampleSize = trex.readUnsignedIntToInt();
|
int defaultSampleSize = trex.readInt();
|
||||||
int defaultSampleFlags = trex.readInt();
|
int defaultSampleFlags = trex.readInt();
|
||||||
|
|
||||||
return Pair.create(trackId, new DefaultSampleValues(defaultSampleDescriptionIndex,
|
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,
|
private static void parseTruns(
|
||||||
@Flags int flags) {
|
ContainerAtom traf, TrackBundle trackBundle, long decodeTime, @Flags int flags)
|
||||||
|
throws ParserException {
|
||||||
int trunCount = 0;
|
int trunCount = 0;
|
||||||
int totalSampleCount = 0;
|
int totalSampleCount = 0;
|
||||||
List<LeafAtom> leafChildren = traf.leafChildren;
|
List<LeafAtom> leafChildren = traf.leafChildren;
|
||||||
@ -871,13 +872,20 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
|
DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
|
||||||
int defaultSampleDescriptionIndex =
|
int defaultSampleDescriptionIndex =
|
||||||
((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
|
((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
|
||||||
? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
|
? tfhd.readInt() - 1
|
||||||
int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
|
: defaultSampleValues.sampleDescriptionIndex;
|
||||||
? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
|
int defaultSampleDuration =
|
||||||
int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
|
((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
|
||||||
? tfhd.readUnsignedIntToInt() : defaultSampleValues.size;
|
? tfhd.readInt()
|
||||||
int defaultSampleFlags = ((atomFlags & 0x20 /* default_sample_flags_present */) != 0)
|
: defaultSampleValues.duration;
|
||||||
? tfhd.readUnsignedIntToInt() : defaultSampleValues.flags;
|
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,
|
trackBundle.fragment.header = new DefaultSampleValues(defaultSampleDescriptionIndex,
|
||||||
defaultSampleDuration, defaultSampleSize, defaultSampleFlags);
|
defaultSampleDuration, defaultSampleSize, defaultSampleFlags);
|
||||||
return trackBundle;
|
return trackBundle;
|
||||||
@ -910,16 +918,22 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
/**
|
/**
|
||||||
* Parses a trun atom (defined in 14496-12).
|
* Parses a trun atom (defined in 14496-12).
|
||||||
*
|
*
|
||||||
* @param trackBundle The {@link TrackBundle} that contains the {@link TrackFragment} into
|
* @param trackBundle The {@link TrackBundle} that contains the {@link TrackFragment} into which
|
||||||
* which parsed data should be placed.
|
* parsed data should be placed.
|
||||||
* @param index Index of the track run in the fragment.
|
* @param index Index of the track run in the fragment.
|
||||||
* @param decodeTime The decode time of the first sample in the fragment run.
|
* @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 flags Flags to allow any required workaround to be executed.
|
||||||
* @param trun The trun atom to decode.
|
* @param trun The trun atom to decode.
|
||||||
* @return The starting position of samples for the next run.
|
* @return The starting position of samples for the next run.
|
||||||
*/
|
*/
|
||||||
private static int parseTrun(TrackBundle trackBundle, int index, long decodeTime,
|
private static int parseTrun(
|
||||||
@Flags int flags, ParsableByteArray trun, int trackRunStart) {
|
TrackBundle trackBundle,
|
||||||
|
int index,
|
||||||
|
long decodeTime,
|
||||||
|
@Flags int flags,
|
||||||
|
ParsableByteArray trun,
|
||||||
|
int trackRunStart)
|
||||||
|
throws ParserException {
|
||||||
trun.setPosition(Atom.HEADER_SIZE);
|
trun.setPosition(Atom.HEADER_SIZE);
|
||||||
int fullAtom = trun.readInt();
|
int fullAtom = trun.readInt();
|
||||||
int atomFlags = Atom.parseFullAtomFlags(fullAtom);
|
int atomFlags = Atom.parseFullAtomFlags(fullAtom);
|
||||||
@ -937,7 +951,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
boolean firstSampleFlagsPresent = (atomFlags & 0x04 /* first_sample_flags_present */) != 0;
|
boolean firstSampleFlagsPresent = (atomFlags & 0x04 /* first_sample_flags_present */) != 0;
|
||||||
int firstSampleFlags = defaultSampleValues.flags;
|
int firstSampleFlags = defaultSampleValues.flags;
|
||||||
if (firstSampleFlagsPresent) {
|
if (firstSampleFlagsPresent) {
|
||||||
firstSampleFlags = trun.readUnsignedIntToInt();
|
firstSampleFlags = trun.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean sampleDurationsPresent = (atomFlags & 0x100 /* sample_duration_present */) != 0;
|
boolean sampleDurationsPresent = (atomFlags & 0x100 /* sample_duration_present */) != 0;
|
||||||
@ -972,9 +986,10 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
long cumulativeTime = index > 0 ? fragment.nextFragmentDecodeTime : decodeTime;
|
long cumulativeTime = index > 0 ? fragment.nextFragmentDecodeTime : decodeTime;
|
||||||
for (int i = trackRunStart; i < trackRunEnd; i++) {
|
for (int i = trackRunStart; i < trackRunEnd; i++) {
|
||||||
// Use trun values if present, otherwise tfhd, otherwise trex.
|
// Use trun values if present, otherwise tfhd, otherwise trex.
|
||||||
int sampleDuration = sampleDurationsPresent ? trun.readUnsignedIntToInt()
|
int sampleDuration =
|
||||||
: defaultSampleValues.duration;
|
checkNonNegative(sampleDurationsPresent ? trun.readInt() : defaultSampleValues.duration);
|
||||||
int sampleSize = sampleSizesPresent ? trun.readUnsignedIntToInt() : defaultSampleValues.size;
|
int sampleSize =
|
||||||
|
checkNonNegative(sampleSizesPresent ? trun.readInt() : defaultSampleValues.size);
|
||||||
int sampleFlags = (i == 0 && firstSampleFlagsPresent) ? firstSampleFlags
|
int sampleFlags = (i == 0 && firstSampleFlagsPresent) ? firstSampleFlags
|
||||||
: sampleFlagsPresent ? trun.readInt() : defaultSampleValues.flags;
|
: sampleFlagsPresent ? trun.readInt() : defaultSampleValues.flags;
|
||||||
if (sampleCompositionTimeOffsetsPresent) {
|
if (sampleCompositionTimeOffsetsPresent) {
|
||||||
@ -1000,6 +1015,13 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
return trackRunEnd;
|
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,
|
private static void parseUuid(ParsableByteArray uuid, TrackFragment out,
|
||||||
byte[] extendedTypeScratch) throws ParserException {
|
byte[] extendedTypeScratch) throws ParserException {
|
||||||
uuid.setPosition(Atom.HEADER_SIZE);
|
uuid.setPosition(Atom.HEADER_SIZE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user