Android5.0 MTk Camera HAL层代码分析

1.    Android Camera 框架


如上图为Camera的主要框架,其中最上面的Camera.java是应用的使用的接口,它处理维护一个在java层的状态外核心功能都是通过Android_hardware_Camera这个JNI调到C++层实现的。其实他对应的是C++层的一个同名的Camera类。

在C++层的Camera类其实是Binder的client端,对应的Service端是CameraService。每次请求Camera服务时会在CameraService端创建一个CameraClient,并保存在mClient数组里面,同时返回给Client保存在Camera类的mCamera对象里面。这样子CameraService 和Client端的Camera.cpp对象就彻底撒手。对后续的关于Camera操作都是java层调用Camera.cpp,然后直接转交给mCamera,也就是调用CameraClient的方法。CameraService里面的mClient数组的最大长度就是Camera的个数。CameraService在第一次 引用的时候会通过HAL标准规范获得一个hw_module_t对象mModule。

CameraClient在创建的时候会获得mModule对象,同时还会创建一个类型为CameraHardwareInterface的mHardware对象,并通过mModule的open函数获得一个HAL设备对象hw_device_t mDevice,这个mDevice与HAL层里面的DefaultCam1Device里面的一个属性对应。CameraDeviceManagerBase顾名思义就是管理Cam1Device的。如此Camera的操作就在CameraClient中交给mHardWare,进一步交给mDevice,再进一步到了Cam1Device。

2.    关于Camera的主要代码目录:

l  Java层的:

frameworks/base/core/java/android/hardware/Camera.java 

l  Jni

frameworks/base/core/jni/android_hardware_Camera.cpp 

l  Client端

frameworks/av/camera/Camera.cpp 
frameworks/av/camera/CameraBase.cpp 
frameworks/av/camera/ICameraService.cpp 

l  Service端

frameworks/av/services/camera/libcameraservice/CameraService.cpp 

frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp 

frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp    

l  HAL层

vendor\mediatek\proprietary\hardware\mtkcam\module_hal\module\module.h

vendor\mediatek\proprietary\hardware\mtkcam\module_hal\devicemgr\CamDeviceManagerBase.cpp

vendor\mediatek\proprietary\hardware\mtkcam\v1\device\Cam1DeviceBase.cpp

3.    主要的调用过程:
1.      camera的打开的过程:

Camera.open()---->native_setup()----> android_hardware_Camera_native_setup() ----> Camera::connect()---->CameraBase::connect() ----> CameraService::conect()---->CameraService::connectHelperLocked() ----> new CameraClient()。

 2.设置Preview窗口的过程:

Camera.setPreviewDisplay() ----> setPreviewSurface----> android_hardware_Camera_setPreviewSurface() ---->Camera:: setPreviewTarget()----> c->setPreviewTarget() ---->CameraClient ----> CameraClient::setPreviewTarget()----> CameraClient::setPreviewWindow ----> CameraHardwareInterface::setPreviewWindow ----> mDevice->ops->set_preview_window (hw_device_t) ---->Cam1Device:: camera_set_preview_window() ----> Cam1Device:: setPreviewWindow()----> Cam1DeviceBase::setPreviewWindow() ----> Cam1DeviceBase::

initDisplayClient() ----> Cam1DeviceBase::initDisplayClient() ----> DisplayClient::setWindow()  ---->  DisplayClient:: set_preview_stream_ops() ----> mpStreamOps = window

3.数据被读取到图像缓冲区的过程:

Cam1DeviceBase::setPreviewWindow() ----> Cam1DeviceBase::initDisplayClient()---->IDisplayClient::createInstance() ----> DisplayClient::init()----> createDisplayThread()&& createImgBufQueue()---->Cam1DeviceBase::enableDisplayClient()---->DisplayClient::enableDisplay()---->DisplayClient::enableDisplay()----> mpDisplayThread-> postCommand(Command(Command::eID_WAKEUP)) ---->DisplayThread::threadLoop() ----> DisplayClient::onThreadLoop()---->DisplayClient::waitAndHandleReturnBuffers ---->rpBufQueue->dequeProcessor(vQueNode)----> DisplayClient::handleReturnBuffers() ----> enquePrvOps() ----> mpStreamOps->enqueue_buffer(mpStreamOps,rpImgBuf->getBufHndlPtr())

所以总体来说是在DisplayClient的init的时候创建了一个线程:

mpDisplayThread =IDisplayThread::createInstance(this)

一个队列:

mpImgBufQueue = newImgBufQueue(IImgBufProvider::eID_DISPLAY, "CameraDisplay@ImgBufQue");

然后mpDisplayThread等待ImgBufQueue有数据的时候通过dequeProcessor取到要渲染的数据,交给mpStreamOps也就是preview_stream_ops对象,其实preview_stream_ops只是对ANativeWindow的简单封装,最后调用的其实是ANativeWindow的queueBuffer函数,到这里一个流程基本结束,其实还是比较简单的,一个线程等待一个队列,有数据后把他塞到ANativeWindow中

4.在preview的时候数据的产生过程:

IImgBufQueue继承于IImgBufProvider和IImgBufProcessor数据通过IImgBufProvider提供的接口写入,通过IImgBufProcessor的接口消费,ImgBufProvidersManager是个大管家,管理着所有的IImgBufProvider,可以通过getDisplayPvdr(),getRecCBPvdr()等接口获取到对应的IImgBufProvider,然后把数据塞给他,于是对应的饥肠辘辘的消费者就开始消费了,比如DisplayClient。

         IImgBufProvider的设置过程:

