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:
4783c329cc

PiperOrigin-RevId: 343072201
This commit is contained in:
aquilescanta 2020-11-18 15:06:17 +00:00 committed by Ian Baker
parent bb8a2de37d
commit 78d65818c6

View file

@ -1396,7 +1396,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
/**
* 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 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
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