目录
Android9.0 – HAL1 – preview – RAW
Android9.0 – HAL1 - snapshot – RAW
Android9.0 – HAL1 - video – RAW
Android9.0 另一种方式抓 snapshot raw 图
Android9.0 – HAL1 – preview – YUV
Android9.0 – HAL1 - snapshot – YUV
Android9.0 – HAL1 – video – YUV
Android9.0 – HAL3 – Callback – YUV
前言
简述Qcom 平台,抓取raw图、YUV图的抓取方式,和相关的代码流程。
旨在camera sensor存在比较明显的效果问题的时候,判断问题出在哪个环节。
Note:
抓取 RAW或 YUV图之前需要先确认当前Android版本和Camera APP使用的是哪种HAL接口。
HAL1或HAL3,在HAL层中 camera的这部分差异较大,实现流程不同,需要注意。
参考文档 :
kba-161204073328_2_how_to_dump_camera_image_buffer.pdf
抓取raw图的文件路径和代码:
【HAL1】 代码位置:
- HAL1 接口位置
8953_APP_P\hardware\qcom\camera\QCamera2\HAL\QCamera2HWI.cpp
- HAL1 回调函数位置
8953_APP_P\hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
- HAL1 dump 函数
void QCamera2HardwareInterface::dumpFrameToFile
- HAL1 dump 属性
- HAL1 dump JPEG 图
hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp:
2920: property_get("persist.vendor.camera.dumpimg", value, "0");
- HAL1 dump YUV 图
hardware/qcom/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp:
3097: property_get("persist.vendor.camera.dumpimg", value, "0");
【HAL3】 代码位置:
- HAL3 接口位置
hardware\qcom\camera\QCamera2\HAL3\QCamera3HWI.cpp
- HAL3 回调函数位置
hardware\qcom\camera\QCamera2\HAL3\QCamera3Channel.cpp
- HAL3 dump 函数
void QCamera3Channel::dumpYUV(...)
- HAL3 dump 属性
property_get("persist.vendor.camera.dumpimg", prop, "0");
- HAL3 dump YUV 图
hardware/qcom/camera/QCamera2/HAL3/QCamera3Channel.cpp:
542: property_get("persist.vendor.camera.dumpimg", prop, "0");
抓取注意事项
HAL 架构问题
- 首先要注意抓取的 Camera APP 使用的HAL1 还是 HAL3 架构
- 因为不同 hal 架构,所需要的抓取命令不同
数据流的时效性问题:
要抓取的这路流什么时候存在,是打开相机就存在还是需要触发才出现,
- preview:预览数据流, 打开相机预览流就开始启动了。打开相机触发。[常开流]
- video:录像数据流, 只有开启录像,这路流才存在。开启录像触发。[触发流]
- metadata:元数据配置流, 每个 Capture 都会伴随一个 metadata 流。[待补充]
- snapshot:拍照数据流, 只有拍照动作才会存在这路流。拍照触发。[触发流]
- callback:Google Camera2 相机存在这路流,请用这个App进行测试。[待补充]
- 以上基线代码默认配置的流。其他新增的流,要和APP开发人员确认什么时候流存在。
dumping mask bit 定义
参数解释:
/**
* 参数解释:
* adb shell setprop persist.vendor.camera.dumpimg 16711696
* 16711696 converted to hexadecimal is 0xFF0010 .
* Bit-16 to bit-23 specifies how many frames to dump; default is 10.
* Bit-8 to bit-15 specifies how many frames to skip during dumping; default is no skip.
// 每两帧之间的帧数间隔,如跳10帧,抓10帧:抓到的就是 第12、22、至102等10帧。
// 驱动设置isp跳2帧,即从 02 帧算第一帧。
* Bit-0 to bit-7 need to be set, corresponding to flags:
* QCAMERA_DUMP_FRM_PREVIEW –0x1
* QCAMERA_DUMP_FRM_VIDEO –0x2
* QCAMERA_DUMP_FRM_SNAPSHOT –0x4
* QCAMERA_DUMP_FRM_THUMBNAIL –0x8
* QCAMERA_DUMP_FRM_RAW –0x10 // dump raw image set to 0x10
* QCAMERA_DUMP_FRM_JPEG –0x20
*
* So when we set persist.vendor.camera.dumpimg to 16711696
* It’s means we want to dump 255 frame, no skip during dumping, dump raw image.
*/
Andorid5/8 – HAL1 – 拍照 – RAW
进入 camera app 专业模式。
- 打开相机,点击右上角设置按钮,, 连续点击 ‘连续拍照按钮”(Continuous Shot), 进入专业模式。
- 退出,然后重新进入设置。(会发现多了许多选项)。
- 关闭 zsl 、Auto HDR。
- 修改图片格式为BayerQ10BGGR。Select Picture Format --> BayerM10RGGB 等。
- 拍照,相册中会出现灰色的RAW文件。
- pull 文件。adb pull sdcard/DCIM/Camera/raw
调试 抓取拍照 RAW 图 Android9.0
进入 camera app 专业模式
1. 打开相机,右上角 设置按钮点开, 连续点击 红眼消除(Redeye Reduction), 进入专业模式
2. 关闭 zsl Auto HDR
3. 选择 照片格式 Select Picture Format --> BayerM10RGGB 等
4. 拍照
5. pull 文件 adb pull sdcard/DCIM/Camera/raw
Android9.0 – HAL1 – preview – RAW
操作步骤:
1. 修改的 data 目录权限
adb shell chmod 777 /data/vendor/camera
2. 打开 dump raw 图功能
adb shell setprop persist.vendor.camera.raw_yuv 1
3. 打开 dump preview raw 图功能
adb shell setprop persist.vendor.camera.preview_raw 1
4. 设置 dumping 命令
:: Dump preview RAW , [Qcom App], QCAMERA_DUMP_FRM_RAW –0x10
:: 0x0A0A10 [0A] 抓取 10 帧 [0A]跳过 10 帧 [10]抓取 preview RAW
adb shell setprop persist.vendor.camera.dumpimg 657936 2.
5. 打开 Qcom Camera App 进行预览
6. pull preview raw 图
adb pull /data/vendor/camera/
抓取的脚本:
[待上传...]
相关的代码:
第一步,打开dump raw 功能
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWI.cpp
调用函数:
int32_t QCamera2HardwareInterface::addPreviewChannel()
调用位置:
property_get("persist.vendor.camera.raw_yuv", value, "0");
raw_yuv = atoi(value) > 0 ? true : false;
if ( raw_yuv ) {
rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
preview_raw_stream_cb_routine,this);
...
}
第二步,打开preview raw 功能
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
调用函数:
void QCamera2HardwareInterface::preview_raw_stream_cb_routine
调用位置:
if (raw_frame != NULL) {
property_get("persist.vendor.camera.preview_raw", value, "0");
dump_preview_raw = atoi(value) > 0 ? true : false;
property_get("persist.vendor.camera.video_raw", value, "0");
dump_video_raw = atoi(value) > 0 ? true : false;
if (dump_preview_raw || (pme->mParameters.getRecordingHintValue()
&& dump_video_raw)) {
pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW);
}
stream->bufDone(raw_frame->buf_idx);
}
第三步, 设置dumping 功能
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
调用函数:
void QCamera2HardwareInterface::dumpFrameToFile
调用位置:
case QCAMERA_DUMP_FRM_RAW:
{
mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim);
snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw",
dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
}
break;
抓到的 RAW 图:
注意点:
- 使用 Qcom Camera APP 进行拍照
Android9.0 – HAL1 - snapshot – RAW
操作步骤:
1. 修改 data 目录权限
adb shell chmod 777 /data/vendor/camera
2. 打开 dump raw 功能
adb shell setprop persist.vendor.camera.raw_yuv 1
3. 打开 dump snapshot 功能
adb shell setprop persist. vendor.camera.snapshot_raw 1
4. 设置 dumpling 命令
:: Dump snapshot RAW , [Qcom App], QCAMERA_DUMP_FRM_RAW –0x10
:: 0x0A0010 [0A] 抓取 10 帧 [00]跳过 0 帧 [10]抓取 snapshot RAW
adb shell setprop persist.vendor.camera.dumpimg 655376
5. 打开 Qcom Camera App 点击拍照
6. pull snapshot raw 图
adb pull data/vendor/camera/
抓取脚本:
[待补充。。。]
相关的代码:
第一步,打开dump raw 功能
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWI.cpp
调用函数:
int32_t QCamera2HardwareInterface::addCaptureChannel()
调用位置:
property_get("persist.vendor.camera.raw_yuv", value, "0");
raw_yuv = atoi(value) > 0 ? true : false;
if (raw_yuv) {
stream_cb = snapshot_raw_stream_cb_routine;
}
第二步,打开snapshot raw 功能
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
调用函数:
void QCamera2HardwareInterface::snapshot_raw_stream_cb_routine
调用位置:
property_get("persist.vendor.camera.snapshot_raw", value, "0");
dump_raw = atoi(value) > 0 ? true : false;
for (uint32_t i = 0; i < super_frame->num_bufs; i++) {
if (super_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_RAW) {
mm_camera_buf_def_t * raw_frame = super_frame->bufs[i];
if (NULL != stream) {
if (dump_raw) {
pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW);
。。。
第三步, 设置dumping 功能
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
调用函数:
void QCamera2HardwareInterface::dumpFrameToFile
调用位置:
case QCAMERA_DUMP_FRM_RAW:
{
mParameters.getStreamDimension(CAM_STREAM_TYPE_RAW, dim);
snprintf(buf, sizeof(buf), "%dr_%dx%d_%d.raw",
dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
}
break;
抓到的 RAW 图:
注意点:
- 使用 Qcom Camera App 进行拍照
Android9.0 – HAL1 - video – RAW
- 抓取命令和设置步骤和 preview raw 步骤一样,在代码中流程是一样的。
- 只需要打开Qcom Camera2 App ,切换到录像模式即可。
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
调用位置:
void QCamera2HardwareInterface::preview_raw_stream_cb_routine
代码实现:
if (raw_frame != NULL) {
property_get("persist.vendor.camera.preview_raw", value, "0");
dump_preview_raw = atoi(value) > 0 ? true : false;
property_get("persist.vendor.camera.video_raw", value, "0");
dump_video_raw = atoi(value) > 0 ? true : false;
if (dump_preview_raw || (pme->mParameters.getRecordingHintValue()
&& dump_video_raw)) {
pme->dumpFrameToFile(stream, raw_frame, QCAMERA_DUMP_FRM_RAW);
}
stream->bufDone(raw_frame->buf_idx);
}
free(super_frame);
Android9.0 另一种方式抓 snapshot raw 图
进入 Qcom Camera App 专业模式
- 打开相机右上角设置按钮, 连续点击, 红眼消除(Redeye Reduction), 进入专业模式
- 关闭 zsl、 Auto HDR
- 选择照片格式为 Select Picture Format --> BayerM10RGGB
- 点击拍照
- pull 文件 adb pull sdcard/DCIM/Camera/raw
RAW 图裁剪参数 - 驱动配置
代码如:
prj_name:/data/vendor/camera # ls
202011261707540r_1948x1080_9.raw // 原本是 1952x1080
与驱动关系:
调整下面参数会影响 raw 的尺寸
.crop_params_array =
{
.crop_params =
{
/* Res 0 */
{
.top_crop = 0,
.bottom_crop = 0,
.left_crop = 4,
.right_crop = 0,
},
Android9.0 – HAL1 – preview – YUV
抓取步骤:
1. 修改 data 目录权限
adb shell chmod 777 /data/vendor/camera
2. 设置抓取预览YUV图(preview-yuv),跳10帧, 抓10帧
:: 0x0A0A01 [0A]抓取 10 帧 [64]跳过 10 帧 [01] QCAMERA_DUMP_FRM_PREVIEW
:: 拍照的话, 就算设置抓取8帧,每次拍照也只会抓取一帧
:: 每两帧之间的帧数间隔,如跳 10 帧,抓 10 帧:抓到的就是 第12、22、一直到 102 帧。
:: 驱动设置 isp 跳 2 帧,即从第3帧算第一帧。
adb shell setprop persist.vendor.camera.dumpimg 657921
3. 打开qcom 相机 预览
4. pull 预览 yuv 图片
adb pull data/vendor/camera/
抓取的脚本:
[待补充。。。]
相关的代码:
文件位置:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
调用位置:
void QCamera2HardwareInterface::preview_stream_cb_routine
=======>
// Dump preview frames
if (memory->isBufActive(dequeuedIdx)) {
dumpBuffer = stream->getBuffer(dequeuedIdx);
pme->dumpFrameToFile(stream, dumpBuffer, QCAMERA_DUMP_FRM_PREVIEW);
抓到的 YUV 图:
注意点:
- 根据不同设备的LCD分辨率的不同,系统会设置不同分辨率的预览尺寸。
- 这里使用M11 机器LCD分辨率,320x240, dump 的yuv 尺寸为640x360 。
Android9.0 – HAL1 - snapshot – YUV
抓取步骤:
1. 修改 data 目录权限
adb shell chmod 777 /data/vendor/camera
2. 设置抓取拍照YUV命令,跳0帧,抓1帧
// 524292 == 0x80004 QCAMERA_DUMP_FRM_SNAPSHOT –0x4
:: 0x080004 [0A]抓取 8帧 [00]跳过 00 帧 [04]抓取 snapshot [已经验证 ok]
adb shell setprop persist.vendor.camera.dumpimg 524292
3. 打开高通相机APP,拍照
4. pull yuv 图
adb pull data/vendor/camera/
抓取的脚本:
[待补充。。。]
相关的代码:
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCameraPostProc.cpp // 2418
调用位置:
// dump snapshot frame if enabled
m_parent->dumpFrameToFile(main_stream, main_frame,
QCAMERA_DUMP_FRM_INPUT_JPEG, (char *)"CPP");
抓到的 YUV 图:
注意点:
- 在拍照 yuv 中,就算设置抓取 8 帧,每次拍照也只会抓取一帧 [这里拍照了两次]
Android9.0 – HAL1 – video – YUV
抓取步骤:
1. 修改 data 目录的权限
adb shell chmod 777 /data/vendor/camera
2. 执行抓取 video yuv 的命令
:: dump hal1 video yuv 10 帧,打开 qcom app 相机, 开启录像
:: 0x0A0002 [0A]抓取 10 帧 [00]跳过 00 帧 [02]抓取 video yuv
:: 如果是拍照的,就算设置抓取 10 帧,每次拍照也只会抓取一帧
adb shell setprop persist.vendor.camera.dumpimg 655362
3. 打开 qcom app, 开始录像
4. dump video yuv 图像
adb pull data/vendor/camera
抓取的脚本:
[待补充。。。]
抓到的 YUV 图:
相关的代码:
文件路径:
hardware\qcom\camera\QCamera2\HAL\QCamera2HWICallbacks.cpp
调用函数:
void QCamera2HardwareInterface::video_stream_cb_routine
调用位置:
} else {
//Handle video batch callback
native_handle_t *nh = NULL;
pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_VIDEO);
注意点:
暂无
Android9.0 – HAL3 – Callback – YUV
抓取步骤:
修改权限
adb shell chmod 777 /data/vendor/camera
设置 duping mask
:: 0x0A6408 [0A]抓取 10 帧 [64]跳过 100 帧 [08]抓取 callback
adb shell setprop persist.vendor.camera.dumpimg 680968
查看 camera 相关的系统属性
:: 查看 camera 相关的系统属性
adb shell getprop | find "camera"
打开 camera 2相机
pull yuv 帧
adb pull /data/vendor/camera
抓取脚本:
[待补充。。。]
相关的代码:
文件位置:
hardware\qcom\camera\QCamera2\HAL3\QCamera3Channel.cpp
调用函数:
void QCamera3ProcessingChannel::streamCbRoutine
调用位置:
} else if (stream->getMyType() == CAM_STREAM_TYPE_CALLBACK) {
dumpYUV(super_frame->bufs[0], dim, offset, QCAMERA_DUMP_FRM_CALLBACK);
抓到的 YUV 图:
注意点:
- 要使用Google Camera2相机,这个相机使用HAL3架构,且具有callback 流。
Android9.0 dump Metadata
参考文档:
80-NL239-33SC_LINUX CAMERA DEBUGGING GUIDE (SIMPLIFIED CHINESE-ONLY).pdf
章节:2.3.4
dump 属性配置
adb shell setprop persist.vendor.camera.dumpmetadata 1
dump 路径文件和函数定义:
hardware\qcom\camera\QCamera2\HAL3\QCamera3HWI.cpp
void QCamera3HardwareInterface::dumpMetadataToFile(tuning_params_t &meta,
uint32_t &dumpFrameCount,
bool enabled,
const char *type,
uint32_t frameNumber)
dumo 函数调用:
handleMetadataWithLock ->
dumpMetadataToFile(*tuning_ptr,mMetaFrameCount,enabled, "Snapshot",frame_number);
默认dump 拍照(snapshot) metadata
property_get("persist.vendor.camera.dumpmetadata", prop, "0");
dumpMetadataToFile(*tuning_ptr,mMetaFrameCount,enabled, "Snapshot",frame_number);
默认dump 路径:
#define QCAMERA_DUMP_FRM_LOCATION "/data/vendor/camera/"
Demo:
雪山千古冷,独照峨嵋峰