From 1a76403283ffe2f995043c355deead4d6945dd13 Mon Sep 17 00:00:00 2001 From: ybai001 Date: Mon, 27 Jul 2026 09:36:02 +0800 Subject: [PATCH] BugFix: Fix DV playback if SDR fallback is added to the manifest The partial fix in aa5b318 moved HDR and codec score preferences into quality preferences and resolved fallback MIME types, but testing indicates there is still SDR track instead of Dolby Vision track selected on some TV devices. This change fixes the remaining portion of #3135 not addressed by aa5b318. (e.g. Dolby Vision profile 8.1 stream may fail in playback on separate OMX Dolby Vision decoders per profile device). Issue: https://github.com/androidx/media/issues/3135 Related-commit: aa5b318406d40de7fdb31dabc3802b4e1624f710 --- .../exoplayer/mediacodec/MediaCodecUtil.java | 49 +++++++++++++++++++ .../trackselection/DefaultTrackSelector.java | 2 +- .../video/MediaCodecVideoRenderer.java | 9 +++- 3 files changed, 57 insertions(+), 3 deletions(-) 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)