From f0fb3862245579ff3874d0bdc10a7481077984d8 Mon Sep 17 00:00:00 2001 From: michaelkatz Date: Wed, 18 Sep 2024 03:26:43 -0700 Subject: [PATCH] Add workaround for Galaxy Tab S7 FE device PerformancePoint issue The Galaxy Tab S7 FE has a device issue that causes 60fps secure H264 streams to be marked as unsupported. This CL adds a workaround for this issue by checking the CDD required support for secure H264 in addition to the current check on standard H264. If the provided performance points do not cover the CDD requirement of support 720p H264 at 60fps, then it falls back to using legacy methods for checking frame rate and resolution support. Issue: androidx/media#1619 PiperOrigin-RevId: 675920968 --- RELEASENOTES.md | 3 ++ ...CodecPerformancePointCoverageProvider.java | 28 +++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 668e99ba81..ff505df259 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -29,6 +29,9 @@ * DataSource: * Audio: * Video: + * Add workaround for a device issue on Galaxy Tab S7 FE that causes 60fps + secure H264 streams to be marked as unsupported + ([#1619](https://github.com/androidx/media/issues/1619)). * Text: * Metadata: * Image: diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecPerformancePointCoverageProvider.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecPerformancePointCoverageProvider.java index 4d79061e7d..4f20f2a699 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecPerformancePointCoverageProvider.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecPerformancePointCoverageProvider.java @@ -137,6 +137,25 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; // The same check as below is tested in CTS and we should get reliable results from API 35. return false; } + @PerformancePointCoverageResult + int h264RequiredSupportResult = + evaluateH264RequiredSupport(/* requiresSecureDecoder= */ false); + @PerformancePointCoverageResult + int h264SecureRequiredSupportResult = + evaluateH264RequiredSupport(/* requiresSecureDecoder= */ true); + + if (h264RequiredSupportResult == COVERAGE_RESULT_NO_PERFORMANCE_POINTS_UNSUPPORTED) { + return true; + } + if (h264SecureRequiredSupportResult == COVERAGE_RESULT_NO_PERFORMANCE_POINTS_UNSUPPORTED) { + return h264RequiredSupportResult != COVERAGE_RESULT_YES; + } + return h264RequiredSupportResult != COVERAGE_RESULT_YES + || h264SecureRequiredSupportResult != COVERAGE_RESULT_YES; + } + + private static @PerformancePointCoverageResult int evaluateH264RequiredSupport( + boolean requiresSecureDecoder) { try { Format formatH264 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build(); // Null check required to pass RequiresNonNull annotation on getDecoderInfosSoftMatch. @@ -145,7 +164,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; MediaCodecUtil.getDecoderInfosSoftMatch( MediaCodecSelector.DEFAULT, formatH264, - /* requiresSecureDecoder= */ false, + /* requiresSecureDecoder= */ requiresSecureDecoder, /* requiresTunnelingDecoder= */ false); for (int i = 0; i < decoderInfos.size(); i++) { if (decoderInfos.get(i).capabilities != null @@ -160,15 +179,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; PerformancePoint targetPerformancePointH264 = new PerformancePoint(/* width= */ 1280, /* height= */ 720, /* frameRate= */ 60); return evaluatePerformancePointCoverage( - performancePointListH264, targetPerformancePointH264) - == COVERAGE_RESULT_NO; + performancePointListH264, targetPerformancePointH264); } } } } - return true; + return COVERAGE_RESULT_NO_PERFORMANCE_POINTS_UNSUPPORTED; } catch (MediaCodecUtil.DecoderQueryException ignored) { - return true; + return COVERAGE_RESULT_NO_PERFORMANCE_POINTS_UNSUPPORTED; } }