From 94a88e93d91e86c93239639a65612eab297efa9b Mon Sep 17 00:00:00 2001 From: michaelkatz Date: Fri, 23 Sep 2022 13:43:21 +0000 Subject: [PATCH] Try alternative decoder for Dolby Vision if display does not support If the sample type is dolby vision and the following conditions match a)There is a supported alternative codec mimetype b)Display does not support Dolby Vision Then getDecoderInfos will return the alternative types. Issue: google/ExoPlayer#9794 PiperOrigin-RevId: 476356223 --- .../video/MediaCodecVideoRenderer.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) 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 71137a77d7c..c04a544512c 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 @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.video; +import static android.view.Display.DEFAULT_DISPLAY; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_VIDEO_MAX_RESOLUTION_EXCEEDED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_NO; @@ -25,6 +26,7 @@ import android.annotation.TargetApi; import android.content.Context; import android.graphics.Point; +import android.hardware.display.DisplayManager; import android.media.MediaCodec; import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecInfo.CodecProfileLevel; @@ -35,6 +37,7 @@ import android.os.Message; import android.os.SystemClock; import android.util.Pair; +import android.view.Display; import android.view.Surface; import androidx.annotation.CallSuper; import androidx.annotation.Nullable; @@ -353,6 +356,7 @@ public String getName() { boolean requiresSecureDecryption = drmInitData != null; List decoderInfos = getDecoderInfos( + context, mediaCodecSelector, format, requiresSecureDecryption, @@ -361,6 +365,7 @@ public String getName() { // No secure decoders are available. Fall back to non-secure decoders. decoderInfos = getDecoderInfos( + context, mediaCodecSelector, format, /* requiresSecureDecoder= */ false, @@ -408,6 +413,7 @@ public String getName() { if (isFormatSupported) { List tunnelingDecoderInfos = getDecoderInfos( + context, mediaCodecSelector, format, requiresSecureDecryption, @@ -436,7 +442,8 @@ protected List getDecoderInfos( MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder) throws DecoderQueryException { return MediaCodecUtil.getDecoderInfosSortedByFormatSupport( - getDecoderInfos(mediaCodecSelector, format, requiresSecureDecoder, tunneling), format); + getDecoderInfos(context, mediaCodecSelector, format, requiresSecureDecoder, tunneling), + format); } /** @@ -456,6 +463,7 @@ protected List getDecoderInfos( * @throws DecoderQueryException Thrown if there was an error querying decoders. */ private static List getDecoderInfos( + Context context, MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder, @@ -475,6 +483,28 @@ private static List getDecoderInfos( List alternativeDecoderInfos = mediaCodecSelector.getDecoderInfos( alternativeMimeType, requiresSecureDecoder, requiresTunnelingDecoder); + if (Util.SDK_INT >= 26 + && MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType) + && !alternativeDecoderInfos.isEmpty()) { + // If sample type is Dolby Vision, check if Display supports Dolby Vision + boolean supportsDolbyVision = false; + DisplayManager displayManager = + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + Display display = + (displayManager != null) ? displayManager.getDisplay(DEFAULT_DISPLAY) : null; + if (display != null && display.isHdr()) { + int[] supportedHdrTypes = display.getHdrCapabilities().getSupportedHdrTypes(); + for (int hdrType : supportedHdrTypes) { + if (hdrType == Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION) { + supportsDolbyVision = true; + break; + } + } + } + if (!supportsDolbyVision) { + return ImmutableList.copyOf(alternativeDecoderInfos); + } + } return ImmutableList.builder() .addAll(decoderInfos) .addAll(alternativeDecoderInfos)