camera 配置预览和拍照streams上报的可用尺寸列表
camera 配置预览和拍照streams上报的可用尺寸列表
1.通过查看当前dump设备的camera 信息,可以得到当前设备,相机支持的preview size和picture size和FPSRange
1.1 dump camera service信息到dump.txt 文件指令:
adb shell dumpsys media.camera > dump.txt
1.2 通过dump 信息查看相机支持的preview size和picture size 的列表。在dump结果中搜索:android.scaler.availableStreamConfigurations,出来的结果列表形式如下:
参数解释:
①第1个参数为format(图像像素格式),主要的format如下:
路径:LINUX/android/system/core/include/system$ vim graphics-base-v1.0.h
HAL_PIXEL_FORMAT_RAW16 = 32; //原始图像Raw16 数据主要用于拍照,特别是需要高质量。这些照片可以用于专业摄影或需要高动态范
//围(HDR)处理的场景
HAL_PIXEL_FORMAT_BLOB = 33; //表示是jpegstream,对应的size即平时所说的picture size;
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 34; //表示preview stream,对应的size即平时所说的preview size.
HAL_PIXEL_FORMAT_YCbCr_420_888 = 35; //常用于预览流 ,输出yuv420数据。
HAL_PIXEL_FORMAT_RAW_OPAQUE = 36; // 常用于ZSL用例,允许相机在预览模式下捕获并缓存原始数据。
HAL_PIXEL_FORMAT_RAW10 = 37; // 主要用于拍照,特别是需要高质量、未处理的原始图像数据的场景,输出RAW10
HAL_PIXEL_FORMAT_RAW12 = 38; // 主要用于拍照,特别是需要高质量场景,输出RAW12
②第二个参数:图像宽度(width)
③第三个参数:图像高度(height)
④第四个参数参数为streamType(流类型) 。OUTPUT:输出类型 ,INPUT:输入类型
android.scaler.availableStreamConfigurations (d000a): int32[216]
[54 3840 2160 INPUT ]
[35 3840 2160 INPUT ]
[34 3840 2160 INPUT ]
[54 3840 2160 OUTPUT ]
[37 3840 2160 OUTPUT ]
[36 3840 2160 OUTPUT ]
[35 3840 2160 OUTPUT ]
[34 3840 2160 OUTPUT ] //表示previewsize支持3840x2160 的输出配置
[33 3840 2160 OUTPUT ] //表示picture size支持4032x2016 的输出配置
[32 3840 2160 OUTPUT ]
[33 2688 1512 OUTPUT ]
[54 2592 1944 INPUT ]
[35 2592 1944 INPUT ]
[34 2592 1944 INPUT ]
[33 2592 1944 OUTPUT ]
[54 2560 1440 OUTPUT ]
[35 2560 1440 OUTPUT ]
[34 2560 1440 OUTPUT ]
[33 2560 1440 OUTPUT ]
....
//所以availableStreamConfigurations的输出结果中,有format=34且streamType=OUTPUT的size即为相机支持的preview size.
//同理,所有format=33且streamType=OUTPUT的size即为相机支持的picture size
1.3查看当前打开的相机,在dump结果,搜索CameraDeviceClient,出来的结果类似:
//camera 设备的个数:
Number of camera devices: 4
Number of normal camera devices: 1
Number of public camera devices visible to API1: 1
Device 0 maps to "1"
Active Camera Clients:
[
(Camera ID: 4, Cost: 66, PID: 4058, Score: 0, State: 2User Id: 0, Client Package Name: org.codeaurora.qmedia, Conflicting Client Devices: {1, 2, 3, })
]
Allowed user IDs: 0
//------------------------------------------------------------------------------------------------------//
== Camera device 1 dynamic info: == //camera id=1 未打开
Device 1 is closed, no client instance
== Camera device 2 dynamic info: == //camera id=2 未打开
Device 2 is closed, no client instance
== Camera device 3 dynamic info: == //camera id=3 未打开
Device 3 is closed, no client instance
== Camera device 4 dynamic info: == //camera id=4 信息 被打开
01-14 02:53:23 : Device 4 is open. Client instance dump: //camera 4 被客户端打开
Client priority score: 0 state: 2
Client PID: 4058 // 打开的进程id
Client package: org.codeaurora.qmedia //打开的客户端包名
CameraDeviceClient[4] (0xb400007ae8ca1550) dump: //括号里的“4”即为当前打开的camera id.
1.4 .查看相机当前设置的preview size,在dump结果中,搜索Stream configuration,Stream configuration的输出类似
Device status: ACTIVE
Stream configuration:
Operation mode: NORMAL (0)
No input stream.
Stream[0]: Output //配置的一路流数据是输出流
Consumer name: SurfaceView[org.codeaurora.qmedia/org.codeaurora.qmedia.MainActivity]#13(BLAST Consumer)13 //消费者应用是org.codeaurora.qmedia
State: 4
Dims: 3840 x 2160, format 0x22, dataspace 0x102 //format为0x22=34,这个即为preview stream,其size为3840 x2160
Max size: 0
Combined usage: 0x20900, max HAL buffers: 8 //hal最大缓冲buffer是8
1.5 查看相机支持的FPS,搜索android.control.aeAvailableTargetFpsRanges出来的结果列表形式如下:
//数据中每2个一组构成一个FPSRange,其中第1个为FPSRange的下限,第2个为FPSRange的上限。
//例如,[30 30 30 30 ]表示相机支持的FPSRange为[30 30]和[30 30].
android.control.aeAvailableTargetFpsRanges (10014): int32[4]
[30 30 30 30 ]
2.定义新增一组图像Size
在camx\src\hwl\titan17x\camxtitan17xcontext.cpp 文件中有定义一个数组:StandardImageSizes。其中配置的是支持的size.如果要新增Size,则在这个数组中添加。
static const DimensionCap StandardImageSizes[] =
{ 2976, 2976 }, // Square 291
{ 2688, 1512 }, // 4MP 292
{ 2592, 1944 }, // 5MP
+ { 2560, 1440 }, //添加一组新size
{ 2048, 1536 }, // 3MP
{ 2016, 1512 },
{ 1928, 1208 }, // For GMSL ar0231
....
2.1这个数组在camxhwenvironment.cpp文件中的InitializeDefaultImageSizeStaticCaps方法被加载到defaultImageSizes数组中:
camx/src/core/camxhwenvironment.cpp
–>InitializeDefaultImageSizeStaticCaps() 被拷贝到defaultImageSizes 数组中。
std::sort(std::begin(imageSizes), std::end(imageSizes), DimensionsComparator());
m_platformCaps[sensorIndex].numDefaultImageSizes = numImageSizes; Utils::Memcpy(m_platformCaps[sensorIndex].defaultImageSizes, //将StandardImageSizes中可用列表拷贝到
//defaultImageSizes 数组中,上报size时获取到的判断用的
// size 是从这里来的。
imageSizes,
sizeof(DimensionCap)*MaxResolutions);
3.我们对上报的列表进行自定义限制
SetAvailableStreamConfig() 方法,将需要上报的可用size列表保存到std::vector streamConfigs 向量数组中其调用链路为:
//provider启动时硬件环境的配置信息会被调用到。链路调用:
camx/src/core/camxhwinterface.cp
->HwInterface::Create() //创建硬件接口示例
-->pHwInterface->InitCaps(); //初始化硬件接口能力。
--->GetHWEnvironment()->InitCaps();
camx/src/core/camxhwenvironment.cpp
HwEnvironment::InitCaps() //函数通常用于初始化硬件环境的配置信息。在相机HAL(硬件抽象层)中,这个函数可能用于初始化相机设备的硬件能力,如支持的分辨率、帧率、格式等。
->InitializeHwEnvironmentStaticCaps()
-->InitializeScalerStaticCaps()
--->SetAvailableStreamConfig() // 设置上报preview 和snapshot 的可用size。存放到std::vector<ScalerStreamConfig> streamConfigs; 数组中
camx/src/core/camxstaticcaps.h
->std::vector<ScalerStreamConfig> //可用列表数组中
3.1.修改输入和输出预览size 的上报限制的具体实现
①InitializeScalerStaticCaps()方法中循环获取defaultImageSizes数组中的数据width,hegith.用于下面做限制时使用。
INT32 width = pPlatformCaps->defaultImageSizes[imageIndex].width;
INT32 height = pPlatformCaps->defaultImageSizes[imageIndex].height;
②输出预览size 上报限制
//预览流,yuv420 格式,
if ((ScalerAvailableFormatsImplementationDefined == pPlatformCaps->scalerFormats[format]) ||
(ScalerAvailableFormatsYCbCr420888 == pPlatformCaps->scalerFormats[format]) ||
(ScalerAvailableFormatsYCbCr420P010 == pPlatformCaps->scalerFormats[format]))
{
CAMX_LOG_INFO(CamxLogGroupHWL ,"preview mode: output :width %d * height %d ",width
,height);
//上报下面这些分辨率的尺寸,其它分辨率全部忽略掉。
if((3840 == width && 2160 == height) ||
(4000 == width && 3000 == height) ||
(1920 == width && 1080 == height) ||
(1280 == width && 720 == height) ||
(640 == width && 360 == height) ||
(2560 ==width && 1440 == height)){
CAMX_LOG_INFO(CamxLogGroupHWL ,"preview mode: output :width %d * height %d ",width ,height);
// 存放到std::vector<ScalerStreamConfig> streamConfigs; 数组中
SetAvailableStreamConfig(&(m_caps[sensorIndex].streamConfigs[numStreamConfigs]),
pPlatformCaps->scalerFormats[format], //获取的图像数据的格式
width, //图像数据的宽
height, //图像数据的高
ScalerAvailableStreamConfigurationsOutput, //设置图像数据流是输出流
&numStreamConfigs);
isResUpdatedToStreamConfiguration[format] = TRUE;
}
}
③输入预览流上报限制
//预览流,yuv420 格式,
if ((ScalerAvailableFormatsYCbCr420888 == pPlatformCaps->scalerFormats[format]) ||
(ScalerAvailableFormatsImplementationDefined == pPlatformCaps->scalerFormats[format]) ||
(ScalerAvailableFormatsYCbCr420P010 == pPlatformCaps->scalerFormats[format]))
{
//获取camxsetting.xml 配置的minReprocessInputWidth字段数值,配置输入限制的width 尺寸。
INT32 minReprocessInputWidth = static_cast<INT32>
(GetSettingsManager()->GetStaticSettings()-
>minReprocessInputWidth);
//获取camxsetting.xml 配置的minReprocessInputHeight字段数值,配置输入限制的height 尺寸。
INT32 minReprocessInputHeight = static_cast<INT32>
(GetSettingsManager()->GetStaticSettings()-
>minReprocessInputHeight);
//输出限制尺寸小于sensor size 最大能力时,同时 不是hdmi 和dp 场景,
if (((maxWidth * maxHeight) > (minReprocessInputWidth * minReprocessInputHeight)) &&
((FALSE == pSensorCaps->isHDMISensor) || (FALSE == pSensorCaps->isDPSensor)))
{
//将所有大于限制尺寸的size 存放到std::vector<ScalerStreamConfig> streamConfigs; 数组中
if ((width * height) >= (minReprocessInputWidth * minReprocessInputHeight))
{
SetAvailableStreamConfig(&(m_caps[sensorIndex].streamConfigs[numStreamConfigs]),
pPlatformCaps->scalerFormats[format],
width,
height,
ScalerAvailableStreamConfigurationsInput,
&numStreamConfigs);
isResUpdatedToInputConfig[format] = TRUE;
}
}
inReprocessInputWidth和minReprocessInputHeight 在camxsettings.xml 中的定义位置.
camx-common/settings/common/camxsettings.xml
// 输入最小width 限制
<setting>
849 <Name>Cap minimum reprocess input width exposed to Frameworks</Name>
850 <Help>
851 Cap minimum reprocess width of input dimension supported by HAL.
852 By default all sizes upto 5MP(2592x1944) will be advertised.
853 Default value of this is 2592
854 </Help>
855 <VariableName>minReprocessInputWidth</VariableName>
856 <VariableType>UINT</VariableType>
857 <SetpropKey>persist.vendor.camera.minReprocessInputWidth</SetpropKey>
858 <DefaultValue>2592</DefaultValue>
859 <Dynamic>FALSE</Dynamic>
860 </setting>
// 输入最小高度限制
<setting>
862 <Name>Cap minimum reprocess input height exposed to Frameworks</Name>
863 <Help>
864 Cap minimum reprocess height of input dimension supported by HAL.
865 By default all sizes upto 5MP(2592x1944) will be advertised.
866 Default value of this is 1944
867 </Help>
868 <VariableName>minReprocessInputHeight</VariableName>
869 <VariableType>UINT</VariableType>
870 <SetpropKey>persist.vendor.camera.minReprocessInputHeight</SetpropKey>
871 <DefaultValue>1944</DefaultValue>
872 <Dynamic>FALSE</Dynamic>
873 </setting>
4.硬件HAL 将相机支持的preview流配置信息(ScalerAvailableStreamConfigurations
)设置到静态元数据中。目的是为了让上层应用(如Camera服务或App)能够查询和使用这些配置信息。
链路调用:
src/core/chi/camxchicontext.cpp
GetCameraInfo()
InitializeStaticMetadata()
GetStaticMetadata()
GetStaticMetadataPool()
InitializeStaticMetadataPool(cameraId)
case ScalerAvailableStreamConfigurations:
{
if (!pCameraInfo->pSensorCaps->isDepthSensor)
{
count = pCameraInfo->pHwEnvironmentCaps->numStreamConfigs *
(sizeof(ScalerStreamConfig) / sizeof(INT32));
//将std::vector<ScalerStreamConfig> streamConfigs中的预览流列表放入到静态meta中
result = pStaticMetadataSlot->SetMetadataByTag(ScalerAvailableStreamConfigurations,
static_cast<VOID*>(const_cast<
ScalerStreamConfig*>(pCameraInfo->
pHwEnvironmentCaps->streamConfigs.data())),
count,
"camxContext");
}
break;
}
5.App层查询元数据:
app 通过key:CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS 获取特征属性中的可用列表。
CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String cameraId = cameraManager.getCameraIdList()[0];
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
int[] scalerAvailableStreamConfigurations = characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS);