最近一直在调试Android 4.4.3的Camera HAL层,对framework层到HAL的参数传递方法一直不明白,导致调试无从下手,今天总算是有点启发,也不知道对不对,但是要写出来给,一是给自己做个笔记,二是可能会对后来的朋友有些启发;
在调试Camera HAL的过程中发现,HAL层调用的许多framework层的很多回调函数,这点要注意,以前我一直以为都是只能framework向下调用HAL层的函数,而HAL层不能调用到framework层的函数,所以导致我在追踪代码的过程中有很多迷糊的地方;后来知道了这些豁然开朗;
首先第一个很关键的头文件:myandroid/system/media/camera/include/system/camera_metadata_tags.h,这个头文件中有一个很关键的enum类型camera_metadata_tag;camera_metadata_tag 中很很多tag,每个tag后面的注释部分意思是你要定义一个相应类型的enum或int32[ ]类型的数据,并把数据的值注册到系统list中,以后framework和HAL就可以通过tag中的ID匹配相应的参数值;framework层和HAL层通过查找这个tag id找到buffer list中相应的惨值;
typedef enum camera_metadata_tag {
ANDROID_COLOR_CORRECTION_MODE = // enum | public
ANDROID_COLOR_CORRECTION_START,
ANDROID_COLOR_CORRECTION_TRANSFORM, // rational[] | public
ANDROID_COLOR_CORRECTION_GAINS, // float[] | public
ANDROID_COLOR_CORRECTION_END,
ANDROID_CONTROL_AE_ANTIBANDING_MODE = // enum | public
ANDROID_CONTROL_START,
ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, // int32 | public
ANDROID_CONTROL_AE_LOCK, // enum | public
ANDROID_CONTROL_AE_MODE, // enum | public
ANDROID_CONTROL_AE_REGIONS, // int32[] | public //要定义一个public权限的int32[]数据,并把它注册到系统中;
ANDROID_CONTROL_AE_TARGET_FPS_RANGE, // int32[] | public
ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, // enum | public
ANDROID_CONTROL_AF_MODE, // enum | public //自动对焦相关?
ANDROID_CONTROL_AF_REGIONS, // int32[] | public
ANDROID_CONTROL_AF_TRIGGER,
ANDROID_CONTROL_AF_AVAILABLE_MODES, // byte[] | public //AF控制相关
ANDROID_FLASH_MODE, // enum | public //闪光灯相关?
//.......................省略部分代码.............................ANDROID_BLACK_LEVEL_LOCK = // enum | public
ANDROID_BLACK_LEVEL_START, ANDROID_BLACK_LEVEL_END, //在枚举空间层次结构中的位置。所有供应商的扩展标签必须定义在标签 >=vendor_section_start 后} camera_metadata_tag_t;
上面那些camera_metadata_tag_t中有些enum类型,有些事int32类型,他们具体指什么呢?在myandroid/hardware/imx/mx6/libcamera2/MetadaManager.cpp文件中MetadaManager::createStaticInfo(camera_metadata_t **info, bool sizeRequest)函数中;
status_t MetadaManager::createStaticInfo(camera_metadata_t **info, bool sizeRequest)
{
//.......................................
static const uint8_t availableAfModes[] = {
ANDROID_CONTROL_AF_MODE_OFF , // new add
ANDROID_CONTROL_AF_MODE_AUTO, // new add
ANDROID_CONTROL_AF_MODE_MACRO, // new add
//ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO, // new add
//ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE // new add
};
//添加对自动对焦模式的支持
ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES,
availableAfModes, sizeof(availableAfModes));
//.......................................
}
Camera HAL层是怎么获得Framework层传下来的参数呢?通过调用myandroid/system/media/camera/src/camera_metadata.c文件中的ANDROID_API接口find_camera_metadata_entry();find_camera_metadata_entry()函数的entry参数是输出指针,得到entry值;entry是一个camera_metadata_entry结构体;通过camera_metadata_entry的union指针传递参数值;
typedef struct camera_metadata_entry {
size_t index;
uint32_t tag;
uint8_t type;
size_t count;
union {
uint8_t *u8; //trigger
int32_t *i32; //trigger_id
float *f;
int64_t *i64; //timestamp
double *d;
camera_metadata_rational_t *r; //帧率相关
} data;
} camera_metadata_entry_t;
status_t MetadaManager::getFrameRate(int *value)
{
camera_metadata_entry_t streams;
int res = find_camera_metadata_entry(mCurrentRequest,
ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &streams);
if (res != NO_ERROR) {
ALOGE("%s: error reading fps range tag", __FUNCTION__);
return BAD_VALUE;
}
int v[2];
for (uint32_t i = 0; i < streams.count && i < 2; i++) {
v[i] = streams.data.i32[i]; //得到framework层的值;
}
if (v[0] > 15 && v[1] > 15) {
*value = 30;
}
else {
*value = 15;
}
return NO_ERROR;
}
framework层是怎么得到HAL层返回的值呢?
myandroid/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
//.............................................
// Check that there's a timestamp in the result metadata
CameraMetadata captureResult; //CameraMetadata.find(tag)返回camera_metadata_entry 就得到了HAL层传上来的参数;
camera_metadata_entry entry =
captureResult.find(ANDROID_SENSOR_TIMESTAMP);
if (entry.count == 0) {
SET_ERR("No timestamp provided by HAL for frame %d!",
frameNumber);
gotResult = false;
} else if (timestamp != entry.data.i64[0]) {
SET_ERR("Timestamp mismatch between shutter notify and result"
" metadata for frame %d (%lld vs %lld respectively)",
frameNumber, timestamp, entry.data.i64[0]);
gotResult = false;
}
//.............................................
}
其实myandroid/frameworks/av/include/camera/CameraMetadata.h是framework和HAL参数的中间class;类似个中间变量;以上内容全是个人理解,有错的地方还希望大家指正;一起进步;