Commit dd425613 by michaelkatz Committed by microkatz

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
(cherry picked from commit ed79f469)
parent ab371849
......@@ -14,6 +14,8 @@
* Discard back buffer before playback gets stuck due to insufficient
available memory.
* Close the Tracing "doSomeWork" block when offload is enabled.
* Try alternative decoder for Dolby Vision if display does not support it.
([#9794](https://github.com/google/ExoPlayer/issues/9794)).
* Downloads:
* Fix potential infinite loop in `ProgressiveDownloader` caused by
simultaneous download and playback with the same `PriorityTaskManager`
......
......@@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.video;
import static android.view.Display.DEFAULT_DISPLAY;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_VIDEO_MAX_RESOLUTION_EXCEEDED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.REUSE_RESULT_NO;
......@@ -25,6 +26,7 @@ import android.annotation.SuppressLint;
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.Handler;
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;
......@@ -356,6 +359,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
boolean requiresSecureDecryption = drmInitData != null;
List<MediaCodecInfo> decoderInfos =
getDecoderInfos(
context,
mediaCodecSelector,
format,
requiresSecureDecryption,
......@@ -364,6 +368,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// No secure decoders are available. Fall back to non-secure decoders.
decoderInfos =
getDecoderInfos(
context,
mediaCodecSelector,
format,
/* requiresSecureDecoder= */ false,
......@@ -411,6 +416,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
if (isFormatSupported) {
List<MediaCodecInfo> tunnelingDecoderInfos =
getDecoderInfos(
context,
mediaCodecSelector,
format,
requiresSecureDecryption,
......@@ -439,7 +445,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder)
throws DecoderQueryException {
return MediaCodecUtil.getDecoderInfosSortedByFormatSupport(
getDecoderInfos(mediaCodecSelector, format, requiresSecureDecoder, tunneling), format);
getDecoderInfos(context, mediaCodecSelector, format, requiresSecureDecoder, tunneling),
format);
}
/**
......@@ -459,6 +466,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @throws DecoderQueryException Thrown if there was an error querying decoders.
*/
private static List<MediaCodecInfo> getDecoderInfos(
Context context,
MediaCodecSelector mediaCodecSelector,
Format format,
boolean requiresSecureDecoder,
......@@ -478,6 +486,28 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
List<MediaCodecInfo> 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.<MediaCodecInfo>builder()
.addAll(decoderInfos)
.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