diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 108026dd7c..2eb40730c9 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -78,6 +78,9 @@ * Add workaround for track index mismatches between trex and tkhd boxes in fragmented MP4 files ([#4477](https://github.com/google/ExoPlayer/issues/4477)). +* Add workaround for track index mismatches between tfhd and tkhd boxes in + fragmented MP4 files + ([#4083](https://github.com/google/ExoPlayer/issues/4083)). ### 2.8.2 ### diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index a61b41dea2..74181f8898 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -654,7 +654,7 @@ public final class FragmentedMp4Extractor implements Extractor { private static void parseTraf(ContainerAtom traf, SparseArray trackBundleArray, @Flags int flags, byte[] extendedTypeScratch) throws ParserException { LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd); - TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray, flags); + TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray); if (trackBundle == null) { return; } @@ -805,13 +805,13 @@ public final class FragmentedMp4Extractor implements Extractor { * @return The {@link TrackBundle} to which the {@link TrackFragment} belongs, or null if the tfhd * does not refer to any {@link TrackBundle}. */ - private static TrackBundle parseTfhd(ParsableByteArray tfhd, - SparseArray trackBundles, int flags) { + private static TrackBundle parseTfhd( + ParsableByteArray tfhd, SparseArray trackBundles) { tfhd.setPosition(Atom.HEADER_SIZE); int fullAtom = tfhd.readInt(); int atomFlags = Atom.parseFullAtomFlags(fullAtom); int trackId = tfhd.readInt(); - TrackBundle trackBundle = trackBundles.get((flags & FLAG_SIDELOADED) == 0 ? trackId : 0); + TrackBundle trackBundle = getTrackBundle(trackBundles, trackId); if (trackBundle == null) { return null; } @@ -836,6 +836,17 @@ public final class FragmentedMp4Extractor implements Extractor { return trackBundle; } + private static @Nullable TrackBundle getTrackBundle( + SparseArray 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 (flag FLAG_SIDELOADED) 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). *