1. 初始化3A库并配置传感器
任务说明
本案例完成高通Spectra ISP 3A库的最小初始化闭环:加载3A库、配置传感器输出参数、注册图像回调,使3A算法能够从指定缓冲区获取RAW图像数据。仅覆盖初始化与数据通路建立,不涉及具体3A算法调参。
环境依赖
- 高通Spectra ISP SDK(包含
libcamx.so与头文件camx/camx3a.h) - Linux交叉编译工具链(aarch64-linux-gnu-g++)
- 传感器驱动已通过V4L2子设备注册,设备节点
/dev/video0
关键完整代码
// 3a_init_sensor.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "camx/camx3a.h"
#define SENSOR_WIDTH 1920
#define SENSOR_HEIGHT 1080
#define BAYER_PATTERN CAMX_BAYER_RGGB
#define BIT_DEPTH 10
// 图像回调:3A库处理完一帧后调用
static void image_callback(Camx3aFrame *frame, void *user_data) {
(void)user_data;
printf("[3A] 收到图像帧: %ux%u, 格式=0x%x\n",
frame->width, frame->height, frame->format);
}
int main(void) {
Camx3aHandle handle = NULL;
Camx3aConfig config;
Camx3aSensorInfo sensor;
// 1. 创建3A库实例
Camx3aResult ret = Camx3aCreate(&handle);
if (ret != CAMX_3A_OK || handle == NULL) {
fprintf(stderr, "Camx3aCreate 失败: %d\n", ret);
return -1;
}
// 2. 配置传感器参数
memset(&sensor, 0, sizeof(sensor));
sensor.width = SENSOR_WIDTH;
sensor.height = SENSOR_HEIGHT;
sensor.bayer_pattern = BAYER_PATTERN;
sensor.bit_depth = BIT_DEPTH;
sensor.pixel_clock_hz = 120000000; // 120MHz PCLK
sensor.line_length_pck = 2200; // 含消隐的行像素数
ret = Camx3aSetSensorInfo(handle, &sensor);
if (ret != CAMX_3A_OK) {
fprintf(stderr, "Camx3aSetSensorInfo 失败: %d\n", ret);
Camx3aDestroy(handle);
return -1;
}
// 3. 设置图像回调与工作模式
memset(&config, 0, sizeof(config));
config.frame_callback = image_callback;
config.work_mode = CAMX_3A_MODE_PREVIEW;
config.input_format = CAMX_3A_INPUT_RAW;
ret = Camx3aConfigure(handle, &config);
if (ret != CAMX_3A_OK) {
fprintf(stderr, "Camx3aConfigure 失败: %d\n", ret);
Camx3aDestroy(handle);
return -1;
}
// 4. 启动3A处理
ret = Camx3aStart(handle);
if (ret != CAMX_3A_OK) {
fprintf(stderr, "Camx3aStart 失败: %d\n", ret);
Camx3aDestroy(handle);
return -1;
}
printf("3A库初始化成功,传感器已配置为 %ux%u %d-bit %s\n",
SENSOR_WIDTH, SENSOR_HEIGHT, BIT_DEPTH,
BAYER_PATTERN == CAMX_BAYER_RGGB ? "RGGB" : "other");
// 5. 模拟送入一帧图像数据(实际工程中由ISP驱动填充)
Camx3aFrame frame;
memset(&frame, 0, sizeof(frame));
frame.width = SENSOR_WIDTH;
frame.height = SENSOR_HEIGHT;
frame.format = CAMX_3A_INPUT_RAW;
frame.buffer = malloc(SENSOR_WIDTH * SENSOR_HEIGHT * 2); // 10bit 按2字节存
if (!frame.buffer) {
Camx3aStop(handle);
Camx3aDestroy(handle);
return -1;
}
memset(frame.buffer, 0x80, SENSOR_WIDTH * SENSOR_HEIGHT * 2); // 中性灰填充
ret = Camx3aProcessFrame(handle, &frame);
if (ret != CAMX_3A_OK) {
fprintf(stderr, "Camx3aProcessFrame 失败: %d\n", ret);
}
free(frame.buffer);
Camx3aStop(handle);
Camx3aDestroy(handle);
return 0;
}
编译与运行
# 交叉编译(假设SDK安装在 /opt/spectra_sdk)
aarch64-linux-gnu-gcc 3a_init_sensor.c \
-I/opt/spectra_sdk/include \
-L/opt/spectra_sdk/lib -lcamx \
-o 3a_init_sensor
# 拷贝到目标板并运行
adb push 3a_init_sensor /data/local/tmp/
adb shell "chmod +x /data/local/tmp/3a_init_sensor"
adb shell "/data/local/tmp/3a_init_sensor"
验证方法
- 通过条件:程序退出码为0,且终端依次输出以下两行日志:
3A库初始化成功,传感器已配置为 1920x1080 10-bit RGGB
[3A] 收到图像帧: 1920x1080, 格式=0x1
- 预期输出说明:
格式=0x1对应CAMX_3A_INPUT_RAW枚举值;若回调未触发或格式不符,说明传感器配置或数据通路有误。 - 常见问题:若
Camx3aCreate返回非0,检查libcamx.so是否在目标板/vendor/lib64或/system/lib64中;若Camx3aProcessFrame失败,确认传感器时序参数(PCLK、line_length)与驱动实际配置一致。