有参考: https://www.jianshu.com/p/cfb1da9d4217
思考:camera.provider中如何实现到camera hal层的跳跃 ? 之后上层是如何配置每个 stream 的?
camera service调用到camera provider中的接口方法,现在调用到 camera provider中的 hardware/interfaces/camera/device/3.2/default/CameraDeviceSession.cpp 中的processCaptureRequest(...)方法,最终会调用到:
status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
configureStreams(...)方法,最终会调用到:
status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
这个mDevice->ops 就是 hardware/libhardware/include/hardware/camera3.h 中的 camera3_device_ops 结构体:
typedef struct camera3_device_ops {
int (*initialize)(const struct camera3_device *,
const camera3_callback_ops_t *callback_ops);
int (*configure_streams)(const struct camera3_device *,
camera3_stream_configuration_t *stream_list);
int (*register_stream_buffers)(const struct camera3_device *,
const camera3_stream_buffer_set_t *buffer_set);
const camera_metadata_t* (*construct_default_request_settings)(
const struct camera3_device *,
int type);
int (*process_capture_request)(const struct camera3_device *,
camera3_capture_request_t *request);
void (*get_metadata_vendor_tag_ops)(const struct camera3_device*,
vendor_tag_query_ops_t* ops);
void (*dump)(const struct camera3_device *, int fd);
int (*flush)(const struct camera3_device *);
/* reserved for future use */
void *reserved[8];
} camera3_device_ops_t;
这样找到在camera hal层的函数指针的映射关系。
映射到:vendor/qcom/proprietary/camx/src/core/hal/camxhal3entry.cpp 中的:
static Dispatch g_dispatchHAL3(&g_jumpTableHAL3);
看一下g_jumpTableHAL3 变量:在 vendor/qcom/proprietary/camx/src/core/hal/camxhal3.cpp 中定义的:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Jump table for HAL3
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
JumpTableHAL3 g_jumpTableHAL3 =
{
open,
get_number_of_cameras,
get_camera_info,
set_callbacks,
get_vendor_tag_ops,
open_legacy,
set_torch_mode,
init,
parallelQuery,
setCallBack,
get_tag_count,
get_all_tags,
get_section_name,
get_tag_name,
get_tag_type,
close,
initialize,
configure_streams,
construct_default_request_settings,
process_capture_request,
dump,
flush,
camera_device_status_change,
torch_mode_status_change,
process_capture_result,
notify
};
然后就可以开始我们要说的 configure_streams 了。
首先须知道以下概念:
UseCase , vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecase.h 上面有介绍类图。UseCase在camx中很有很多衍生类,这是camx针对不同的stream来建立不同的usecase对象,用来管理选择feature,并且创建 pipeline以及session。
ChiFeature, vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxfeature.h, usecase选择相应的feature,关联一组pipeline,收到request请求,根据request选择对应的feature
Node , vendro/qcom/propriatary/camx/src/core/camxnode.h ,下面有类图。Node是camx中非常重要的一个父类,是camx中处理camera 请求的一个中间节点,用于处理pipeline下发的请求,下面有类图介绍,比较重要**的Node子类已经标出来了。
pipeline , 一连串node的集合,通过pipeline下发给各个node处理。
session , 若干个有关联的pipeline的集合,用来管理pipeline,使用pipeline处理请求。
UseCase 类图及文件位置,如下图:
AdvancedCameraUsecase 是最常用的 usecase。下面将通过流程图描述调用的流程和在流程中调用的函数的详细信息来解释这个 usecase中的一些重要内容。同时,这也是 configure_streams 到 调用 UseCase 的整体流程。
CHI的驱动程序实现调用CHI override模块的 chi_hal_override_entry() 方法来设置驱动程序和CHI extension 之间的接口 。它是在 camera server 初始化期间完成的。一旦创建了 camera device (上层应用 open camera 即 创建了 camera device ), framework 调用驱动程序来实现 configure_streams ,就会调用 chi_initialize_override_session 模块。如果 override 模块希望为 streams 和其他状态(包括 per-session vendor tags )指定自定义功能,则override模块必须为 live stream 创建 pipeline ,并返回该 pipeline。HAL验证 livestream pipeline ,如果有效,则调用chi_finalize_override_session 。如果需要额外的 postprocessing pipelines,那么CHI override模块必须为每个 postprocessing topology 创建一个 pipeline ,并为处理每个pipeline 创建一个session 。此时,所有process_capture_request和process_capture结果都被转发到CHI override 模块进行进一步处理。或者,plugin 可以返回一个 NULL pipeline 来表明没有请求 override ,驱动程序应该使用它的默认行为。
标记下需要实操的重点: 根据 createnodes 中的 Topology log 画出 UseCase 的拓展图。
进阶: //TODO: 尝试修改 UseCase ,增删查改node等。