Merge "GTS/youtube performance tests check claimed performance" into qt-dev am: 258e7e2b69 am: fe69054f3d
am: ac7d0befc6
Change-Id: I419ea17d6670cd66e63569d05231f9718a6128df
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java
index 469e99a..7e02b85 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaPerfUtils.java
@@ -173,4 +173,41 @@
return "Expected " + kind + ": " + reported + ".\n"
+ "Measured frame rate: " + Arrays.toString(measuredFps) + ".\n";
}
+
+ /** Verifies |requestedFps| does not exceed reported achievable rates.
+ * Returns null if *ALL* requested rates are claimed to be achievable.
+ * Otherwise, returns a diagnostic explaining why it's not achievable.
+ * (one of the rates was too fast, we don't have achievability information, etc).
+ *
+ * we're looking for 90% confidence, which is documented as being:
+ * "higher than half of the lower limit at least 90% of the time in tested configurations"
+ *
+ * NB: we only invoke this for the SW codecs; we use performance point info for the
+ * hardware codecs.
+ * */
+ public static String areAchievableFrameRates(
+ String name, String mime, int w, int h, double... requestedFps) {
+ Range<Double> reported =
+ MediaUtils.getVideoCapabilities(name, mime).getAchievableFrameRatesFor(w, h);
+ String kind = "achievable frame rates for " + name + " " + mime + " " + w + "x" + h;
+ if (reported == null) {
+ return "Failed to get " + kind;
+ }
+
+ double confidence90 = reported.getLower() / 2.0;
+
+ Log.d(TAG, name + " " + mime + " " + w + "x" + h +
+ " lower " + reported.getLower() + " 90% confidence " + confidence90 +
+ " requested " + Arrays.toString(requestedFps));
+
+ // if *any* of them are too fast, we say no.
+ for (double requested : requestedFps) {
+ if (requested > confidence90) {
+ return "Expected " + kind + ": " + reported + ", 90% confidence: " + confidence90
+ + ".\n"
+ + "Requested frame rate: " + Arrays.toString(requestedFps) + ".\n";
+ }
+ }
+ return null;
+ }
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
index c01efd2..53da03a 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
@@ -300,11 +300,79 @@
}
public static boolean canDecode(MediaFormat format) {
- if (sMCL.findDecoderForFormat(format) == null) {
+ return canDecode(format, 0.0);
+ }
+
+ // this is "do we claim to decode"; caller is on the hook to determine
+ // if we actually meet that claim, specifically around speed.
+ public static boolean canDecode(MediaFormat format, double rate ) {
+ String decoder = sMCL.findDecoderForFormat(format);
+
+ if (decoder == null) {
Log.i(TAG, "no decoder for " + format);
return false;
}
- return true;
+
+ if (rate == 0.0) {
+ return true;
+ }
+
+ // we care about speed of decoding
+ Log.d(TAG, "checking for decoding " + format + " at " +
+ rate + " fps with " + decoder);
+
+ String mime = format.getString(MediaFormat.KEY_MIME);
+ int width = format.getInteger(MediaFormat.KEY_WIDTH);
+ int height = format.getInteger(MediaFormat.KEY_HEIGHT);
+
+ MediaCodecInfo[] mciList = sMCL.getCodecInfos();
+
+ if (mciList == null) {
+ Log.d(TAG, "did not get list of MediaCodecInfo");
+ return false;
+ }
+
+ MediaCodecInfo mci = null;
+ for (MediaCodecInfo mci2 : mciList) {
+ if (mci2.getName().equals(decoder)) {
+ mci = mci2;
+ break;
+ }
+ }
+ if (mci == null) {
+ return false;
+ }
+ if (!mci.getName().equals(decoder)) {
+ Log.e(TAG, "did not find expected " + decoder);
+ return false;
+ }
+
+ if (mci.isSoftwareOnly()) {
+ String verified = MediaPerfUtils.areAchievableFrameRates(
+ decoder, mime, width, height, rate);
+ if (verified == null) {
+ Log.d(TAG, "claims to decode content at " + rate + " fps");
+ return true;
+ }
+ Log.d(TAG, "achieveable framerates says: " + verified);
+ return false;
+ } else {
+ MediaCodecInfo.VideoCapabilities caps =
+ mci.getCapabilitiesForType(mime).getVideoCapabilities();
+ List<MediaCodecInfo.VideoCapabilities.PerformancePoint> pp =
+ caps.getSupportedPerformancePoints();
+ VideoCapabilities.PerformancePoint target =
+ new VideoCapabilities.PerformancePoint(width, height, (int) rate);
+ for (MediaCodecInfo.VideoCapabilities.PerformancePoint point : pp) {
+ if (point.covers(target)) {
+ Log.i(TAG, "target " + target.toString() +
+ " covered by point " + point.toString());
+ return true;
+ }
+ }
+ Log.i(TAG, "NOT covered by any hardware performance point");
+ return false;
+ }
}
public static boolean supports(String codecName, String mime, int w, int h) {
@@ -555,15 +623,27 @@
return check(hasCodecForMimes(true /* encoder */, mimes), "no encoder found");
}
+ // checks format, does not address actual speed of decoding
public static boolean canDecodeVideo(String mime, int width, int height, float rate) {
+ return canDecodeVideo(mime, width, height, rate, (float)0.0);
+ }
+
+ // format + decode rate
+ public static boolean canDecodeVideo(String mime, int width, int height, float rate, float decodeRate) {
MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
- return canDecode(format);
+ return canDecode(format, decodeRate);
}
public static boolean canDecodeVideo(
String mime, int width, int height, float rate,
Integer profile, Integer level, Integer bitrate) {
+ return canDecodeVideo(mime, width, height, rate, profile, level, bitrate, (float)0.0);
+ }
+
+ public static boolean canDecodeVideo(
+ String mime, int width, int height, float rate,
+ Integer profile, Integer level, Integer bitrate, float decodeRate) {
MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
if (profile != null) {
@@ -575,7 +655,7 @@
if (bitrate != null) {
format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
}
- return canDecode(format);
+ return canDecode(format, decodeRate);
}
public static boolean checkEncoderForFormat(MediaFormat format) {