Commit 94a88e93 by michaelkatz Committed by Marc Baechinger

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
parent df58107e
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.video; 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_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.DISCARD_REASON_VIDEO_MAX_RESOLUTION_EXCEEDED;
import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_NO; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_NO;
...@@ -25,6 +26,7 @@ import android.annotation.SuppressLint; ...@@ -25,6 +26,7 @@ import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.graphics.Point; import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecInfo.CodecProfileLevel;
...@@ -35,6 +37,7 @@ import android.os.Handler; ...@@ -35,6 +37,7 @@ import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Pair; import android.util.Pair;
import android.view.Display;
import android.view.Surface; import android.view.Surface;
import androidx.annotation.CallSuper; import androidx.annotation.CallSuper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -353,6 +356,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -353,6 +356,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
boolean requiresSecureDecryption = drmInitData != null; boolean requiresSecureDecryption = drmInitData != null;
List<MediaCodecInfo> decoderInfos = List<MediaCodecInfo> decoderInfos =
getDecoderInfos( getDecoderInfos(
context,
mediaCodecSelector, mediaCodecSelector,
format, format,
requiresSecureDecryption, requiresSecureDecryption,
...@@ -361,6 +365,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -361,6 +365,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// No secure decoders are available. Fall back to non-secure decoders. // No secure decoders are available. Fall back to non-secure decoders.
decoderInfos = decoderInfos =
getDecoderInfos( getDecoderInfos(
context,
mediaCodecSelector, mediaCodecSelector,
format, format,
/* requiresSecureDecoder= */ false, /* requiresSecureDecoder= */ false,
...@@ -408,6 +413,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -408,6 +413,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
if (isFormatSupported) { if (isFormatSupported) {
List<MediaCodecInfo> tunnelingDecoderInfos = List<MediaCodecInfo> tunnelingDecoderInfos =
getDecoderInfos( getDecoderInfos(
context,
mediaCodecSelector, mediaCodecSelector,
format, format,
requiresSecureDecryption, requiresSecureDecryption,
...@@ -436,7 +442,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -436,7 +442,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder) MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder)
throws DecoderQueryException { throws DecoderQueryException {
return MediaCodecUtil.getDecoderInfosSortedByFormatSupport( return MediaCodecUtil.getDecoderInfosSortedByFormatSupport(
getDecoderInfos(mediaCodecSelector, format, requiresSecureDecoder, tunneling), format); getDecoderInfos(context, mediaCodecSelector, format, requiresSecureDecoder, tunneling),
format);
} }
/** /**
...@@ -456,6 +463,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -456,6 +463,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @throws DecoderQueryException Thrown if there was an error querying decoders. * @throws DecoderQueryException Thrown if there was an error querying decoders.
*/ */
private static List<MediaCodecInfo> getDecoderInfos( private static List<MediaCodecInfo> getDecoderInfos(
Context context,
MediaCodecSelector mediaCodecSelector, MediaCodecSelector mediaCodecSelector,
Format format, Format format,
boolean requiresSecureDecoder, boolean requiresSecureDecoder,
...@@ -475,6 +483,28 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -475,6 +483,28 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
List<MediaCodecInfo> alternativeDecoderInfos = List<MediaCodecInfo> alternativeDecoderInfos =
mediaCodecSelector.getDecoderInfos( mediaCodecSelector.getDecoderInfos(
alternativeMimeType, requiresSecureDecoder, requiresTunnelingDecoder); 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.<MediaCodecInfo>builder() return ImmutableList.<MediaCodecInfo>builder()
.addAll(decoderInfos) .addAll(decoderInfos)
.addAll(alternativeDecoderInfos) .addAll(alternativeDecoderInfos)
......
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