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

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

  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等。

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

  1. 高通骁龙888 5G移动平台性能详解:能否发发发 这些是关键

    今天是高通骁龙技术峰会的第二天,主要详细介绍其最新旗舰移动平台骁龙888 5G 移动平台.为什么这次叫骁龙888,不叫骁龙875呢?高通回复媒体,"8一直是高通代表着旗舰的数字,而数字8也是 ...

  2. 高通 Camx debug log控制

    某天,在某网站上看到一句话,"log开的好,问题都能搞". 问题能不能都搞好不知道,不过log开的好,对分析问题的确有很大的帮助. 高通camx的日志主要分2大模块,UMD (us ...

  3. Spring的初始化和对象创建流程

    Spring容器的初始化和对象创建流程(代码方面): 如图: 1.Spring容器初始化流程: 文字说明: 在ClassPathXmlApplicationContext的构造函数中: super(p ...

  4. Linux进程最大socket数,Linux下高并发socket最大连接数所受的各种限制(详解)

    1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每 ...

  5. 个人Internet网站创建过程详解

    个人Internet网站创建过程详解 本文通过创建Internet示范网站--自由网络(Webfree)的实例,详细叙述了Windows NT安装.WWW服务.FTP服务的配置.邮件服务.新闻讨论组服 ...

  6. Linux 高可用(HA)集群之Pacemaker详解

    大纲 说明:本来我不想写这篇博文的,因为前几篇博文都有介绍pacemaker,但是我觉得还是得写一下,试想应该会有博友需要,特别是pacemaker 1.1.8(CentOS 6.4)以后,pacem ...

  7. linux oracle 用户创建,LINUX下Oracle数据库用户创建方法详解

    本文实例分析了LINUX下Oracle数据库用户创建方法.分享给大家供大家参考,具体如下: 1)登录linux,以oracle用户登录(如果是root用户登录的,登录后用 su - oracle命令切 ...

  8. Lesson13【加餐】 损失函数的随机创建现象详解

    [Lesson 13 加餐]损失函数的随机创建现象详解   接下来,我们通过手动创建一个实例,来观察在小批梯度下降过程中,损失函数是如何根据数据数据变化而变化的,这里既是作为本节内容的一个补充,同时也 ...

  9. layui添加复选框_对layui初始化列表的CheckBox属性详解,初始化属性

    对layui初始化列表的CheckBox属性详解,初始化属性 通常layui前端页面完全按照layui官网的例子写所有的页面初始化都没有问题,但是那只是静态页面.当加入后台去动态加载页面的时候有写样式 ...

最新文章

  1. jemeter多场景混合案例_Redis 混合存储最佳实践指南
  2. Failed building wheel for netifaces
  3. Linux服务集群部署实战--MySQL、Redis、ES、RocketMQ、Zookeeper
  4. python的requests模块功能_requests模块的入门使用
  5. strict standards php报错,Bigcommerce:PHP版本升级错误解决办法_PHP教程
  6. 选择排序是外面循环的array[i]与内循环的array[j]比较。冒泡排序是内循环的相邻两个值做比较修改...
  7. 如何找对另一半--第一章 品格与择偶关系
  8. BIP学习第一课,创建一个应用和实体并设计页面(图文)
  9. python超清壁纸_python爬虫 爬取超清壁纸代码实例
  10. 什么是APS计划排程系统和生产计划排产系统?
  11. 淋巴细胞转化中PHP的作用,淋巴细胞转化试验介绍|意义
  12. 我用AI技术修万里长城
  13. 使用Python3将word文档和pdf电子书进行格式互转(兼容Windows/Linux)
  14. 直播美颜sdk是什么?它是怎么让用户”变美“的?
  15. 常见的电子器件,这篇文章总结得很到位,你还不收藏吗?
  16. 3.Garbage Collection
  17. Mybatis-Plus和Mybatis的区别
  18. LaTeX中对矩阵加行属性名称和列属性名称
  19. 使用USB 3G上网卡+树莓派搭建接受短信自动转发邮箱的服务
  20. JavaScript高级程序设计[第3版]

热门文章

  1. cmakelist生成
  2. 单芯片的人脸掌静脉识别
  3. Ubuntu安装Go及开发工具Goland
  4. 蓝桥杯单片机省赛第十一届赛题二
  5. 2021Java面试题总汇
  6. 在WordPress网站上支持代码高亮(代码着色)
  7. Visual Assis 破解
  8. 网络游戏需要多大的带宽,延迟又是怎么回事
  9. STM32F051学习- GPIO
  10. 相关性检验–Spearman秩相关系数和皮尔森相关系数