3. 获取摄像头静态信息

获取摄像头静态信息 学习卡片

任务说明

在相机HAL层开发中,获取摄像头静态信息是上层应用与相机能力协商的基础。本案例目标:实现一个HAL层模块,能够枚举系统中所有摄像头设备,并读取每个摄像头的基础静态信息(如设备ID、朝向、支持的分辨率列表),以结构体形式返回给调用方。

核心实现

// camera_static_info.h
#ifndef CAMERA_STATIC_INFO_H
#define CAMERA_STATIC_INFO_H

#include <stdint.h>
#include <vector>
#include <string>

#define MAX_CAMERAS 4
#define MAX_RESOLUTIONS 16

typedef struct {
    int32_t width;
    int32_t height;
} Resolution;

typedef struct {
    int32_t camera_id;
    char device_name[64];
    int32_t facing;          // 0=rear, 1=front
    int32_t orientation;     // 顺时针角度: 0/90/180/270
    std::vector<Resolution> resolutions;
} CameraStaticInfo;

typedef struct {
    int32_t camera_count;
    CameraStaticInfo cameras[MAX_CAMERAS];
} CameraInfoList;

#endif
// camera_static_info.cpp
#include "camera_static_info.h"
#include <cstring>

// 模拟底层硬件探测:实际项目中此处替换为对V4L2或硬件寄存器的读取
static bool read_hardware_info(int32_t id, CameraStaticInfo* info) {
    if (id < 0 || id >= MAX_CAMERAS) return false;
    
    info->camera_id = id;
    snprintf(info->device_name, sizeof(info->device_name), "/dev/video%d", id);
    
    // 以下为模拟数据,真实场景中来自传感器驱动或设备树配置
    if (id == 0) {
        info->facing = 0;
        info->orientation = 90;
        info->resolutions = {{1920,1080}, {1280,720}, {640,480}};
    } else if (id == 1) {
        info->facing = 1;
        info->orientation = 270;
        info->resolutions = {{1280,720}, {640,480}};
    } else {
        return false;
    }
    return true;
}

// HAL层对外暴露的查询接口
int32_t get_camera_static_info(CameraInfoList* list) {
    if (!list) return -1;
    
    memset(list, 0, sizeof(CameraInfoList));
    list->camera_count = 0;
    
    for (int32_t id = 0; id < MAX_CAMERAS; ++id) {
        CameraStaticInfo info;
        if (read_hardware_info(id, &info)) {
            list->cameras[list->camera_count++] = info;
        }
    }
    return list->camera_count;
}
// main.cpp(调用示例)
#include <cstdio>
#include "camera_static_info.h"

int main() {
    CameraInfoList list;
    int32_t count = get_camera_static_info(&list);
    
    printf("检测到 %d 个摄像头:\n", count);
    for (int32_t i = 0; i < count; ++i) {
        CameraStaticInfo& cam = list.cameras[i];
        printf("  [%d] %s 朝向:%s 旋转:%d°\n",
               cam.camera_id, cam.device_name,
               cam.facing == 0 ? "后置" : "前置",
               cam.orientation);
        printf("      支持分辨率: ");
        for (auto& r : cam.resolutions) {
            printf("%dx%d ", r.width, r.height);
        }
        printf("\n");
    }
    return 0;
}

编译与运行

g++ -std=c++11 -o camera_info camera_static_info.cpp main.cpp
./camera_info

预期输出

检测到 2 个摄像头:
  [0] /dev/video0 朝向:后置 旋转:90°
      支持分辨率: 1920x1080 1280x720 640x480 
  [1] /dev/video1 朝向:前置 旋转:270°
      支持分辨率: 1280x720 640x480

验证方法

编译并运行程序,观察输出是否与预期一致。判定标准:
1. 程序能正确枚举出2个摄像头设备;
2. 每个摄像头的设备名、朝向、旋转角与分辨率列表与代码中模拟数据完全一致;
3. 若修改read_hardware_info中的模拟数据(如增加分辨率),重新编译后输出能同步更新。

上层调用方 main() HAL静态信息接口 get_camera_static_info() 硬件探测层 read_hardware_info() 查询请求 逐设备探测 返回CameraInfoList结构体 CameraInfoList 数据布局 camera_count=2 cameras[0]: id=0, /dev/video0 facing=后置, orientation=90° resolutions: 1920x1080, 1280x720, 640x480 cameras[1]: id=1, /dev/video1 facing=前置, orientation=270° resolutions: 1280x720, 640x480

关键说明

本案例中read_hardware_info使用模拟数据代替真实硬件读取,在实际HAL开发中,该函数内部应通过V4L2的VIDIOC_QUERYCAP、VIDIOC_ENUM_FMT等ioctl调用或读取设备树配置来获取真实参数。代码中的CameraInfoList结构体采用固定数组而非动态分配,是为了避免在HAL层引入内存管理复杂性,实际产品中可根据需要改为指针加长度字段的方式。验证时只需确认枚举数量、字段值与模拟数据一致,即证明HAL层静态信息获取链路工作正常。