本讲是Android Camera专题系列的第12讲,我们介绍Android Camera2 API专题的StreamConfigurationMap实战之如何获取录像Size。
更多资源:
资源 | 描述 |
---|---|
在线课程 | 极客笔记在线课程 |
知识星球 | 星球名称:深入浅出Android Camera 星球ID: 17296815 |
极客笔记圈 |
获取录像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(),
fr,
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(),
fr,
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());
}