diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java index 6881de1ecf2..6d1bd597c58 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java @@ -222,6 +222,55 @@ public static List getDecoderInfosSoftMatch( .build(); } + /** + * Returns a list of decoders that can decode media in the specified format, in the priority order + * specified by the {@link MediaCodecSelector}. + * Unlike {@link #getDecoderInfosSoftMatch}, this method may exclude decoders that match the + * sample MIME type but do not support relevant format details. + * + *

This list is more complete than {@link #getDecoderInfos}, as it also considers alternative + * MIME types that are a close match using {@link #getAlternativeCodecMimeType}. + * + * @param context The application context. + * @param mediaCodecSelector The decoder selector. + * @param format The {@link Format} for which a decoder is required. + * @param requiresSecureDecoder Whether a secure decoder is required. + * @param requiresTunnelingDecoder Whether a tunneling decoder is required. + * @return A list of {@link MediaCodecInfo}s corresponding to decoders. May be empty. + * @throws DecoderQueryException Thrown if there was an error querying decoders. + */ + @RequiresNonNull("#3.sampleMimeType") + public static List getDecoderInfosSoftMatchFilteredByFormatSupport( + Context context, + MediaCodecSelector mediaCodecSelector, + Format format, + boolean requiresSecureDecoder, + boolean requiresTunnelingDecoder) + throws DecoderQueryException { + + List decoderInfos = + mediaCodecSelector.getDecoderInfos( + format.sampleMimeType, requiresSecureDecoder, requiresTunnelingDecoder); + + ImmutableList.Builder result = ImmutableList.builder(); + + for (MediaCodecInfo decoderInfo : decoderInfos) { + if (!decoderInfo.isFormatSupported(context, format)) { + continue; + } + result.add(decoderInfo); + } + + result.addAll( + getAlternativeDecoderInfos( + mediaCodecSelector, + format, + requiresSecureDecoder, + requiresTunnelingDecoder)); + + return result.build(); + } + /** * Returns a list of decoders for {@linkplain #getAlternativeCodecMimeType alternative MIME types} * that can decode samples of the provided {@link Format}, in the priority order specified by the diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java index 6b63549119b..3c96a84d47d 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java @@ -3937,7 +3937,7 @@ public VideoTrackInfo( == RendererCapabilities.HARDWARE_ACCELERATION_SUPPORTED; this.resolvedMimeType = resolvedMimeType; codecPreferenceScore = getVideoCodecPreferenceScore(resolvedMimeType); - isHdr = usesPrimaryDecoder && ColorInfo.isTransferHdr(format.colorInfo); + isHdr = usesPrimaryOrFallbackDecoder && ColorInfo.isTransferHdr(format.colorInfo); selectionEligibility = evaluateSelectionEligibility(formatSupport, requiredAdaptiveSupport); } 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 361f9291ff6..cd034d662c4 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 @@ -940,8 +940,13 @@ private static List getDecoderInfos( return alternativeDecoderInfos; } } - return MediaCodecUtil.getDecoderInfosSoftMatch( - mediaCodecSelector, format, requiresSecureDecoder, requiresTunnelingDecoder); + if (MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)) { + return MediaCodecUtil.getDecoderInfosSoftMatchFilteredByFormatSupport( + context, mediaCodecSelector, format, requiresSecureDecoder, requiresTunnelingDecoder); + } else { + return MediaCodecUtil.getDecoderInfosSoftMatch( + mediaCodecSelector, format, requiresSecureDecoder, requiresTunnelingDecoder); + } } @RequiresApi(26)