DisplayClient::enableDisplay ()---->DisplayClient::setImgBufProviderClient (mpCamAdapter)----> IImgBufProviderClient::onImgBufProviderCreated(mpImgBufQueue) ---->BaseCamAdapter::

onImgBufProviderCreated(sp<IImgBufProvider>const&rpProvider) ----> ImgBufProvidersManager::setProvider()

         Camera的数据来源

         DefaultCam1Device::onStartPreview()----> Cam1DeviceBase::initCameraAdapter() ----> CamAdapter::init() ---->IPreviewCmdQueThread::createInstance() ----> CamAdapter::startPreview() ---->StateIdle::onStartPreview() ----> CamAdapter::onHandleStartPreview() ---->mpPreviewCmdQueThread->postCommand(PrvCmdCookie::eUpdate, PrvCmdCookie::eSemBefore)----> PreviewCmdQueThread::threadLoop()----> PreviewCmdQueThread::update()----> PreviewCmdQueThread::updateOne() ----> PreviewBufMgr::enqueBuffer()----> IImgBufProvider:: enqueProvider()

5.Camera 回调的过程:

以takepicture为例,Callback的设置过程

mDevice->ops->set_callbacks--> Cam1Device::camera_set_callbacks() --> Cam1DeviceBase::setCallbacks--> mpCamMsgCbInfo->mDataCb=data_cb

拍照的流程:

CamAdapter::takePicture()-> IState::onCapture() ->IStateHandler::onHandleCapture() ->CamAdapter::onHandleCapture()CamAdapter::onHandleCapture() ->CaptureCmdQueThread::onCapture() -> CaptureCmdQueThread::threadLoop() ->CamAdapter::onCaptureThreadLoop()->CapBufShot::sendCommand()->CapBufShot::onCmd_capture()-> SingleShot::startOne()在这里组装IImgBuffer

回调的流程:

SingleShot::startOne() --> CamShotImp::handleDataCallback() --> CamShotImp::onDataCallback--> CapBufShot::fgCamShotDataCb --> CapBufShot::handleJpegData  -->CamAdapter::onCB_RawImage -->mpCamMsgCbInfo->mDataCb

##注意两个两个标红的和标蓝的,他们这样就头尾对起来了。

===========================================================分割线

1.所谓的Camera主要就是从摄像头取一点数据放到LCD上显示,所以打蛇打七寸,我们首先介绍HAL层的Window对象是mpStrwamOps。而这个对象被设置的流程是:

Cam1DeviceBase::setPreviewWindow()  --->  initDisplayClient()  ---> DisplayClient::setWindow()  ---> set_preview_stream_ops()  ---> mpStreamOps = window

2.另一个面我们看下数据的获取流程,Camera HAL层数据主要通过ImgBufQueue对象传递,而这个对象最开始的赋值过程如下:

CamAdapter::takePicture() -> IState::onCapture() ->IStateHandler::onHandleCapture() -> CamAdapter::onHandleCapture()CamAdapter::onHandleCapture() -> CaptureCmdQueThread::onCapture() -> CaptureCmdQueThread::threadLoop() -> CamAdapter::onCaptureThreadLoop()->CapBufShot::sendCommand()->CapBufShot::onCmd_capture() -> SingleShot::startOne()在这里组装IImgBuffer


————————————————
版权声明:本文为CSDN博主「罗自荣」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luozirong/article/details/52244031

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android TIF (TV Input Framework) HAL层是Android系统中专门用于电视输入设备的HAL层,它提供了与电视输入设备交互的接口。本文将从以下几个方面对Android TIF HAL层进行分析: 1. TIF HAL层的结构 TIF HAL层的结构主要包括以下几个部分: - TIF HAL层接口:包含了TIF HAL层与上层应用交互的接口,包括初始化、搜索电视节目、设置电视节目等接口。 - TIF HAL层实现:包含了TIF HAL层的具体实现,与具体的电视输入设备相关。 - TIF HAL层框架:包含了TIF HAL层的框架代码,用于管理TIF HAL层的实现。 2. TIF HAL层的初始化 TIF HAL层的初始化主要包括以下几个步骤: - 加载TIF HAL层库:系统在启动时会自动加载TIF HAL层库。 - 查找TIF HAL层接口:系统通过dlsym函数查找TIF HAL层接口。 - 初始化TIF HAL层实现:系统调用TIF HAL层接口中的初始化函数初始化TIF HAL层实现。 3. TIF HAL层与电视输入设备的交互 TIF HAL层与电视输入设备的交互主要包括以下几个步骤: - 搜索电视节目:应用调用TIF HAL层接口中的搜索电视节目函数,TIF HAL层实现会向电视输入设备发送搜索电视节目的指令,并接收电视输入设备返回的电视节目信息。 - 设置电视节目:应用调用TIF HAL层接口中的设置电视节目函数,TIF HAL层实现会向电视输入设备发送设置电视节目的指令,并等待电视输入设备返回设置结果。 4. TIF HAL层的实现 TIF HAL层的具体实现与电视输入设备相关,不同的电视输入设备需要实现不同的TIF HAL层。TIF HAL层的实现需要遵循Android HAL层的规范,包括实现HAL层接口、定义HAL层结构体等。 总的来说,Android TIF HAL层是一个用于电视输入设备的HAL层,它提供了与电视输入设备交互的接口,其具体实现与电视输入设备相关。在使用Android TIF HAL层时,需要遵循Android HAL层的规范,并根据实际的电视输入设备进行相应的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值