Fix issue where a trun atom could be associated with the wrong track

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
#minor-release
PiperOrigin-RevId: 379506261
This commit is contained in:
olly 2021-06-15 17:27:44 +01:00 committed by Oliver Woodman
parent 391ad7dbb9
commit 4e8895d5cb
2 changed files with 21 additions and 18 deletions

View File

@ -50,6 +50,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.
* Ad playback:
* Support changing ad break positions in the player logic
([#5067](https://github.com/google/ExoPlayer/issues/5067).

View File

@ -556,7 +556,7 @@ public class FragmentedMp4Extractor implements Extractor {
}
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) {
@ -703,7 +703,8 @@ public class FragmentedMp4Extractor implements Extractor {
private static void parseMoof(
ContainerAtom moof,
SparseArray<TrackBundle> trackBundleArray,
SparseArray<TrackBundle> trackBundles,
boolean haveSideloadedTrack,
@Flags int flags,
byte[] extendedTypeScratch)
throws ParserException {
@ -712,7 +713,7 @@ public class FragmentedMp4Extractor implements Extractor {
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);
}
}
}
@ -720,12 +721,13 @@ public class FragmentedMp4Extractor implements Extractor {
/** Parses a traf atom (defined in 14496-12). */
private static void parseTraf(
ContainerAtom traf,
SparseArray<TrackBundle> trackBundleArray,
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;
}
@ -883,17 +885,21 @@ public class FragmentedMp4Extractor implements Extractor {
*
* @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;
}
@ -929,17 +935,6 @@ public class FragmentedMp4Extractor implements Extractor {
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).
*