Skip to content

Commit

Permalink
Fix issue where a trun atom could be associated with the wrong track
Browse files Browse the repository at this point in the history
Note that this removes a workaround for malformed content, in which the
track_ID is set incorrectly. It's unclear there was sufficient reason to
implement that workaround, and so it's preferable to remove it, rather
than implementing the concept of unrecognized tracks, which would be
needed to keep it and to also fix this issue.

Issue: #9056
PiperOrigin-RevId: 379506261
  • Loading branch information
ojw28 authored and icbaker committed Jul 16, 2021
1 parent 189c52b commit 08dbfd5
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 18 deletions.
8 changes: 8 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
passthrough capability from API 29 onwards, instead of using the HDMI
audio plug intent
([#6500](https://github.com/google/ExoPlayer/pull/6500)).
* Extractors:
* Fix issue where a `trun` atom could be associated with the wrong track
in an FMP4 stream
([#9056](https://github.com/google/ExoPlayer/pull/9056)). The fix
removes a previous workaround to handle content in which the `track_ID`
is set incorrectly
([#4083](https://github.com/google/ExoPlayer/issues/4083)). Such content
is malformed and should be re-encoded.
* UI:
* Add `PendingIntent.FLAG_IMMUTABLE` flag when creating a broadcast intent
in `PlayerNotificationManager`. This is required to avoid an error on
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ private DefaultSampleValues getDefaultSampleValues(
}

private void onMoofContainerAtomRead(ContainerAtom moof) throws ParserException {
parseMoof(moof, trackBundles, flags, scratchBytes);
parseMoof(moof, trackBundles, sideloadedTrack != null, flags, scratchBytes);

@Nullable DrmInitData drmInitData = getDrmInitDataFromAtoms(moof.leafChildren);
if (drmInitData != null) {
Expand Down Expand Up @@ -699,25 +699,27 @@ private static long parseMehd(ParsableByteArray mehd) {
return version == 0 ? mehd.readUnsignedInt() : mehd.readUnsignedLongToLong();
}

private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundles,
boolean haveSideloadedTrack,
@Flags int flags, byte[] extendedTypeScratch) throws ParserException {
int moofContainerChildrenSize = moof.containerChildren.size();
for (int i = 0; i < moofContainerChildrenSize; i++) {
Atom.ContainerAtom child = moof.containerChildren.get(i);
// TODO: Support multiple traf boxes per track in a single moof.
if (child.type == Atom.TYPE_traf) {
parseTraf(child, trackBundleArray, flags, extendedTypeScratch);
parseTraf(child, trackBundles, haveSideloadedTrack, flags, extendedTypeScratch);
}
}
}

/**
* Parses a traf atom (defined in 14496-12).
*/
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray,
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundles,
boolean haveSideloadedTrack,
@Flags int flags, byte[] extendedTypeScratch) throws ParserException {
LeafAtom tfhd = checkNotNull(traf.getLeafAtomOfType(Atom.TYPE_tfhd));
@Nullable TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray);
@Nullable TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundles, haveSideloadedTrack);
if (trackBundle == null) {
return;
}
Expand Down Expand Up @@ -874,17 +876,21 @@ private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws
*
* @param tfhd The tfhd atom to decode.
* @param trackBundles The track bundles, one of which corresponds to the tfhd atom being parsed.
* @param haveSideloadedTrack Whether {@code trackBundles} contains a single bundle corresponding
* to a side-loaded track.
* @return The {@link TrackBundle} to which the {@link TrackFragment} belongs, or null if the tfhd
* does not refer to any {@link TrackBundle}.
*/
@Nullable
private static TrackBundle parseTfhd(
ParsableByteArray tfhd, SparseArray<TrackBundle> trackBundles) {
ParsableByteArray tfhd, SparseArray<TrackBundle> trackBundles, boolean haveSideloadedTrack) {
tfhd.setPosition(Atom.HEADER_SIZE);
int fullAtom = tfhd.readInt();
int atomFlags = Atom.parseFullAtomFlags(fullAtom);
int trackId = tfhd.readInt();
@Nullable TrackBundle trackBundle = getTrackBundle(trackBundles, trackId);
@Nullable
TrackBundle trackBundle =
haveSideloadedTrack ? trackBundles.valueAt(0) : trackBundles.get(trackId);
if (trackBundle == null) {
return null;
}
Expand Down Expand Up @@ -916,17 +922,6 @@ private static TrackBundle parseTfhd(
return trackBundle;
}

private static @Nullable TrackBundle getTrackBundle(
SparseArray<TrackBundle> trackBundles, int trackId) {
if (trackBundles.size() == 1) {
// Ignore track id if there is only one track. This is either because we have a side-loaded
// track or to cope with non-matching track indices (see
// https://github.com/google/ExoPlayer/issues/4083).
return trackBundles.valueAt(/* index= */ 0);
}
return trackBundles.get(trackId);
}

/**
* Parses a tfdt atom (defined in 14496-12).
*
Expand Down

0 comments on commit 08dbfd5

Please sign in to comment.