Commit a1849243 by aquilescanta Committed by Oliver Woodman

Avoid chunkless preparation if the codec mapping is ambiguous

Issue: #7877
PiperOrigin-RevId: 338659937
parent 5b1514e9
...@@ -1488,6 +1488,18 @@ public final class Util { ...@@ -1488,6 +1488,18 @@ public final class Util {
+ ") " + ExoPlayerLibraryInfo.VERSION_SLASHY; + ") " + ExoPlayerLibraryInfo.VERSION_SLASHY;
} }
/** Returns the number of codec strings in {@code codecs} whose type matches {@code trackType}. */
public static int getCodecCountOfType(@Nullable String codecs, int trackType) {
String[] codecArray = splitCodecs(codecs);
int count = 0;
for (String codec : codecArray) {
if (trackType == MimeTypes.getTrackTypeOfCodec(codec)) {
count++;
}
}
return count;
}
/** /**
* Returns a copy of {@code codecs} without the codecs whose track type doesn't match {@code * Returns a copy of {@code codecs} without the codecs whose track type doesn't match {@code
* trackType}. * trackType}.
......
...@@ -603,6 +603,12 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -603,6 +603,12 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
} }
} }
String codecs = selectedPlaylistFormats[0].codecs; String codecs = selectedPlaylistFormats[0].codecs;
int numberOfVideoCodecs = Util.getCodecCountOfType(codecs, C.TRACK_TYPE_VIDEO);
int numberOfAudioCodecs = Util.getCodecCountOfType(codecs, C.TRACK_TYPE_AUDIO);
boolean codecsStringAllowsChunklessPreparation =
numberOfAudioCodecs <= 1
&& numberOfVideoCodecs <= 1
&& numberOfAudioCodecs + numberOfVideoCodecs > 0;
HlsSampleStreamWrapper sampleStreamWrapper = HlsSampleStreamWrapper sampleStreamWrapper =
buildSampleStreamWrapper( buildSampleStreamWrapper(
C.TRACK_TYPE_DEFAULT, C.TRACK_TYPE_DEFAULT,
...@@ -614,18 +620,16 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -614,18 +620,16 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
positionUs); positionUs);
sampleStreamWrappers.add(sampleStreamWrapper); sampleStreamWrappers.add(sampleStreamWrapper);
manifestUrlIndicesPerWrapper.add(selectedVariantIndices); manifestUrlIndicesPerWrapper.add(selectedVariantIndices);
if (allowChunklessPreparation && codecs != null) { if (allowChunklessPreparation && codecsStringAllowsChunklessPreparation) {
boolean variantsContainVideoCodecs = Util.getCodecsOfType(codecs, C.TRACK_TYPE_VIDEO) != null;
boolean variantsContainAudioCodecs = Util.getCodecsOfType(codecs, C.TRACK_TYPE_AUDIO) != null;
List<TrackGroup> muxedTrackGroups = new ArrayList<>(); List<TrackGroup> muxedTrackGroups = new ArrayList<>();
if (variantsContainVideoCodecs) { if (numberOfVideoCodecs > 0) {
Format[] videoFormats = new Format[selectedVariantsCount]; Format[] videoFormats = new Format[selectedVariantsCount];
for (int i = 0; i < videoFormats.length; i++) { for (int i = 0; i < videoFormats.length; i++) {
videoFormats[i] = deriveVideoFormat(selectedPlaylistFormats[i]); videoFormats[i] = deriveVideoFormat(selectedPlaylistFormats[i]);
} }
muxedTrackGroups.add(new TrackGroup(videoFormats)); muxedTrackGroups.add(new TrackGroup(videoFormats));
if (variantsContainAudioCodecs if (numberOfAudioCodecs > 0
&& (masterPlaylist.muxedAudioFormat != null || masterPlaylist.audios.isEmpty())) { && (masterPlaylist.muxedAudioFormat != null || masterPlaylist.audios.isEmpty())) {
muxedTrackGroups.add( muxedTrackGroups.add(
new TrackGroup( new TrackGroup(
...@@ -640,7 +644,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -640,7 +644,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
muxedTrackGroups.add(new TrackGroup(ccFormats.get(i))); muxedTrackGroups.add(new TrackGroup(ccFormats.get(i)));
} }
} }
} else if (variantsContainAudioCodecs) { } else /* numberOfAudioCodecs > 0 */ {
// Variants only contain audio. // Variants only contain audio.
Format[] audioFormats = new Format[selectedVariantsCount]; Format[] audioFormats = new Format[selectedVariantsCount];
for (int i = 0; i < audioFormats.length; i++) { for (int i = 0; i < audioFormats.length; i++) {
...@@ -651,9 +655,6 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -651,9 +655,6 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
/* isPrimaryTrackInVariant= */ true); /* isPrimaryTrackInVariant= */ true);
} }
muxedTrackGroups.add(new TrackGroup(audioFormats)); muxedTrackGroups.add(new TrackGroup(audioFormats));
} else {
// Variants contain codecs but no video or audio entries could be identified.
throw new IllegalArgumentException("Unexpected codecs attribute: " + codecs);
} }
TrackGroup id3TrackGroup = TrackGroup id3TrackGroup =
...@@ -693,7 +694,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -693,7 +694,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
continue; continue;
} }
boolean renditionsHaveCodecs = true; boolean codecStringsAllowChunklessPreparation = true;
scratchPlaylistUrls.clear(); scratchPlaylistUrls.clear();
scratchPlaylistFormats.clear(); scratchPlaylistFormats.clear();
scratchIndicesList.clear(); scratchIndicesList.clear();
...@@ -704,7 +705,8 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -704,7 +705,8 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
scratchIndicesList.add(renditionIndex); scratchIndicesList.add(renditionIndex);
scratchPlaylistUrls.add(rendition.url); scratchPlaylistUrls.add(rendition.url);
scratchPlaylistFormats.add(rendition.format); scratchPlaylistFormats.add(rendition.format);
renditionsHaveCodecs &= rendition.format.codecs != null; codecStringsAllowChunklessPreparation &=
Util.getCodecCountOfType(rendition.format.codecs, C.TRACK_TYPE_AUDIO) == 1;
} }
} }
...@@ -720,7 +722,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -720,7 +722,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
manifestUrlsIndicesPerWrapper.add(Ints.toArray(scratchIndicesList)); manifestUrlsIndicesPerWrapper.add(Ints.toArray(scratchIndicesList));
sampleStreamWrappers.add(sampleStreamWrapper); sampleStreamWrappers.add(sampleStreamWrapper);
if (allowChunklessPreparation && renditionsHaveCodecs) { if (allowChunklessPreparation && codecStringsAllowChunklessPreparation) {
Format[] renditionFormats = scratchPlaylistFormats.toArray(new Format[0]); Format[] renditionFormats = scratchPlaylistFormats.toArray(new Format[0]);
sampleStreamWrapper.prepareWithMasterPlaylistInfo( sampleStreamWrapper.prepareWithMasterPlaylistInfo(
new TrackGroup[] {new TrackGroup(renditionFormats)}, /* primaryTrackGroupIndex= */ 0); new TrackGroup[] {new TrackGroup(renditionFormats)}, /* primaryTrackGroupIndex= */ 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment