From f2f149adca2bd9133e9d973d33de2efee0409c2d Mon Sep 17 00:00:00 2001 From: tonihei Date: Fri, 6 Jul 2018 09:16:31 -0700 Subject: [PATCH] Add workaround for unmatched track indices in tkhd and tfhd. If there is only one track, we can assume that both boxes refer to the same track even if the track indices don't match. Issue:#4083 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=203485872 --- RELEASENOTES.md | 3 +++ .../extractor/mp4/FragmentedMp4Extractor.java | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 93c5c344bca..70fd33db6dc 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -18,6 +18,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 a61b41dea28..74181f8898d 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 @@ private static void parseMoof(ContainerAtom moof, SparseArray track 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 @@ private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws * @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 @@ private static TrackBundle parseTfhd(ParsableByteArray tfhd, 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). *