From ccf78f99c45e7a303e2bc649ef101b2c823778af Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Thu, 22 Oct 2020 20:47:19 +0100 Subject: [PATCH] Allow multiple codecs with same type in DefaultHlsExtractorFactory When disabling a TsExtractor track type because of a missing codec in the master playlist, look through the entire codecs string instead of checking the first codec with matching type. Issue: #7877 PiperOrigin-RevId: 338530046 --- .../android/exoplayer2/util/MimeTypes.java | 23 +++++++++++++ .../exoplayer2/util/MimeTypesTest.java | 32 +++++++++++++++++++ .../hls/DefaultHlsExtractorFactory.java | 4 +-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java b/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java index 6d5f167047..64afcd393a 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java @@ -239,6 +239,29 @@ public final class MimeTypes { return null; } + /** + * Returns whether the given {@code codecs} string contains a codec which corresponds to the given + * {@code mimeType}. + * + * @param codecs An RFC 6381 codecs string. + * @param mimeType A MIME type to look for. + * @return Whether the given {@code codecs} string contains a codec which corresponds to the given + * {@code mimeType}. + */ + public static boolean containsCodecsCorrespondingToMimeType( + @Nullable String codecs, String mimeType) { + if (codecs == null) { + return false; + } + String[] codecList = Util.splitCodecs(codecs); + for (String codec : codecList) { + if (mimeType.equals(getMediaMimeType(codec))) { + return true; + } + } + return false; + } + /** * Returns the first audio MIME type derived from an RFC 6381 codecs string. * diff --git a/library/common/src/test/java/com/google/android/exoplayer2/util/MimeTypesTest.java b/library/common/src/test/java/com/google/android/exoplayer2/util/MimeTypesTest.java index 46202a5991..6f68328dc7 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/util/MimeTypesTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/util/MimeTypesTest.java @@ -28,6 +28,38 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public final class MimeTypesTest { + @Test + public void containsCodecsCorrespondingToMimeType_returnsCorrectResult() { + assertThat( + MimeTypes.containsCodecsCorrespondingToMimeType( + /* codecs= */ "ac-3,mp4a.40.2,avc1.4D4015", MimeTypes.AUDIO_AAC)) + .isTrue(); + assertThat( + MimeTypes.containsCodecsCorrespondingToMimeType( + /* codecs= */ "ac-3,mp4a.40.2,avc1.4D4015", MimeTypes.AUDIO_AC3)) + .isTrue(); + assertThat( + MimeTypes.containsCodecsCorrespondingToMimeType( + /* codecs= */ "ac-3,mp4a.40.2,avc1.4D4015", MimeTypes.VIDEO_H264)) + .isTrue(); + assertThat( + MimeTypes.containsCodecsCorrespondingToMimeType( + /* codecs= */ "unknown-codec,mp4a.40.2,avc1.4D4015", MimeTypes.AUDIO_AAC)) + .isTrue(); + + assertThat( + MimeTypes.containsCodecsCorrespondingToMimeType( + /* codecs= */ "unknown-codec,mp4a.40.2,avc1.4D4015", MimeTypes.AUDIO_AC3)) + .isFalse(); + assertThat( + MimeTypes.containsCodecsCorrespondingToMimeType( + /* codecs= */ null, MimeTypes.AUDIO_AC3)) + .isFalse(); + assertThat( + MimeTypes.containsCodecsCorrespondingToMimeType(/* codecs= */ "", MimeTypes.AUDIO_AC3)) + .isFalse(); + } + @Test public void isText_returnsCorrectResult() { assertThat(MimeTypes.isText(MimeTypes.TEXT_VTT)).isTrue(); diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/DefaultHlsExtractorFactory.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/DefaultHlsExtractorFactory.java index 0a9ead7c48..c8ef90742b 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/DefaultHlsExtractorFactory.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/DefaultHlsExtractorFactory.java @@ -199,10 +199,10 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory { // Sometimes AAC and H264 streams are declared in TS chunks even though they don't really // exist. If we know from the codec attribute that they don't exist, then we can // explicitly ignore them even if they're declared. - if (!MimeTypes.AUDIO_AAC.equals(MimeTypes.getAudioMediaMimeType(codecs))) { + if (!MimeTypes.containsCodecsCorrespondingToMimeType(codecs, MimeTypes.AUDIO_AAC)) { payloadReaderFactoryFlags |= DefaultTsPayloadReaderFactory.FLAG_IGNORE_AAC_STREAM; } - if (!MimeTypes.VIDEO_H264.equals(MimeTypes.getVideoMediaMimeType(codecs))) { + if (!MimeTypes.containsCodecsCorrespondingToMimeType(codecs, MimeTypes.VIDEO_H264)) { payloadReaderFactoryFlags |= DefaultTsPayloadReaderFactory.FLAG_IGNORE_H264_STREAM; } }