Skip to content

Commit

Permalink
Try alternative decoder for Dolby Vision if display does not support
Browse files Browse the repository at this point in the history
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 ed79f46)
  • Loading branch information
microkatz committed Sep 23, 2022
1 parent ab37184 commit dd42561
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Expand Up @@ -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`
Expand Down
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -356,6 +359,7 @@ public String getName() {
boolean requiresSecureDecryption = drmInitData != null;
List<MediaCodecInfo> decoderInfos =
getDecoderInfos(
context,
mediaCodecSelector,
format,
requiresSecureDecryption,
Expand All @@ -364,6 +368,7 @@ public String getName() {
// No secure decoders are available. Fall back to non-secure decoders.
decoderInfos =
getDecoderInfos(
context,
mediaCodecSelector,
format,
/* requiresSecureDecoder= */ false,
Expand Down Expand Up @@ -411,6 +416,7 @@ public String getName() {
if (isFormatSupported) {
List<MediaCodecInfo> tunnelingDecoderInfos =
getDecoderInfos(
context,
mediaCodecSelector,
format,
requiresSecureDecryption,
Expand Down Expand Up @@ -439,7 +445,8 @@ protected List<MediaCodecInfo> 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);
}

/**
Expand All @@ -459,6 +466,7 @@ protected List<MediaCodecInfo> getDecoderInfos(
* @throws DecoderQueryException Thrown if there was an error querying decoders.
*/
private static List<MediaCodecInfo> getDecoderInfos(
Context context,
MediaCodecSelector mediaCodecSelector,
Format format,
boolean requiresSecureDecoder,
Expand All @@ -478,6 +486,28 @@ private static List<MediaCodecInfo> getDecoderInfos(
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)
Expand Down

0 comments on commit dd42561

Please sign in to comment.