/** * Whether the decoder supports video with a given width, height and frame rate. * <p> * Must not be called if the device SDK version is less than 21. * * @param width Width in pixels. * @param height Height in pixels. * @param frameRate Optional frame rate in frames per second. Ignored if set to * {@link Format#NO_VALUE} or any value less than or equal to 0. * @return Whether the decoder supports video with the given width, height and frame rate. */ @TargetApi(21) public boolean isVideoSizeAndRateSupportedV21(int width, int height, double frameRate) { if (capabilities == null) { logNoSupport("sizeAndRate.caps"); return false; } VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); if (videoCapabilities == null) { logNoSupport("sizeAndRate.vCaps"); return false; } if (!areSizeAndRateSupported(videoCapabilities, width, height, frameRate)) { // Capabilities are known to be inaccurately reported for vertical resolutions on some devices // (b/31387661). If the video is vertical and the capabilities indicate support if the width // and height are swapped, we assume that the vertical resolution is also supported. if (width >= height || !areSizeAndRateSupported(videoCapabilities, height, width, frameRate)) { logNoSupport("sizeAndRate.support, " + width + "x" + height + "x" + frameRate); return false; } logAssumedSupport("sizeAndRate.rotated, " + width + "x" + height + "x" + frameRate); } return true; }
/** * Returns the smallest video size greater than or equal to a specified size that also satisfies * the {@link MediaCodec}'s width and height alignment requirements. * <p> * Must not be called if the device SDK version is less than 21. * * @param width Width in pixels. * @param height Height in pixels. * @return The smallest video size greater than or equal to the specified size that also satisfies * the {@link MediaCodec}'s width and height alignment requirements, or null if not a video * codec. */ @TargetApi(21) public Point alignVideoSizeV21(int width, int height) { if (capabilities == null) { logNoSupport("align.caps"); return null; } VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); if (videoCapabilities == null) { logNoSupport("align.vCaps"); return null; } int widthAlignment = videoCapabilities.getWidthAlignment(); int heightAlignment = videoCapabilities.getHeightAlignment(); return new Point(Util.ceilDivide(width, widthAlignment) * widthAlignment, Util.ceilDivide(height, heightAlignment) * heightAlignment); }
/** * Needed on M and older to get correct information about VP9 support. * @param profileLevels The CodecProfileLevelList to add supported profile levels to. * @param videoCapabilities The MediaCodecInfo.VideoCapabilities used to infer support. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private static void addVp9CodecProfileLevels(CodecProfileLevelList profileLevels, MediaCodecInfo.CodecCapabilities codecCapabilities) { // https://www.webmproject.org/vp9/levels final int[][] bitrateMapping = { {200, 10}, {800, 11}, {1800, 20}, {3600, 21}, {7200, 30}, {12000, 31}, {18000, 40}, {30000, 41}, {60000, 50}, {120000, 51}, {180000, 52}, }; VideoCapabilities videoCapabilities = codecCapabilities.getVideoCapabilities(); for (int[] entry : bitrateMapping) { int bitrate = entry[0]; int level = entry[1]; if (videoCapabilities.getBitrateRange().contains(bitrate)) { // Assume all platforms before N only support VP9 profile 0. profileLevels.addCodecProfileLevel( VideoCodec.CODEC_VP9, VideoCodecProfile.VP9PROFILE_PROFILE0, level); } } }
/** * Whether the decoder supports video with a given width, height and frame rate. * <p> * Must not be called if the device SDK version is less than 21. * * @param width Width in pixels. * @param height Height in pixels. * @param frameRate Optional frame rate in frames per second. Ignored if set to * {@link Format#NO_VALUE} or any value less than or equal to 0. * @return Whether the decoder supports video with the given width, height and frame rate. */ @TargetApi(21) public boolean isVideoSizeAndRateSupportedV21(int width, int height, double frameRate) { if (capabilities == null) { logNoSupport("sizeAndRate.caps"); return false; } VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); if (videoCapabilities == null) { logNoSupport("sizeAndRate.vCaps"); return false; } if (!areSizeAndRateSupportedV21(videoCapabilities, width, height, frameRate)) { // Capabilities are known to be inaccurately reported for vertical resolutions on some devices // (b/31387661). If the video is vertical and the capabilities indicate support if the width // and height are swapped, we assume that the vertical resolution is also supported. if (width >= height || !areSizeAndRateSupportedV21(videoCapabilities, height, width, frameRate)) { logNoSupport("sizeAndRate.support, " + width + "x" + height + "x" + frameRate); return false; } logAssumedSupport("sizeAndRate.rotated, " + width + "x" + height + "x" + frameRate); } return true; }
@TargetApi(21) private static boolean areSizeAndRateSupported(VideoCapabilities capabilities, int width, int height, double frameRate) { return frameRate == Format.NO_VALUE || frameRate <= 0 ? capabilities.isSizeSupported(width, height) : capabilities.areSizeAndRateSupported(width, height, frameRate); }
@TargetApi(21) private static boolean areSizeAndRateSupportedV21(VideoCapabilities capabilities, int width, int height, double frameRate) { return frameRate == Format.NO_VALUE || frameRate <= 0 ? capabilities.isSizeSupported(width, height) : capabilities.areSizeAndRateSupported(width, height, frameRate); }
/** * Whether the decoder supports video with a specified width and height. * <p> * Must not be called if the device SDK version is less than 21. * * @param width Width in pixels. * @param height Height in pixels. * @return Whether the decoder supports video with the given width and height. */ @TargetApi(21) public boolean isVideoSizeSupportedV21(int width, int height) { if (capabilities == null) { return false; } VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); return videoCapabilities != null && videoCapabilities.isSizeSupported(width, height); }
/** * Whether the decoder supports video with a given width, height and frame rate. * <p> * Must not be called if the device SDK version is less than 21. * * @param width Width in pixels. * @param height Height in pixels. * @param frameRate Frame rate in frames per second. * @return Whether the decoder supports video with the given width, height and frame rate. */ @TargetApi(21) public boolean isVideoSizeAndRateSupportedV21(int width, int height, double frameRate) { if (capabilities == null) { return false; } VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); return videoCapabilities != null && videoCapabilities.areSizeAndRateSupported(width, height, frameRate); }