Skip to content

Commit 0eb30ea

Browse files
microkatzrohitjoins
authored andcommitted
Change areSizeAndRateSupported to use PerfomancePoint.covers
PiperOrigin-RevId: 482461219
1 parent e3f2842 commit 0eb30ea

File tree

1 file changed

+68
-4
lines changed

1 file changed

+68
-4
lines changed

library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@
2828
import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_YES_WITHOUT_RECONFIGURATION;
2929
import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_YES_WITH_FLUSH;
3030
import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_YES_WITH_RECONFIGURATION;
31+
import static java.lang.annotation.ElementType.TYPE_USE;
3132

3233
import android.graphics.Point;
3334
import android.media.MediaCodec;
3435
import android.media.MediaCodecInfo.AudioCapabilities;
3536
import android.media.MediaCodecInfo.CodecCapabilities;
3637
import android.media.MediaCodecInfo.CodecProfileLevel;
3738
import android.media.MediaCodecInfo.VideoCapabilities;
39+
import android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint;
3840
import android.util.Pair;
41+
import androidx.annotation.DoNotInline;
42+
import androidx.annotation.IntDef;
3943
import androidx.annotation.Nullable;
4044
import androidx.annotation.RequiresApi;
4145
import androidx.annotation.VisibleForTesting;
@@ -47,6 +51,11 @@
4751
import com.google.android.exoplayer2.util.Log;
4852
import com.google.android.exoplayer2.util.MimeTypes;
4953
import com.google.android.exoplayer2.util.Util;
54+
import java.lang.annotation.Documented;
55+
import java.lang.annotation.Retention;
56+
import java.lang.annotation.RetentionPolicy;
57+
import java.lang.annotation.Target;
58+
import java.util.List;
5059

5160
/** Information about a {@link MediaCodec} for a given mime type. */
5261
@SuppressWarnings("InlinedApi")
@@ -480,8 +489,6 @@ public DecoderReuseEvaluation canReuseCodec(Format oldFormat, Format newFormat)
480489
/**
481490
* Whether the decoder supports video with a given width, height and frame rate.
482491
*
483-
*

Must not be called if the device SDK version is less than 21.

484-
*
485492
* @param width Width in pixels.
486493
* @param height Height in pixels.
487494
* @param frameRate Optional frame rate in frames per second. Ignored if set to {@link
@@ -499,14 +506,28 @@ public boolean isVideoSizeAndRateSupportedV21(int width, int height, double fram
499506
logNoSupport("sizeAndRate.vCaps");
500507
return false;
501508
}
509+
510+
if (Util.SDK_INT >= 29) {
511+
@PerformancePointCoverageResult
512+
int evaluation =
513+
Api29.areResolutionAndFrameRateCovered(videoCapabilities, width, height, frameRate);
514+
if (evaluation == COVERAGE_RESULT_YES) {
515+
return true;
516+
} else if (evaluation == COVERAGE_RESULT_NO) {
517+
logNoSupport("sizeAndRate.cover, " + width + "x" + height + "@" + frameRate);
518+
return false;
519+
}
520+
// COVERAGE_RESULT_NO_EMPTY_LIST falls through to API 21+ code below
521+
}
522+
502523
if (!areSizeAndRateSupportedV21(videoCapabilities, width, height, frameRate)) {
503524
if (width >= height
504525
|| !needsRotatedVerticalResolutionWorkaround(name)
505526
|| !areSizeAndRateSupportedV21(videoCapabilities, height, width, frameRate)) {
506-
logNoSupport("sizeAndRate.support, " + width + "x" + height + "x" + frameRate);
527+
logNoSupport("sizeAndRate.support, " + width + "x" + height + "@" + frameRate);
507528
return false;
508529
}
509-
logAssumedSupport("sizeAndRate.rotated, " + width + "x" + height + "x" + frameRate);
530+
logAssumedSupport("sizeAndRate.rotated, " + width + "x" + height + "@" + frameRate);
510531
}
511532
return true;
512533
}
@@ -842,4 +863,47 @@ private static boolean needsProfileExcludedWorkaround(String mimeType, int profi
842863
&& CodecProfileLevel.HEVCProfileMain10 == profile
843864
&& ("sailfish".equals(Util.DEVICE) || "marlin".equals(Util.DEVICE));
844865
}
866+
867+
/** Possible outcomes of evaluating PerformancePoint coverage */
868+
@Documented
869+
@Retention(RetentionPolicy.SOURCE)
870+
@Target(TYPE_USE)
871+
@IntDef({COVERAGE_RESULT_YES, COVERAGE_RESULT_NO, COVERAGE_RESULT_NO_EMPTY_LIST})
872+
private @interface PerformancePointCoverageResult {}
873+
874+
/** The decoder has a PerformancePoint that covers the resolution and frame rate */
875+
private static final int COVERAGE_RESULT_YES = 2;
876+
/**
877+
* The decoder has at least one PerformancePoint, but none of them cover the resolution and frame
878+
* rate
879+
*/
880+
private static final int COVERAGE_RESULT_NO = 1;
881+
/** The VideoCapabilities does not contain any PerformancePoints */
882+
private static final int COVERAGE_RESULT_NO_EMPTY_LIST = 0;
883+
884+
@RequiresApi(29)
885+
private static final class Api29 {
886+
@DoNotInline
887+
public static @PerformancePointCoverageResult int areResolutionAndFrameRateCovered(
888+
VideoCapabilities videoCapabilities, int width, int height, double frameRate) {
889+
List<PerformancePoint> performancePointList =
890+
videoCapabilities.getSupportedPerformancePoints();
891+
if (performancePointList == null || performancePointList.isEmpty()) {
892+
return COVERAGE_RESULT_NO_EMPTY_LIST;
893+
}
894+
895+
// Round frame rate down to to avoid situations where a range check in
896+
// covers fails due to slightly exceeding the limits for a standard format
897+
// (e.g., 1080p at 30 fps). [Internal ref: b/134706676]
898+
PerformancePoint targetPerformancePoint =
899+
new PerformancePoint(width, height, (int) frameRate);
900+
901+
for (int i = 0; i < performancePointList.size(); i++) {
902+
if (performancePointList.get(i).covers(targetPerformancePoint)) {
903+
return COVERAGE_RESULT_YES;
904+
}
905+
}
906+
return COVERAGE_RESULT_NO;
907+
}
908+
}
845909
}

0 commit comments

Comments
 (0)