Skip to content

Commit

Permalink
Avoid throwing an exception for sample default values
Browse files Browse the repository at this point in the history
Allows playback of content when the default value is
not valid, but not used for any samples.

Issue: #7207
PiperOrigin-RevId: 306631376
  • Loading branch information
AquilesCanta authored and icbaker committed Apr 15, 2020
1 parent 91690f0 commit 5092665
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 20 deletions.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
* Remove deprecated members in `DefaultTrackSelector`.
* Add `Player.DeviceComponent` and implement it for `SimpleExoPlayer` so
that the device volume can be controlled by player.
* 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)).
* Text:
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
later).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -665,9 +665,9 @@ private void onEmsgLeafAtomRead(ParsableByteArray atom) {
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,
Expand Down Expand Up @@ -753,8 +753,9 @@ private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> track
}
}

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;
Expand Down Expand Up @@ -874,13 +875,20 @@ private static TrackBundle parseTfhd(
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;
Expand Down Expand Up @@ -913,16 +921,22 @@ private static long parseTfdt(ParsableByteArray tfdt) {
/**
* 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);
Expand All @@ -940,7 +954,7 @@ private static int parseTrun(TrackBundle trackBundle, int index, long decodeTime
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;
Expand Down Expand Up @@ -975,9 +989,10 @@ private static int parseTrun(TrackBundle trackBundle, int index, long decodeTime
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) {
Expand All @@ -1003,6 +1018,13 @@ private static int parseTrun(TrackBundle trackBundle, int index, long decodeTime
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);
Expand Down

0 comments on commit 5092665

Please sign in to comment.