3. 配置相机静态信息
任务说明
在Camera HAL层开发中,相机静态信息(static camera info)是上层框架获取设备能力的基础数据。本案例要求填充camera_info结构体中的关键字段,包括设备ID(device_id)、朝向(facing)、资源成本(resource_cost)等,确保上层应用能够正确识别摄像头类型与硬件约束。
核心实现
// camera_static_info.cpp
#include <unordered_map>
#include <string>
#include <vector>
#include <cutils/properties.h>
// 定义相机静态信息结构(与AOSP camera_metadata_tags.h中camera_info对应)
struct camera_info {
int device_id; // 设备ID,0表示后摄,1表示前摄
int facing; // 朝向:CAMERA_FACING_BACK=0, CAMERA_FACING_FRONT=1
int orientation; // 图像旋转角度(0/90/180/270)
int resource_cost; // 资源成本(0-100,越高表示越耗资源)
int max_num_output_streams; // 最大输出流数量
bool can_disable_shutter; // 是否支持关闭快门声
};
// 从系统属性读取设备配置
static int get_device_id(const std::string& camera_id) {
// 实际项目中可从persist.vendor.camera.ids读取,此处简化
return camera_id == "0" ? 0 : 1;
}
static int get_facing(const std::string& camera_id) {
char prop_value[PROPERTY_VALUE_MAX] = {0};
std::string prop_name = "persist.vendor.camera.facing." + camera_id;
property_get(prop_name.c_str(), prop_value, camera_id == "0" ? "0" : "1");
return atoi(prop_value);
}
static int get_orientation(const std::string& camera_id) {
char prop_value[PROPERTY_VALUE_MAX] = {0};
std::string prop_name = "persist.vendor.camera.orientation." + camera_id;
property_get(prop_name.c_str(), prop_value, camera_id == "0" ? "90" : "270");
return atoi(prop_value);
}
static int get_resource_cost(const std::string& camera_id) {
// 前摄通常与ISP共享资源,成本更高
return camera_id == "0" ? 50 : 80;
}
// 填充camera_info结构体
bool fill_camera_info(const std::string& camera_id, camera_info* info) {
if (!info || camera_id.empty()) {
return false;
}
info->device_id = get_device_id(camera_id);
info->facing = get_facing(camera_id);
info->orientation = get_orientation(camera_id);
info->resource_cost = get_resource_cost(camera_id);
info->max_num_output_streams = 3; // 标准HAL支持3路并发流
info->can_disable_shutter = true;
// 校验字段合法性
if (info->facing != 0 && info->facing != 1) {
return false;
}
if (info->orientation % 90 != 0 || info->orientation < 0 || info->orientation > 270) {
return false;
}
if (info->resource_cost < 0 || info->resource_cost > 100) {
return false;
}
return true;
}
// 测试入口
#include <cstdio>
int main() {
std::vector<std::string> camera_ids = {"0", "1"};
std::unordered_map<int, camera_info> camera_map;
for (const auto& id : camera_ids) {
camera_info info;
if (fill_camera_info(id, &info)) {
camera_map[info.device_id] = info;
printf("Camera[%s] filled: device_id=%d, facing=%d, orientation=%d, "
"resource_cost=%d, max_streams=%d, shutter_cancel=%d\n",
id.c_str(), info.device_id, info.facing, info.orientation,
info.resource_cost, info.max_num_output_streams,
info.can_disable_shutter ? 1 : 0);
} else {
printf("Failed to fill camera[%s]\n", id.c_str());
return 1;
}
}
return 0;
}
编译与运行
# 在Android源码树中编译(需包含libcutils依赖)
mmm vendor/your_module/ -j8
# 或独立编译测试(需Android NDK环境)
aarch64-linux-android28-clang++ camera_static_info.cpp \
-I$ANDROID_NDK/sysroot/usr/include \
-L$ANDROID_NDK/sysroot/usr/lib/aarch64-linux-android/28 \
-lcutils -o camera_static_info_test
# 推送至设备执行
adb push camera_static_info_test /data/local/tmp/
adb shell /data/local/tmp/camera_static_info_test
验证方法
执行测试程序后,观察输出结果。判定标准如下:
- 设备ID为0的相机输出
facing=0(后置)、orientation=90、resource_cost=50; - 设备ID为1的相机输出
facing=1(前置)、orientation=270、resource_cost=80; - 所有字段均在合法范围内(facing为0或1,orientation为90的倍数,resource_cost在0-100之间);
- 程序返回码为0,无校验失败提示。
若系统属性persist.vendor.camera.facing.0等被修改为其他值,输出应随之变化,说明配置读取链路正确。