获取录像Size
MediaRecorder / MediaCodec
需要考虑的点
录像Size:Camera支持列表 与 Encoder支持列表 交集
判断Video Encoder是否支持某种Size和FPS
* Check if encoder can support this size and frame rate combination by querying
* MediaCodec capability. Check is based on size and frame rate. Ignore the bit rate
* as the bit rates targeted in this test are well below the bit rate max value specified
* by AVC specification for certain level.
private static boolean isSupportedByAVCEncoder(android.util.Size sz, int frameRate) {
MediaFormat format = MediaFormat.createVideoFormat(
MediaFormat.MIMETYPE_VIDEO_AVC, sz.getWidth(), sz.getHeight());
format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
return mcl.findEncoderForFormat(format) != null;
获取Camera支持的录像正常帧率Size列表
private void doInitSupportedVideoSizes(CameraFeatures camera_features,
StreamConfigurationMap configs) throws CameraControllerException {
android.util.Size[] camera_video_sizes = configs.getOutputSizes(MediaRecorder.class);
camera_features.mSupportedVideoSizes = new ArrayList<>();
int min_fps = 9999;
for(int[] r : this.mAeFpsRanges) {
min_fps = Math.min(min_fps, r[0]);
if( camera_video_sizes == null ) {
// camera_video_sizes is null on Samsung Galaxy Note 10+ and S20 for camera ID 4!
Log.e(TAG, "no video sizes returned by getOutputSizes");
throw new CameraControllerException();
else {
for(android.util.Size camera_size : camera_video_sizes) {
long mfd = configs.getOutputMinFrameDuration(MediaRecorder.class, camera_size);
int max_fps = (int)((1.0 / mfd) * 1000000000L);
if (isSupportedByAVCEncoder(camera_size, max_fps)) {
ArrayList<int[]> fr = new ArrayList<>();
fr.add(new int[] {max_fps, max_fps});
CameraController.Size normal_video_size = new CameraController.Size(
camera_size.getWidth(),
camera_size.getHeight(),
false);
camera_features.mSupportedVideoSizes.add(normal_video_size);
if( MyDebug.LOG ) {
Log.i(TAG, "doInitSupportedVideoSizes normal video size: " + normal_video_size +
",max fps:" + max_fps);
} else {
Log.e(TAG, "doInitSupportedVideoSizes not support!" +
"camera_size:" + camera_size.toString() +
",max_fps:" + max_fps);
Collections.sort(camera_features.mSupportedVideoSizes, new CameraController.SizeSorter());
获取Camera支持的录像高帧率Size列表
private void doInitSupportedHighSpeedVideoSizes(CameraFeatures camera_features,
StreamConfigurationMap configs) {
hs_fps_ranges = new ArrayList<>();
camera_features.mSupportedVideoSizesHighSpeed = new ArrayList<>();
for (Range<Integer> r : configs.getHighSpeedVideoFpsRanges()) {
hs_fps_ranges.add(new int[] {r.getLower(), r.getUpper()});
Collections.sort(hs_fps_ranges, new CameraController.RangeSorter());
if( MyDebug.LOG ) {
Log.i(TAG, "Supported high speed video fps ranges: ");
for (int[] f : hs_fps_ranges) {
Log.i(TAG, " hs range: [" + f[0] + "-" + f[1] + "]");
android.util.Size[] camera_video_sizes_high_speed = configs.getHighSpeedVideoSizes();
for(android.util.Size camera_size : camera_video_sizes_high_speed) {
for (Range<Integer> r : configs.getHighSpeedVideoFpsRangesFor(camera_size)) {
int profile_fps = getFpsFromHighSpeedProfileForSize(camera_size);
if (r.getUpper() > r.getLower()) {
Log.e(TAG, "doInitSupportedHighSpeedVideoSizes fps range:" + r.toString());
continue;
if (!isSupportedByAVCEncoder(camera_size, r.getUpper())) {
Log.e(TAG, "doInitSupportedHighSpeedVideoSizes high speed recording " +
camera_size + "@" + r.getLower() + "fps"
+ " is not supported by CamcorderProfile, fps:" + profile_fps);
continue;
ArrayList<int[]> fr = new ArrayList<>();
fr.add(new int[] { r.getLower(), r.getUpper()});
CameraController.Size hs_video_size = new CameraController.Size(
camera_size.getWidth(),
camera_size.getHeight(),
true);
if (MyDebug.LOG) {
Log.i(TAG, "doInitSupportedHighSpeedVideoSizes high speed video size: " +
hs_video_size +
", fps range:" + r.toString());
camera_features.mSupportedVideoSizesHighSpeed.add(hs_video_size);
Collections.sort(camera_features.mSupportedVideoSizesHighSpeed, new CameraController.SizeSorter());
评论 抢沙发
- Android Camera2 API
- 第2讲 Android Camera 架构介绍第3讲 Camera2 API 概述第4讲 Open和Close Camera流程第5讲 GeekCamera2介绍第6讲 Open和Close Camera代码实现第7讲 Hardware Level详解第8讲 AVAILABLE_CAPABILITIES详解第9讲 StreamConfigurationMap详解一第10讲 StreamConfigurationMap详解二第11讲 StreamConfigurationMap实战一第12讲 StreamConfigurationMap实战二第13讲 为什么需要OutputConfiguration第14讲 OutputConfiguration API详解第15讲 Surface Sharing实战第16讲 Deferred Surface实战第17讲 Reprocessable Capture Session详解一第18讲 Reprocessable Capture Session详解二第19讲 App如何实现ZSL功能第20讲 SessionConfiguration详解第21讲 createCaptureSession详解第22讲 SessionParameter实战第23讲 CaptureRequest详解第24讲 如何操作VendorTag第25讲 获取Physical Camera数据流第26讲 CameraCaptureSession详解第27讲 CameraCaptureSession.CaptureCallback详解第28讲 GeekCamera2连拍实战第29讲 SlowMotion实战第30讲 CaptureResult详解第31讲 AE自动曝光 Part 1第32讲 AE自动曝光 Part 2第33讲 AE自动曝光实战第34讲 AE手动曝光第35讲 AE手动曝光实战第36讲 Flash闪光灯控制第37讲 拍照打闪实战第38讲 通过CropRegion控制Zoom缩放第39讲 通过ZoomRatio控制Zoom缩放第40讲 Digital Zoom缩放实战第41讲 Touch AE实战第42讲 AF自动对焦第43讲 AF自动对焦 第二部分第44讲 AF自动对焦实战第45讲 手动对焦实战第46讲 AWB自动白平衡第47讲 AWB自动白平衡实战第48讲 FD人脸检测第49讲 Android13 Camera2 New APIs介绍Android 14 Camera2 API New Changes尝鲜