android.scaler.streamConfigurationMap Key值的来源
android.scaler.streamConfigurationMap Key值的来源
一、背景
在开发camera app时,app获取preview的YUV数据,当从KEY CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP的StreamConfigurationMap中获取类型为SurfaceHolder.class的size时,发现它少于picture size,代码如下:
CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = mCharacteristics.get(cameraId).get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] size = map.getOutputSizes(SurfaceHolder.class);
获取的outsize如果少于picture size,如果camera app选择在app中对预览数据进行处理而呈现给用户的话,它将会造成成取景的窗口小于拍照生成图片的窗口。
二、StreamConfigurationMap中数据的来源
StreamConfigurationMap包含有各种camera streamconfig的数据 ,一般我们只知道这些数据来源于camera metadata,从代码看,我们能知道StreamConfigurationMap包含camera metadata中SCALER_AVAILABLE_STREAM_CONFIGURATIONS、SCALER_AVAILABLE_MIN_FRAME_DURATIONS、SCALER_AVAILABLE_STALL_DURATIONS、DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS、DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS、DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS、CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS和SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP这些键值。
LINUX/android/frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
// Use Command pattern here to avoid lots of expensive if/equals checks in get for overridden
// metadata.
private static final HashMap<Key<?>, GetCommand> sGetCommandMap =new HashMap<Key<?>, GetCommand>();
static {......sGetCommandMap.put(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP.getNativeKey(),new GetCommand() {@Override@SuppressWarnings("unchecked")public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {return (T) metadata.getStreamConfigurationMap();}});
private StreamConfigurationMap getStreamConfigurationMap() {StreamConfiguration[] configurations = getBase(CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS);StreamConfigurationDuration[] minFrameDurations = getBase(CameraCharacteristics.SCALER_AVAILABLE_MIN_FRAME_DURATIONS);StreamConfigurationDuration[] stallDurations = getBase(CameraCharacteristics.SCALER_AVAILABLE_STALL_DURATIONS);StreamConfiguration[] depthConfigurations = getBase(CameraCharacteristics.DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);StreamConfigurationDuration[] depthMinFrameDurations = getBase(CameraCharacteristics.DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);StreamConfigurationDuration[] depthStallDurations = getBase(CameraCharacteristics.DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);HighSpeedVideoConfiguration[] highSpeedVideoConfigurations = getBase(CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);ReprocessFormatsMap inputOutputFormatsMap = getBase(CameraCharacteristics.SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP);int[] capabilities = getBase(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);boolean listHighResolution = false;for (int capability : capabilities) {if (capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE) {listHighResolution = true;break;}}return new StreamConfigurationMap(configurations, minFrameDurations, stallDurations,depthConfigurations, depthMinFrameDurations, depthStallDurations,highSpeedVideoConfigurations, inputOutputFormatsMap,listHighResolution);
}
三、SurfaceHolder.class类型output size的来源
frameworks/base/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
public <T> Size[] getOutputSizes(Class<T> klass) {if (isOutputSupportedFor(klass) == false) {return null;}return getInternalFormatSizes(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,HAL_DATASPACE_UNKNOWN,/*output*/true, /*highRes*/false);
}
private Size[] getInternalFormatSizes(int format, int dataspace,boolean output, boolean highRes) {// All depth formats are non-high-res.if (dataspace == HAL_DATASPACE_DEPTH && highRes) {return new Size[0];}SparseIntArray formatsMap =!output ? mInputFormats :dataspace == HAL_DATASPACE_DEPTH ? mDepthOutputFormats :highRes ? mHighResOutputFormats :mOutputFormats;int sizesCount = formatsMap.get(format);if ( ((!output || dataspace == HAL_DATASPACE_DEPTH) && sizesCount == 0) ||(output && dataspace != HAL_DATASPACE_DEPTH && mAllOutputFormats.get(format) == 0)) {// Only throw if this is really not supported at allthrow new IllegalArgumentException("format not available");}Size[] sizes = new Size[sizesCount];int sizeIndex = 0;StreamConfiguration[] configurations =(dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations;StreamConfigurationDuration[] minFrameDurations =(dataspace == HAL_DATASPACE_DEPTH) ? mDepthMinFrameDurations : mMinFrameDurations;for (StreamConfiguration config : configurations) {int fmt = config.getFormat();if (fmt == format && config.isOutput() == output) {if (output && mListHighResolution) {// Filter slow high-res output formats; include for// highRes, remove for !highReslong duration = 0;for (int i = 0; i < minFrameDurations.length; i++) {StreamConfigurationDuration d = minFrameDurations[i];if (d.getFormat() == fmt &&d.getWidth() == config.getSize().getWidth() &&d.getHeight() == config.getSize().getHeight()) {duration = d.getDuration();break;}}if (dataspace != HAL_DATASPACE_DEPTH &&highRes != (duration > DURATION_20FPS_NS)) {continue;}}sizes[sizeIndex++] = config.getSize();}}if (sizeIndex != sizesCount) {throw new AssertionError("Too few sizes (expected " + sizesCount + ", actual " + sizeIndex + ")");}return sizes;
}
从上面代码我们不难看出SurfaceHolder.class类型的size来源于mConfigurations和mMinFrameDurations之间,这个size存在于mConfigurations,format为HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED(值为34),类型为output,然后它的最小帧率要大于20FPS(DURATION_20FPS_NS)。
public static final Key<android.hardware.camera2.params.StreamConfiguration[]> SCALER_AVAILABLE_STREAM_CONFIGURATIONS =new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.scaler.availableStreamConfigurations", android.hardware.camera2.params.StreamConfiguration[].class);
public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> SCALER_AVAILABLE_MIN_FRAME_DURATIONS =new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.scaler.availableMinFrameDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
根据前面的分析,StreamConfigurationMap中的mConfigurations和mMinFrameDurations分别来源于Key SCALER_AVAILABLE_STREAM_CONFIGURATIONS和SCALER_AVAILABLE_MIN_FRAME_DURATIONS, dump出CameraService中的characteristics,我们可以得到此两个Key中的值,下面只列举format为34的部分值:
android.scaler.availableStreamConfigurations (d000a): int32[476]......[34 4160 3120 OUTPUT ][34 4160 3120 INPUT ][34 4000 3000 OUTPUT ][34 4000 3000 INPUT ][34 3264 2448 OUTPUT ][34 3264 2448 INPUT ][34 3200 2400 OUTPUT ][34 3200 2400 INPUT ][34 2976 2976 OUTPUT ][34 2976 2976 INPUT ][34 2592 1944 OUTPUT ][34 2592 1944 INPUT ][34 2688 1512 OUTPUT ][34 2688 1512 INPUT ][34 2048 1536 OUTPUT ][34 1920 1080 OUTPUT ][34 2560 800 OUTPUT ][34 1600 1200 OUTPUT ]......android.scaler.availableMinFrameDurations (d000b): int64[420]......[34 4160 ][3120 66666666 ][34 4000 ][3000 66666666 ][34 3264 ][2448 41666666 ][34 3200 ][2400 41666666 ][34 2976 ][2976 41666666 ][34 2592 ][1944 33333333 ][34 2688 ][1512 33333333 ][34 2048 ][1536 33333333 ][34 1920 ][1080 33333333 ][34 2560 ][800 33333333 ][34 1600 ][1200 33333333 ][34 1440 ][1080 33333333 ][34 1280 ][960 33333333 ][34 1280 ]......
从上面的值我们不难发现,如果camera sensor支持类型为output,format为34的size最大可到4160x3120,但大于20fps的却只能最大到3264x2448。
四、结语
从Framework中的大于20FPS的限定,猜测原因可能是如果camera app获取的YUV数据来源就FPS很低,app后期处理这些数据或做一些视频合成的处理,画面会卡顿,影响用户体验。
android.scaler.streamConfigurationMap Key值的来源相关推荐
- 高德地图 android key,Android实现高德地图key值申请和地图显示
摘要: java 由于工做的缘由因此须要用到高德地图,因此开始记录一下.目前已经完成了开发,包括高德地图的缩放功能,逆地址编码,地图底部显示数据等.今天开始从头记录一下,你们之后仍是不要写完在记录了, ...
- 《Android studio 创建生成keystore SHA1值的申请 高德地图key值申请 android studio 打包生成apk》
开发背景:目前做车载项目,领导要求用高德地图.整理了一下,差不多就是下面的目录: 一.创建生成keystore: 二.SHA1值的申请: 三.高德地图key值申请: 四.android studio ...
- android 多层json,Android json解析:根据嵌套key值逐层获取最底层数据
需求:根据预先定义好的嵌套的key值一层层获取json最底层数据 主函数里的代码 String json1="{"code":0,"data":{&q ...
- Android Camera2 CameraCharacteristics Key 详细解说
一.简介 CameraCharacteristics 是专门用来描述相机设备属性的一个类,继承自CameraMetadata类.给对给定的相机,它里面所包含的属性都是 固定的 ,也就是我们说的静态me ...
- Android 高德地图key获取、坐标定位
前期准备 点击进入高德平台获取key **步骤一:**登录注册进入控制台 步骤二: **步骤三:**获取sha1值,以及其包名. **步骤四:**获取sha1值 步骤五:复制获取到key值 到这前期工 ...
- Redis 笔记(03)— string类型(设置key、获取key、设置过期时间、批量设置获取key、对key进行加减、对key值进行追加、获取value子串)
字符串 string 是 Redis 最简单的数据结构.Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据.不同类型的数据结构的 ...
- 替换python字典中的key值
转自:http://blog.csdn.net/jt674106399/article/details/76516186 比如有一个 a = {'a': 1} 希望变为 a = {'b' :1} 即: ...
- python字典相同key的值怎么分别取出_python字典值排序并取出前n个key值的方法
python字典值排序并取出前n个key值的方法 今天在写一个算法的过程中,得到了一个类似下面的字典: {'user1':0.456,'user2':0.999,'user3':0.789,user: ...
- QT关联容器QMap,QHash的Key值自动排序问题
QT关联容器根据key -> value映射, 元素根据key值大小排序,与插入顺序无关. 1. QMap 自动排序 2. QHash 速度更快 转载于:https://www.cnblogs ...
- 查询数据库表名,数据表信息,MySQL Key值(PRI, UNI, MUL)的含义
数据表名: SELECT TABLE_NAME FROM information_schema.`TABLES` WHERE TABLE_SCHEMA ='v53' AND TABLE_TYPE =' ...
最新文章
- 开玩笑写代码获奥斯卡?计算机图形专家这样 5 次捧回大奖!
- oracle估算大小,Oracle 估算數據庫大小的方法
- xml不利于调试_流利的接口不利于维护
- 《Java8实战》笔记(16):结论以及Java的未来
- mac怎么用终端编写c语言视频,【新手提问】有知道用mac终端编c语言的网络编程的人吗?...
- Guava入门~CharMatcher
- python内置对象是什么_#【Python】【基础知识】【内置对象常用方法】
- C语言课后习题(54)
- 微信小游戏上线发布全流程详解
- [【震撼】珠海中学曝【师生课堂互殴门】]
- 从数据结构的角度来看Mysql为什么使用B+树
- 视频直播技术之iOS端推流 1
- 计算机网络协议测试技术分析
- 爬虫——记一次奇妙的异步请求爬取
- Java:用户输入矩形的长和宽,使用带返回值的方法求该矩形的面积并输出
- lubuntu12.04将64G minSD卡 格式exFAT 转 FAT32
- 哪种性格的人,更适合转管理?
- 2019Google I/O开发者大会:Pixel 3a、Nest Hub Max,以及 AI 让生活更美好!
- c++rpg黑框游戏_RPG游戏 C++源码 文字RPG游戏
- linux games账号,在Linux上能玩Epic Games Store,附安装和使用方法
热门文章
- GrapeCity Documents for PDF[GcPDF]
- JQuery插件二--colorbox
- 9月【笔耕不辍】勋章活动获奖名单公布
- 「笔耕不辍」mysql的存储引擎详解
- 2022年天津专升本报考专业对口限制目录,升本专业课如何备考~
- html不能打开图片,HTML无法打开图片
- 64位Sql Server 2005开发版于64位Windows7旗舰版 安装过程
- python代码收费_莱斯大学学费 - 高速公路收费的python设计代码
- Activiti6.0(十二)子流程
- 计算机导论知识组织结构与分类体系,计算机导论论文参考