Use getAchievableFrameRatesFor to find approximate SW codec limits

We currently assume SW codecs are capable of playing all resolutions
and frame rates up to their declared supported maximum values, even
though the are likely not able to keep up playback smoothly for higher
resolutions. For HW codecs we can check PerformancePoints to declare
them as EXCEEDS_CAPABILITIES if they technically support a format but
are not performant enough. We can do the same for SW codecs by
checking getAchievableFrameRatesFor.

PiperOrigin-RevId: 739253653
This commit is contained in:
tonihei 2025-03-21 11:55:54 -07:00 committed by Copybara-Service
parent 1230573dfb
commit a472300c7a
2 changed files with 15 additions and 1 deletions

View File

@ -20,6 +20,8 @@
buffers. This flag will signal the decoder to skip the decode-only buffers. This flag will signal the decoder to skip the decode-only
buffers thereby resulting in faster seeking. Enable it with buffers thereby resulting in faster seeking. Enable it with
`DefaultRenderersFactory.experimentalSetEnableMediaCodecBufferDecodeOnlyFlag`. `DefaultRenderersFactory.experimentalSetEnableMediaCodecBufferDecodeOnlyFlag`.
* Improve codec performance checks for software video codecs. This may
lead to some additional tracks being marked as `EXCEEDS_CAPABILITIES`.
* Text: * Text:
* Metadata: * Metadata:
* Image: * Image:

View File

@ -40,6 +40,7 @@ import android.media.MediaCodecInfo.CodecProfileLevel;
import android.media.MediaCodecInfo.VideoCapabilities; import android.media.MediaCodecInfo.VideoCapabilities;
import android.os.Build; import android.os.Build;
import android.util.Pair; import android.util.Pair;
import android.util.Range;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@ -731,7 +732,18 @@ public final class MediaCodecInfo {
// floor to avoid situations where a range check in areSizeAndRateSupported fails due to // floor to avoid situations where a range check in areSizeAndRateSupported fails due to
// slightly exceeding the limits for a standard format (e.g., 1080p at 30 fps). // slightly exceeding the limits for a standard format (e.g., 1080p at 30 fps).
double floorFrameRate = Math.floor(frameRate); double floorFrameRate = Math.floor(frameRate);
return capabilities.areSizeAndRateSupported(width, height, floorFrameRate); if (!capabilities.areSizeAndRateSupported(width, height, floorFrameRate)) {
return false;
}
if (Util.SDK_INT < 24) {
return true;
}
@Nullable
Range<Double> achievableFrameRates = capabilities.getAchievableFrameRatesFor(width, height);
if (achievableFrameRates == null) {
return true;
}
return floorFrameRate <= achievableFrameRates.getUpper();
} }
} }