diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java index 2485793e55..f2fed378ed 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java @@ -317,15 +317,24 @@ private boolean isCodecProfileAndLevelSupported( int profile = codecProfileAndLevel.first; int level = codecProfileAndLevel.second; if (MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)) { - // If this codec is H264 or H265, we only support the Dolby Vision base layer and need to map - // the Dolby Vision profile to the corresponding base layer profile. Also assume all levels of - // this base layer profile are supported. - if (MimeTypes.VIDEO_H264.equals(mimeType)) { - profile = CodecProfileLevel.AVCProfileHigh; - level = 0; - } else if (MimeTypes.VIDEO_H265.equals(mimeType)) { - profile = CodecProfileLevel.HEVCProfileMain10; - level = 0; + // If this codec is H.264, H.265 or AV1, we only support the Dolby Vision base layer and need + // to map the Dolby Vision profile to the corresponding base layer profile. Also assume all + // levels of this base layer profile are supported. + switch (mimeType) { + case MimeTypes.VIDEO_H264: + profile = CodecProfileLevel.AVCProfileHigh; + level = 0; + break; + case MimeTypes.VIDEO_H265: + profile = CodecProfileLevel.HEVCProfileMain10; + level = 0; + break; + case MimeTypes.VIDEO_AV1: + profile = CodecProfileLevel.AV1ProfileMain10; + level = 0; + break; + default: + break; } } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java index 4eabf8842e..1e8bbd09b7 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java @@ -1144,11 +1144,11 @@ public static int getCodecMaxInputSize(MediaCodecInfo codecInfo, Format format) String sampleMimeType = checkNotNull(format.sampleMimeType); if (MimeTypes.VIDEO_DOLBY_VISION.equals(sampleMimeType)) { - // Dolby vision can be a wrapper around H264 or H265. We assume it's wrapping H265 by default - // because it's the common case, and because some devices may fail to allocate the codec when - // the larger buffer size required for H264 is requested. We size buffers for H264 only if the - // format contains sufficient information for us to determine unambiguously that it's a H264 - // profile. + // Dolby vision can be a wrapper around H.264, H.265 or AV1. We assume it's wrapping H.265 by + // default because it's the common case, and because some devices may fail to allocate the + // codec when the larger buffer size required for H.264/AV1 is requested. We size buffers + // for H.264/AV1 only if the format contains sufficient information for us to determine + // unambiguously that it's a H.264/AV1 based profile. sampleMimeType = MimeTypes.VIDEO_H265; @Nullable Pair codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format); @@ -1158,6 +1158,8 @@ public static int getCodecMaxInputSize(MediaCodecInfo codecInfo, Format format) || profile == CodecProfileLevel.DolbyVisionProfileDvavPer || profile == CodecProfileLevel.DolbyVisionProfileDvavPen) { sampleMimeType = MimeTypes.VIDEO_H264; + } else if (profile == CodecProfileLevel.DolbyVisionProfileDvav110) { + sampleMimeType = MimeTypes.VIDEO_AV1; } } } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/DolbyVisionConfig.java b/libraries/extractor/src/main/java/androidx/media3/extractor/DolbyVisionConfig.java index 620ce8fa78..98dc69552a 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/DolbyVisionConfig.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/DolbyVisionConfig.java @@ -38,16 +38,17 @@ public static DolbyVisionConfig parse(ParsableByteArray data) { int dvProfile = (profileData >> 1); int dvLevel = ((profileData & 0x1) << 5) | ((data.readUnsignedByte() >> 3) & 0x1F); String codecsPrefix; - if (dvProfile == 4 || dvProfile == 5 || dvProfile == 7) { + if (dvProfile == 4 || dvProfile == 5 || dvProfile == 7 || dvProfile == 8) { codecsPrefix = "dvhe"; - } else if (dvProfile == 8) { - codecsPrefix = "hev1"; } else if (dvProfile == 9) { - codecsPrefix = "avc3"; + codecsPrefix = "dvav"; + } else if (dvProfile == 10) { + codecsPrefix = "dav1"; } else { return null; } - String codecs = codecsPrefix + ".0" + dvProfile + (dvLevel < 10 ? ".0" : ".") + dvLevel; + String codecs = codecsPrefix + (dvProfile < 10 ? ".0" : ".") + dvProfile + + (dvLevel < 10 ? ".0" : ".") + dvLevel; return new DolbyVisionConfig(dvProfile, dvLevel, codecs); }