From 78d65818c69870279b0cdbe4774e0d761f055ee5 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Wed, 18 Nov 2020 15:06:17 +0000 Subject: [PATCH] Fix HLS format derivation in traditional preparation ExoPlayer's traditional HLS preparation works by loading a chunk from each track group, and then tries to use the sample information plus the master playlist information to generate the preparation's resulting TrackGroups. There are 3 possible scenarios: - Supported case: Each variant has a single codec string per track type. We can assign each track the codec string which matches the loaded sample's type. - Supported case: Each variant has more than one codec string, but each track group has a single track. This is the case when different languages use different codecs. In this case, we can assign whichever codec matches the loaded sample's mime type. - Unsupported case: Each variant has more than one codec string, and track groups contain more than one track. We are not able to safely map tracks to codec strings because that would require loading a chunk from each track (which would considerably delay preparation). Broken in: https://github.com/google/ExoPlayer/commit/4783c329cc545da4269a9401a4975a41e75f2f43 PiperOrigin-RevId: 343072201 --- .../source/hls/HlsSampleStreamWrapper.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index fb1a6c53d9a..2b1ec60607b 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -1396,7 +1396,8 @@ private static int getTrackTypeScore(int trackType) { /** * Derives a track sample format from the corresponding format in the master playlist, and a - * sample format that may have been obtained from a chunk belonging to a different track. + * sample format that may have been obtained from a chunk belonging to a different track in the + * same track group. * * @param playlistFormat The format information obtained from the master playlist. * @param sampleFormat The format information obtained from the samples. @@ -1410,11 +1411,23 @@ private static Format deriveFormat( return sampleFormat; } - @Nullable - String codecs = - MimeTypes.getCodecsCorrespondingToMimeType( - playlistFormat.codecs, sampleFormat.sampleMimeType); - @Nullable String sampleMimeType = MimeTypes.getMediaMimeType(codecs); + int sampleTrackType = MimeTypes.getTrackType(sampleFormat.sampleMimeType); + @Nullable String sampleMimeType; + @Nullable String codecs; + if (Util.getCodecCountOfType(playlistFormat.codecs, sampleTrackType) == 1) { + // We can unequivocally map this track to a playlist variant because only one codec string + // matches this track's type. + codecs = Util.getCodecsOfType(playlistFormat.codecs, sampleTrackType); + sampleMimeType = MimeTypes.getMediaMimeType(codecs); + } else { + // The variant assigns more than one codec string to this track. We choose whichever codec + // string matches the sample mime type. This can happen when different languages are encoded + // using different codecs. + codecs = + MimeTypes.getCodecsCorrespondingToMimeType( + playlistFormat.codecs, sampleFormat.sampleMimeType); + sampleMimeType = sampleFormat.sampleMimeType; + } Format.Builder formatBuilder = sampleFormat