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值的来源相关推荐

  1. 高德地图 android key,Android实现高德地图key值申请和地图显示

    摘要: java 由于工做的缘由因此须要用到高德地图,因此开始记录一下.目前已经完成了开发,包括高德地图的缩放功能,逆地址编码,地图底部显示数据等.今天开始从头记录一下,你们之后仍是不要写完在记录了, ...

  2. 《Android studio 创建生成keystore SHA1值的申请 高德地图key值申请 android studio 打包生成apk》

    开发背景:目前做车载项目,领导要求用高德地图.整理了一下,差不多就是下面的目录: 一.创建生成keystore: 二.SHA1值的申请: 三.高德地图key值申请: 四.android studio ...

  3. android 多层json,Android json解析:根据嵌套key值逐层获取最底层数据

    需求:根据预先定义好的嵌套的key值一层层获取json最底层数据 主函数里的代码 String json1="{"code":0,"data":{&q ...

  4. Android Camera2 CameraCharacteristics Key 详细解说

    一.简介 CameraCharacteristics 是专门用来描述相机设备属性的一个类,继承自CameraMetadata类.给对给定的相机,它里面所包含的属性都是 固定的 ,也就是我们说的静态me ...

  5. Android 高德地图key获取、坐标定位

    前期准备 点击进入高德平台获取key **步骤一:**登录注册进入控制台 步骤二: **步骤三:**获取sha1值,以及其包名. **步骤四:**获取sha1值 步骤五:复制获取到key值 到这前期工 ...

  6. Redis 笔记(03)— string类型(设置key、获取key、设置过期时间、批量设置获取key、对key进行加减、对key值进行追加、获取value子串)

    字符串 string 是 Redis 最简单的数据结构.Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据.不同类型的数据结构的 ...

  7. 替换python字典中的key值

    转自:http://blog.csdn.net/jt674106399/article/details/76516186 比如有一个 a = {'a': 1} 希望变为 a = {'b' :1} 即: ...

  8. python字典相同key的值怎么分别取出_python字典值排序并取出前n个key值的方法

    python字典值排序并取出前n个key值的方法 今天在写一个算法的过程中,得到了一个类似下面的字典: {'user1':0.456,'user2':0.999,'user3':0.789,user: ...

  9. QT关联容器QMap,QHash的Key值自动排序问题

    QT关联容器根据key -> value映射, 元素根据key值大小排序,与插入顺序无关. 1. QMap  自动排序 2. QHash 速度更快 转载于:https://www.cnblogs ...

  10. 查询数据库表名,数据表信息,MySQL Key值(PRI, UNI, MUL)的含义

    数据表名: SELECT TABLE_NAME FROM information_schema.`TABLES` WHERE TABLE_SCHEMA ='v53' AND TABLE_TYPE =' ...

最新文章

  1. 开玩笑写代码获奥斯卡?计算机图形专家这样 5 次捧回大奖!
  2. oracle估算大小,Oracle 估算數據庫大小的方法
  3. xml不利于调试_流利的接口不利于维护
  4. 《Java8实战》笔记(16):结论以及Java的未来
  5. mac怎么用终端编写c语言视频,【新手提问】有知道用mac终端编c语言的网络编程的人吗?...
  6. Guava入门~CharMatcher
  7. python内置对象是什么_#【Python】【基础知识】【内置对象常用方法】
  8. C语言课后习题(54)
  9. 微信小游戏上线发布全流程详解
  10. [【震撼】珠海中学曝【师生课堂互殴门】]
  11. 从数据结构的角度来看Mysql为什么使用B+树
  12. 视频直播技术之iOS端推流 1
  13. 计算机网络协议测试技术分析
  14. 爬虫——记一次奇妙的异步请求爬取
  15. Java:用户输入矩形的长和宽,使用带返回值的方法求该矩形的面积并输出
  16. lubuntu12.04将64G minSD卡 格式exFAT 转 FAT32
  17. 哪种性格的人,更适合转管理?
  18. 2019Google I/O开发者大会:Pixel 3a、Nest Hub Max,以及 AI 让生活更美好!
  19. c++rpg黑框游戏_RPG游戏 C++源码 文字RPG游戏
  20. linux games账号,在Linux上能玩Epic Games Store,附安装和使用方法

热门文章

  1. GrapeCity Documents for PDF[GcPDF]
  2. JQuery插件二--colorbox
  3. 9月【笔耕不辍】勋章活动获奖名单公布
  4. 「笔耕不辍」mysql的存储引擎详解
  5. 2022年天津专升本报考专业对口限制目录,升本专业课如何备考~
  6. html不能打开图片,HTML无法打开图片
  7. 64位Sql Server 2005开发版于64位Windows7旗舰版 安装过程
  8. python代码收费_莱斯大学学费 - 高速公路收费的python设计代码
  9. Activiti6.0(十二)子流程
  10. 计算机导论知识组织结构与分类体系,计算机导论论文参考