diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java index 3310b0dc8b..acaf798b41 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java @@ -198,7 +198,7 @@ public final class MediaCodecInfo { * @throws MediaCodecUtil.DecoderQueryException Thrown if an error occurs while querying decoders. */ public boolean isFormatSupported(Format format) throws MediaCodecUtil.DecoderQueryException { - if (!isCodecSupported(format.codecs)) { + if (!isCodecSupported(format)) { return false; } @@ -226,25 +226,25 @@ public final class MediaCodecInfo { } /** - * Whether the decoder supports the given {@code codec}. If there is insufficient information to - * decide, returns true. + * Whether the decoder supports the codec of the given {@code format}. If there is insufficient + * information to decide, returns true. * - * @param codec Codec string as defined in RFC 6381. - * @return True if the given codec is supported by the decoder. + * @param format The input media format. + * @return True if the codec of the given {@code format} is supported by the decoder. */ - public boolean isCodecSupported(String codec) { - if (codec == null || mimeType == null) { + public boolean isCodecSupported(Format format) { + if (format.codecs == null || mimeType == null) { return true; } - String codecMimeType = MimeTypes.getMediaMimeType(codec); + String codecMimeType = MimeTypes.getMediaMimeType(format.codecs); if (codecMimeType == null) { return true; } if (!mimeType.equals(codecMimeType)) { - logNoSupport("codec.mime " + codec + ", " + codecMimeType); + logNoSupport("codec.mime " + format.codecs + ", " + codecMimeType); return false; } - Pair codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(codec); + Pair codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format); if (codecProfileAndLevel == null) { // If we don't know any better, we assume that the profile and level are supported. return true; @@ -261,7 +261,7 @@ public final class MediaCodecInfo { return true; } } - logNoSupport("codec.profileLevel, " + codec + ", " + codecMimeType); + logNoSupport("codec.profileLevel, " + format.codecs + ", " + codecMimeType); return false; } @@ -279,8 +279,7 @@ public final class MediaCodecInfo { if (isVideo) { return adaptive; } else { - Pair codecProfileLevel = - MediaCodecUtil.getCodecProfileAndLevel(format.codecs); + Pair codecProfileLevel = MediaCodecUtil.getCodecProfileAndLevel(format); return codecProfileLevel != null && codecProfileLevel.first == CodecProfileLevel.AACObjectXHE; } } @@ -314,9 +313,9 @@ public final class MediaCodecInfo { } // Check the codec profile levels support adaptation. Pair oldCodecProfileLevel = - MediaCodecUtil.getCodecProfileAndLevel(oldFormat.codecs); + MediaCodecUtil.getCodecProfileAndLevel(oldFormat); Pair newCodecProfileLevel = - MediaCodecUtil.getCodecProfileAndLevel(newFormat.codecs); + MediaCodecUtil.getCodecProfileAndLevel(newFormat); if (oldCodecProfileLevel == null || newCodecProfileLevel == null) { return false; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java index 455ee6c034..df5ca05972 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java @@ -230,35 +230,34 @@ public final class MediaCodecUtil { } /** - * Returns profile and level (as defined by {@link CodecProfileLevel}) corresponding to the given - * codec description string (as defined by RFC 6381). + * Returns profile and level (as defined by {@link CodecProfileLevel}) corresponding to the codec + * description string (as defined by RFC 6381) of the given format. * - * @param codec A codec description string, as defined by RFC 6381, or {@code null} if not known. - * @return A pair (profile constant, level constant) if {@code codec} is well-formed and - * recognized, or null otherwise + * @param format Media format with a codec description string, as defined by RFC 6381. + * @return A pair (profile constant, level constant) if the codec of the {@code format} is + * well-formed and recognized, or null otherwise. */ - @Nullable - public static Pair getCodecProfileAndLevel(@Nullable String codec) { - if (codec == null) { + public static Pair getCodecProfileAndLevel(Format format) { + if (format.codecs == null) { return null; } - String[] parts = codec.split("\\."); + String[] parts = format.codecs.split("\\."); switch (parts[0]) { case CODEC_ID_AVC1: case CODEC_ID_AVC2: - return getAvcProfileAndLevel(codec, parts); + return getAvcProfileAndLevel(format.codecs, parts); case CODEC_ID_VP09: - return getVp9ProfileAndLevel(codec, parts); + return getVp9ProfileAndLevel(format.codecs, parts); case CODEC_ID_HEV1: case CODEC_ID_HVC1: - return getHevcProfileAndLevel(codec, parts); + return getHevcProfileAndLevel(format.codecs, parts); case CODEC_ID_DVHE: case CODEC_ID_DVH1: - return getDolbyVisionProfileAndLevel(codec, parts); + return getDolbyVisionProfileAndLevel(format.codecs, parts); case CODEC_ID_AV01: - return getAv1ProfileAndLevel(codec, parts); + return getAv1ProfileAndLevel(format.codecs, parts); case CODEC_ID_MP4A: - return getAacCodecProfileAndLevel(codec, parts); + return getAacCodecProfileAndLevel(format.codecs, parts); default: return null; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java index d9d81cf6d4..6e3114d1b1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java @@ -390,8 +390,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { decoderInfos = MediaCodecUtil.getDecoderInfosSortedByFormatSupport(decoderInfos, format); if (MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)) { // Fallback to primary decoders for H.265/HEVC or H.264/AVC for the relevant DV profiles. - Pair codecProfileAndLevel = - MediaCodecUtil.getCodecProfileAndLevel(format.codecs); + Pair codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format); if (codecProfileAndLevel != null) { int profile = codecProfileAndLevel.first; if (profile == 4 || profile == 8) { @@ -1194,8 +1193,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { if (MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)) { // Some phones require the profile to be set on the codec. // See https://github.com/google/ExoPlayer/pull/5438. - Pair codecProfileAndLevel = - MediaCodecUtil.getCodecProfileAndLevel(format.codecs); + Pair codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format); if (codecProfileAndLevel != null) { MediaFormatUtil.maybeSetInteger( mediaFormat, MediaFormat.KEY_PROFILE, codecProfileAndLevel.first); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtilTest.java b/library/core/src/test/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtilTest.java index 05d92e0783..c485ff49f6 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtilTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtilTest.java @@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertThat; import android.media.MediaCodecInfo; import android.util.Pair; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.util.MimeTypes; import org.junit.Test; import org.junit.runner.RunWith; @@ -87,17 +89,53 @@ public final class MediaCodecUtilTest { @Test public void getCodecProfileAndLevel_rejectsNullCodecString() { - assertThat(MediaCodecUtil.getCodecProfileAndLevel(/* codec= */ null)).isNull(); + Format format = + Format.createVideoSampleFormat( + /* id= */ null, + /* sampleMimeType= */ MimeTypes.VIDEO_UNKNOWN, + /* codecs= */ null, + /* bitrate= */ Format.NO_VALUE, + /* maxInputSize= */ Format.NO_VALUE, + /* width= */ 1024, + /* height= */ 768, + /* frameRate= */ Format.NO_VALUE, + /* initializationData= */ null, + /* drmInitData= */ null); + assertThat(MediaCodecUtil.getCodecProfileAndLevel(format)).isNull(); } @Test public void getCodecProfileAndLevel_rejectsEmptyCodecString() { - assertThat(MediaCodecUtil.getCodecProfileAndLevel("")).isNull(); + Format format = + Format.createVideoSampleFormat( + /* id= */ null, + /* sampleMimeType= */ MimeTypes.VIDEO_UNKNOWN, + /* codecs= */ "", + /* bitrate= */ Format.NO_VALUE, + /* maxInputSize= */ Format.NO_VALUE, + /* width= */ 1024, + /* height= */ 768, + /* frameRate= */ Format.NO_VALUE, + /* initializationData= */ null, + /* drmInitData= */ null); + assertThat(MediaCodecUtil.getCodecProfileAndLevel(format)).isNull(); } private static void assertCodecProfileAndLevelForCodecsString( String codecs, int profile, int level) { - Pair codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(codecs); + Format format = + Format.createVideoSampleFormat( + /* id= */ null, + /* sampleMimeType= */ MimeTypes.VIDEO_UNKNOWN, + /* codecs= */ codecs, + /* bitrate= */ Format.NO_VALUE, + /* maxInputSize= */ Format.NO_VALUE, + /* width= */ 1024, + /* height= */ 768, + /* frameRate= */ Format.NO_VALUE, + /* initializationData= */ null, + /* drmInitData= */ null); + Pair codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format); assertThat(codecProfileAndLevel).isNotNull(); assertThat(codecProfileAndLevel.first).isEqualTo(profile); assertThat(codecProfileAndLevel.second).isEqualTo(level);