高通camx configure_streams 初始化 和 usecase 创建流程 详解(五)

有参考: 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。

 

 

  • 类CameraUsecaseBase、UsecaseDefault、UsecaseDualCamera、UsecaseQuadCFA、UsecaseTorch和UsecaseMultiVRCamera都派生自公共类Usecase。
  • 类AdvancedCameraUsecase派生自公共类CameraUsecaseBase。
  • 类UsecaseMultiCamera派生自公共类AdvancedCameraUsecase。

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 类图及文件位置,如下图:

高通camx configure_streams 初始化 和 usecase 创建流程 详解(五)_第1张图片

高通camx configure_streams 初始化 和 usecase 创建流程 详解(五)_第2张图片

AdvancedCameraUsecase 是最常用的 usecase。下面将通过流程图描述调用的流程和在流程中调用的函数的详细信息来解释这个 usecase中的一些重要内容。同时,这也是 configure_streams 到 调用 UseCase 的整体流程。

高通camx configure_streams 初始化 和 usecase 创建流程 详解(五)_第3张图片

  1. chi_initialize_override_session: HAL3Module构造函数获取chi_hal_override_entry并调用该函数,该函数初始化所有的 Chi Override callbacks ,其中chi_initialize_override_session是其中之一。当HAL从框架接收到configure_streams()时,framework 调用chi_initialize_override_session。参考HALDevice::ConfigureStreams,它使用Camera3StreamConfig作为参数调用CHIModuleInitialize。
  2. InitializeOverrideSession:这个函数在调用SetHALOps和GetMatchingUsecase之前检查stream_config、operation mode 和其他配置项(返回selectedUsecaseId)。如果selectedUsecaseId有效,则调用CreateUsecaseObject。
  3. UsecaseFactory::CreateUsecaseObject:基于usecaseId,创建正确的usecase。在调用usecase的创建方法时,LogicalCameraInfo和StreamConfig被用作参数。
  4. AdvancedCameraUsecase::Create: 这个函数在检查StreamConfig之后调用usecase的初始化。如果初始化成功,则返回usecase handle ;如果失败,则调用Destroy。
  5. GetXMLUsecaseByName:该函数遍历usecase XML数据中的所有usecase名称,并返回查找与“UsecaseZSL”匹配的Chiusecase的句柄
  6. SelectUsecaseConfig:它调用ConfigureStream和BuildUsecase,这两个程序实质上创建了usecase级别的流,并获取与这个usecase关联的pipelines and sessions的数量。特性管道和需求也通过调用捕获。

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等

 

 

你可能感兴趣的:(android,camera)