1. 初始化3A库并配置传感器

初始化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)与驱动实际配置一致。