Hal3由cameraprovicer加载并启动。
hal开始跑都是先获取硬件信息存入全局变量
从上节分析调用到
1
首先加载的时候hardware/rockchip/camera/Camera3HALModule.cpp
调用
static void initCameraHAL(void) {
ALOGI("@%s: RockChip Camera Hal3 Release version %s ", __FUNCTION__, rkHal3Version);//可以打印跟踪
……
PlatformData::init();
int ret = PlatformData::numberOfCameras();
……
}
}
hardware/rockchip/camera/common/platformdata/PlatformData.cpp
void PlatformData::init()//函数也是仅在加载库的时候调用,初始化获取所有配置参数
{……
int ret = mInstance->init();//1.ChromeCameraProfiles::init()
status_t ChromeCameraProfiles::init()
{……
getXmlConfigName();//mXmlConfigName 设置配置xml路径
status = CameraProfiles::init();//1.1
……
getDataFromXmlFile();//1.2
createConfParser();//1.3
}
1.1
status_t CameraProfiles::init()//CameraProfiles这个类用于解析xml,存放硬件信息
{……
//在后面详细注释
mCameraCommon->init(PSLConfParser::getSensorMediaDevicePath());
mSensorNames = mCameraCommon->mSensorInfo;
mCameraInfoPool.init(MAX_CAMERAS);
for (int i = 0;i < MAX_CAMERAS; i++)
mCharacteristicsKeys[i].clear();
return OK;
}
1.2
解析定义的xml文件,
void CameraProfiles::getDataFromXmlFile(void)
{
……
XML_Parser parser = ::XML_ParserCreate(nullptr);
if (nullptr == parser) {
LOGE("line:%d, parser is nullptr", __LINE__);
goto exit;
}
::XML_SetUserData(parser, this);
::XML_SetElementHandler(parser, startElement, endElement);
startElement 解析
分三大块
Supported_hardware
Android_metadata
Common
主要是第二个,解析metadata。解析函数ChromeCameraProfiles::handleAndroidStaticMetadata
和驱动的名称如果匹配上,就讲xml对应的参数填入mStaticMeta在place_camera_metadata函数中初始化,只是记录总信息,各个entity和值都是跟在mStaticMeta地址后面
存储信息结构体 | camera_metadata_t |
---|---|
entry信息开始 | camera_metadata_buffer_entry_t 0 |
entry最后一个 | camera_metadata_buffer_entry_t N-1 |
entry空白区 | |
data区 | 跟entry匹配,如果小于4字节存储在entry内部 |
data空白区 |
camera_metadata_t +(4字节对齐)+ camera_metadata_buffer_entry_t*256(256个entry)+(8字节对齐)+6688(将来可能加大)。
如果data小于4个字节直接存在entry里面的data.value否则存入data.offset为偏移量。
Rk代码静态Metadata保存规则:遍历xml里面的tag name,在android_static_tags_table这个预置静态table匹配,如果在这个静态table,然后xml的值(比如OFF等字符串),这个字串也和table的字串比较,如果有,就保存这条tag,data值就是这个字符串在静态table有匹配的值。当然这个值可能会有多个。
比较特殊的几个tag
availableInputOutputFormatsMap “IMPLEMENTATION_DEFINED,2,YCbCr_420_888,BLOB,YCbCr_420_888,2,YCbCr_420_888,BLOB”
第一个是input格式,第二个是支持的输出格式个数,接下来支持的输出格式。接下来又是重复一另外一个input,和对应的多个output。
request.availableRequestKeys和request.availableResultKeys
这里面记录了可以设置和返回的tag值。里面的tag值顺序往下记录,count会比较多
availableStreamConfigurations
availableMinFrameDurations
前面先匹配格式,然后读取分辨率,分辨率是一个字节记录宽,一个高,再存输入还是输出。后面是记录格式分辨率的延时,用8个字节记录延时,也就是两帧中断之间时间。
1.3
createConfParser()
New一个xml文件与camera名字的解析器,
std::map<int, CameraInfo*> mCameraIdToCameraInfo;
下面的IPSLConfParser* parser。
解析xml里面PSL specific section部分,解析到parser的mcaps里面
小结:以上部分其实就是解析camera的配置文件,存入CameraProfiles类,当然里面包含了主要的mStaticMeta,mCameraCommon,mCameraIdToCameraInfo几个重要的参数。
2
以上是加载模块构造函数的获取硬件参数的过程,下面是hal3的过程,和上篇稍有重复,这里再稍微说明
bool CameraProvider::initialize() {
camera_module_t *rawModule;
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);//上面应该是这加载的构造函数
……//下面是hal3的接口的一些实现
mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
struct camera_info info;
auto rc = mModule->getCameraInfo(i, &info);
addDeviceNames(i);
像普通加载一样camera_module_t,这里是真正加载hal的地方。
hardware\rockchip\camera\Camera3HALModule.cpp
是rk的入口函数
camera_module_t VISIBILITY_PUBLIC HAL_MODULE_INFO_SYM = {
NAMED_FIELD_INITIALIZER(common) {
…… //id用于加载匹配
NAMED_FIELD_INITIALIZER(id) CAMERA_HARDWARE_MODULE_ID,
……
NAMED_FIELD_INITIALIZER(methods) &hal_module_methods,
……
},
NAMED_FIELD_INITIALIZER(get_number_of_cameras) hal_get_number_of_cameras,
NAMED_FIELD_INITIALIZER(get_camera_info) hal_get_camera_info,
NAMED_FIELD_INITIALIZER(set_callbacks) hal_set_callbacks,
……
};
里面的common参数是hw_module_t结构,是所有hal模块都必须放在开始位置,返回加载的hal结构,后面有些函数属于camera私有结构。
mModule->getNumberOfCameras()
执行CameraModule::getNumberOfCameras-(直接调用)-> mModule->get_number_of_cameras(),相当于直接执行hal的hal_get_number_of_cameras
CameraModule其实就是hal的一些简单封装层
static int hal_get_number_of_cameras(void)
{……
return PlatformData::numberOfCameras();
函数定义
int PlatformData::numberOfCameras(void)
{
CameraProfiles * i = getInstance();
……
int num = (int)i->mStaticMeta.size();
return (num <= MAX_CAMERAS) ? num : MAX_CAMERAS;
}
因为在前面已经初始化了CameraProfiles类,直接返回i->mStaticMeta.size。
mModule->getCameraInfo(i, &info);同理也是执行到hal
CameraModule::getCameraInfo-> hal_get_camera_info-> PlatformData::getCameraInfo(cameraId, cameraInfo);
etadataHelper::getMetadataValue(staticMeta, ANDROID_LENS_FACING, facing);
里面的信息都是通过staticMeta来获取值
最终会存放到CameraModule类里,然后getinfo返回里面的mCameraInfoMap[index]里面还包含camera_metadata_t *static_camera_characteristics;就是之前存储的staticMeta
addDeviceNames 是将id和名字放入cameraprovider类的mCameraDeviceNames里。
到这里是加载完了hal3,之后就是等待调用了