diff --git a/content/test/data/gpu/webcodecs/encoding-framerate-resolutions.html b/content/test/data/gpu/webcodecs/encoding-framerate-resolutions.html index ffff0a9b37b092656b2af7a56351731b44d07159..d29bc00a06342526754d1568db42d07326c02f30 100644 --- a/content/test/data/gpu/webcodecs/encoding-framerate-resolutions.html +++ b/content/test/data/gpu/webcodecs/encoding-framerate-resolutions.html @@ -33,7 +33,7 @@ Check that VideoEncoder can encode in different framerate and resolutions supported = (await VideoEncoder.isConfigSupported(encoder_config)).supported; } catch (e) {} if (!supported) { - TEST.skip('Unsupported configs: ' + JSON.stringify(encoder_config, null, 2)); + TEST.skip('Unsupported codec: ' + arg.codec); return; } diff --git a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt index f23f02c7b892de103d64217a6cfd898edbbaf782..61c90eced80c388e7008e07e3d99bb13ba9eb007 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt @@ -117,6 +117,10 @@ crbug.com/1368785 [ android-pixel-6 arm renderer-skia-vulkan target-cpu-64 ] Web crbug.com/1368785 [ android-pixel-4 android-r qualcomm renderer-skia-gl target-cpu-32 ] WebCodecs_EncodingRateControl_avc1.420034_prefer-hardware_variable_* [ Failure ] crbug.com/1368785 [ android-pixel-4 android-r qualcomm renderer-skia-gl target-cpu-32 ] WebCodecs_EncodingRateControl_hvc1.1.6.L123.00_prefer-hardware_variable_3000000 [ Failure ] +# MediaCodec doesn't report correct 4k max supported framerate on all Android devices. +crbug.com/371247952 [ android ] WebCodecs_EncodingFramerateResolutions_3840x2160_120_* [ Failure ] +crbug.com/371247952 [ android ] WebCodecs_EncodingFramerateResolutions_3840x2160_240_* [ Failure ] + # Platform API doesn't report correct 8k 30 framerate for vp09 coded on ChromeOS intel devices. crbug.com/373648897 [ chromeos intel angle-vulkan graphite-disabled ] WebCodecs_EncodingFramerateResolutions_7680x3840_30_vp09.00.62.08_prefer-hardware_quality [ Failure ] diff --git a/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java b/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java index 0e7a9c77aff579d4e9525e86cee2b98c61ab58a1..c7b7544b26f57135f941a056fadd118bb67cf7f1 100644 --- a/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java +++ b/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java @@ -18,10 +18,8 @@ import org.jni_zero.JNINamespace; import org.chromium.base.Log; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -56,36 +54,6 @@ class VideoAcceleratorUtil { private static final Set<String> TEMPORAL_SVC_SUPPORTING_ENCODERS = Set.of("c2.qti.avc.encoder", "c2.exynos.h264.encoder"); - // Possible supported resolutions. - private static final Resolution[] SUPPORTED_RESOLUTIONS = { - new Resolution(320, 180), - new Resolution(640, 360), - new Resolution(1280, 720), - new Resolution(1920, 1080), - new Resolution(2560, 1440), - new Resolution(3840, 2160), - new Resolution(5120, 2880), - new Resolution(7680, 4320), - }; - - private static class Resolution { - private int mWidth; - private int mHeight; - - public Resolution(int width, int height) { - mWidth = width; - mHeight = height; - } - - public int getWidth() { - return mWidth; - } - - public int getHeight() { - return mHeight; - } - } - private static class SupportedProfileAdapter { public int profile; public int level; @@ -279,45 +247,30 @@ class VideoAcceleratorUtil { Range<Integer> supportedWidths = videoCapabilities.getSupportedWidths(); Range<Integer> supportedHeights = videoCapabilities.getSupportedHeightsFor(supportedWidths.getUpper()); - int minWidth = supportedWidths.getLower(); - int minHeight = supportedHeights.getLower(); - - // Add the possible supported resolutions. - ArrayList<Resolution> supportedResolutions = - new ArrayList<Resolution>(Arrays.asList(SUPPORTED_RESOLUTIONS)); - // Add the max resolution. - supportedResolutions.add( - new Resolution(supportedWidths.getUpper(), supportedHeights.getUpper())); - LinkedHashMap<Integer, Resolution> frameRateResolutionMap = - new LinkedHashMap<Integer, Resolution>(); - // Compute the final supported resolution and framerate combinations. - for (Resolution supportedResolution : supportedResolutions) { - int supportedWidth = supportedResolution.getWidth(); - int supportedHeight = supportedResolution.getHeight(); - if (!videoCapabilities.isSizeSupported(supportedWidth, supportedHeight)) { - continue; - } - // Each resolution may have different max supported framerate, so we must - // query the framerate base on width and height. - Range<Double> supportedFrameRates = - videoCapabilities.getSupportedFrameRatesFor( - supportedWidth, supportedHeight); - int supportedFrameRate = - (int) Math.floor(supportedFrameRates.getUpper().doubleValue()); - if (!frameRateResolutionMap.containsKey(supportedFrameRate)) { - frameRateResolutionMap.put(supportedFrameRate, supportedResolution); - } else { - Resolution resolution = frameRateResolutionMap.get(supportedFrameRate); - // If the framerates of the two are the same, always use the higher - // resolution to replace the lower resolution and make sure we won't push - // useless result to the list. - if (supportedWidth >= resolution.getWidth() - && supportedHeight >= resolution.getHeight()) { - frameRateResolutionMap.put(supportedFrameRate, supportedResolution); - } - } + + // Some devices don't have their max supported level configured correctly, so they + // can return max resolutions like 7680x1714 which prevents both 4K and 8K content + // from being hardware decoded. + // + // In cases where supported area is > 4k, but width, height are less than standard + // and the standard resolution is supported, use the standard one instead so that at + // least 4k support works. See https://crbug.com/41481822. + if ((supportedWidths.getUpper() < 3840 || supportedHeights.getUpper() < 2160) + && supportedWidths.getUpper() * supportedHeights.getUpper() >= 3840 * 2160 + && videoCapabilities.isSizeSupported(3840, 2160)) { + supportedWidths = new Range<Integer>(supportedWidths.getLower(), 3840); + supportedHeights = new Range<Integer>(supportedHeights.getLower(), 2160); } + boolean needsPortraitEntry = + !supportedHeights.getUpper().equals(supportedWidths.getUpper()) + && videoCapabilities.isSizeSupported( + supportedHeights.getUpper(), supportedWidths.getUpper()); + + // The frame rate entry in the supported profile is independent of the resolution + // range, so we don't query based on the maximum resolution. + Range<Integer> supportedFrameRates = videoCapabilities.getSupportedFrameRates(); + // Since the supported profiles interface doesn't support levels, we just attach // the same min/max to every profile. HashSet<Integer> supportedProfiles = new HashSet<Integer>(); @@ -334,59 +287,43 @@ class VideoAcceleratorUtil { } } - String name = info.getName(); - boolean isSoftwareCodec = info.isSoftwareOnly(); - int maxNumberOfTemporalLayers = - getNumberOfTemporalLayers(name.toLowerCase(Locale.getDefault())); + getNumberOfTemporalLayers(info.getName().toLowerCase(Locale.getDefault())); ArrayList<SupportedProfileAdapter> profiles = info.isHardwareAccelerated() ? hardwareProfiles : softwareProfiles; + for (int mediaProfile : supportedProfiles) { + SupportedProfileAdapter profile = new SupportedProfileAdapter(); - for (Map.Entry<Integer, Resolution> frameRateResolution : - frameRateResolutionMap.entrySet()) { - int maxFrameRate = frameRateResolution.getKey(); - int maxWidth = frameRateResolution.getValue().getWidth(); - int maxHeight = frameRateResolution.getValue().getHeight(); - - boolean needsPortraitEntry = - maxHeight != maxWidth - && videoCapabilities.isSizeSupported(maxHeight, maxWidth); + profile.profile = mediaProfile; + profile.minWidth = supportedWidths.getLower(); + profile.minHeight = supportedHeights.getLower(); + profile.maxWidth = supportedWidths.getUpper(); + profile.maxHeight = supportedHeights.getUpper(); + profile.maxFramerateNumerator = supportedFrameRates.getUpper(); + profile.maxFramerateDenominator = 1; + profile.supportsCbr = supportsCbr; + profile.supportsVbr = supportsVbr; + profile.name = info.getName(); + profile.isSoftwareCodec = info.isSoftwareOnly(); + profile.maxNumberOfTemporalLayers = maxNumberOfTemporalLayers; + profiles.add(profile); - for (int mediaProfile : supportedProfiles) { - SupportedProfileAdapter profile = new SupportedProfileAdapter(); + // Invert min/max height/width for a portrait mode entry if needed. + if (needsPortraitEntry) { + profile = new SupportedProfileAdapter(); profile.profile = mediaProfile; - profile.minWidth = minWidth; - profile.minHeight = minHeight; - profile.maxWidth = maxWidth; - profile.maxHeight = maxHeight; - profile.maxFramerateNumerator = maxFrameRate; + profile.minWidth = supportedHeights.getLower(); + profile.minHeight = supportedWidths.getLower(); + profile.maxWidth = supportedHeights.getUpper(); + profile.maxHeight = supportedWidths.getUpper(); + profile.maxFramerateNumerator = supportedFrameRates.getUpper(); profile.maxFramerateDenominator = 1; profile.supportsCbr = supportsCbr; profile.supportsVbr = supportsVbr; - profile.name = name; - profile.isSoftwareCodec = isSoftwareCodec; - profile.maxNumberOfTemporalLayers = maxNumberOfTemporalLayers; + profile.name = info.getName(); + profile.isSoftwareCodec = info.isSoftwareOnly(); profiles.add(profile); - - // Invert min/max height/width for a portrait mode entry if needed. - if (needsPortraitEntry) { - profile = new SupportedProfileAdapter(); - - profile.profile = mediaProfile; - profile.minWidth = minHeight; - profile.minHeight = minWidth; - profile.maxWidth = maxHeight; - profile.maxHeight = maxWidth; - profile.maxFramerateNumerator = maxFrameRate; - profile.maxFramerateDenominator = 1; - profile.supportsCbr = supportsCbr; - profile.supportsVbr = supportsVbr; - profile.name = name; - profile.isSoftwareCodec = isSoftwareCodec; - profile.maxNumberOfTemporalLayers = maxNumberOfTemporalLayers; - profiles.add(profile); - } } } }