Android Camera系统架构学习(一)

阅读了很多博客和文档,对android camera系统的架构有了一些了解,借此文总结,备忘。

1.代码总体架构,主要来自http://blog.csdn.net/luozirong/article/details/52244031的总结。


对上图的解释如下:

如上图为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_tmDevice,这个mDevice与HAL层里面的DefaultCam1Device里面的一个属性对应。CameraDeviceManagerBase顾名思义就是管理Cam1Device的。如此Camera的操作就在CameraClient中交给mHardWare,进一步交给mDevice,再进一步到了Cam1Device。

Java层:

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

Jni层:

frameworks/base/core/jni/android_hardware_Camera.cpp

Client端:

frameworks/av/camera/Camera.cpp

frameworks/av/camera/CameraBase.cpp

frameworks/av/camera/ICameraService.cpp

Service端:

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

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

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

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


2.open camera:主要来自http://blog.csdn.net/w401229755/article/details/52808559的分析

看看由最开始在camera.java中的open函数连接到cameraservice和HAL层的过程:

(这里涉及三套binder通信)

public static Camera open() {
       int numberOfCameras = getNumberOfCameras();
       CameraInfo cameraInfo = new CameraInfo();
       for (int i = 0; i < numberOfCameras; i++) {
           getCameraInfo(i, cameraInfo);
           if (cameraInfo.facing ==CameraInfo.CAMERA_FACING_BACK) {
                return new Camera(i);
           }
       }
       return null;
}

分两条分析线路,一是getNumberOfCameras()引发的,二是new Camera(i)引发的:

1)

getNumberOfCameras()调用流程如下:

--》

JNI:android_hardware_Camera_getNumberOfCameras(JNIEnv*env, jobject thiz)

--》

CameraBase: getNumberOfCameras()

--》

CameraService : getNumberOfCameras()

--》

HAL层:mModule->get_number_of_cameras();。

上面在CameraBase和CameraService直接建立起binder机制,为第一套binder通信机制。


2) new Camera(i)

--》

native_setup(new WeakReference(this),cameraId, packageName)

--》

JNI:

android_hardware_Camera_native_setup(JNIEnv*env, jobject thiz,

jobjectweak_this, jint cameraId, jstring clientPackageName)

--》

Camera.cpp : connect(cameraId,clientName,Camera::USE_CALLING_UID)

--》

cameraservice.cpp : connect(constsp<ICameraClient>& cameraClient, int cameraId,

                  const String16&clientPackageName, int clientUid, sp<ICamera>& device)

这里在Camera.cpp同样会通过getCameraService();获取CameraService的binder实例,而

cameraservice.cpp会通过newCameraClient()获取client端的binder实例,这样就建立起了双向的binder通信,这样上层对camera的操作才能获得回调响应。


接着继续看看cameraservice中的connect函数往下调的过程:

--》

CameraHardwareInterface.cpp initialize()

--》

Module.h :open_device()

--》

CamDeviceManagerBase :open()

--》

Cam1DeviceFactory.cpp :createCam1Device(String8const s8ClientAppMode, int32_t const i4OpenId)

--》

DefaultCam1Device : onInit()

--》SensorHal和ISP初始化

这里通过Cam1DeviceFactory的createCam1Device创建DefaultCam1Device,它集成自Cam1DeviceBase,而Cam1DeviceBase集成自Cam1Device,

Cam1Device和DefaultCam1Device是每个平台不同的实现,代码在

/vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform中。

而Cam1DeviceBase是android通用代码,在

/vendor/mediatek/proprietary/hardware/mtkcam/legacy/v1/device中。



3.start preview:主要参考自http://blog.csdn.net/shell812/article/details/49425703

--》

Camera.cpp :startPreview()

--》

CameraClient.cpp : startPreview()

--》

CameraClient.cpp : startCameraMode(camera_modemode)

--》

CameraClient::startPreviewMode()

调用到此,开始分为两路,一路是继续调用startPreview,并通过callback将数据返回上层,另外一路将数据塞给surface进行显示。

先来看startPreview这一路:

CameraClient::startPreviewMode()

--》

CameraHardwareInterface.h : startPreview()

--》

DefaultCam1Device:startPreview()

--》

Cam1DeviceBase:startPreview()//重要,做了四件事情,如下四个方法

{

onStartPreview();

enableDisplayClient();

mpCamClient->startPreview();

mpCamAdapter->startPreview();

}
--》

PreviewClient::startPreview()

--》

PreviewClient::initBuffers()

--》

PreviewClient::handleReturnBuffers(Vector<ImgBufQueNode>const&rvQueNode)

--》

PreviewClient::performPreviewCallback(sp<ICameraImgBuf>const&pCameraImgBuf, int32_t const msgType)

然后再通过mDataCb将数据往上回调给应用层。


接下来看显示的过程:

CameraClient::startPreviewMode()

--》

Cam1DeviceBase::setPreviewWindow(preview_stream_ops*window)

--》

DisplayClient::init()

--》

DisplayClient::enableDisplay()

--》

DisplayClient::handleReturnBuffers(Vector<ImgBufQueNode>const& rvQueNode)

--》

DisplayClient:: enquePrvOps(pStreamImgBuf);

enquePrvOps方法里就把数据塞给了由上层设置下来的surface去进行画面的绘制显示。这两条路的主要区别也就是最后的数据流向,一个是通过callback往上传,另一个是通过surface进行绘制。


4.start preview的数据来源

Startpreview做的事情还未分析完,camera数据是从哪里来的还不清楚,看回Cam1DeviceBase:startPreview()方法里,还调用了DefaultCam1Device::onStartPreview()方法,这个方法里调了Cam1DeviceBase::initCameraAdapter()去初始化一个cameraadpter,一般初始MtkDefaultCamAdapter.cpp,CamAdapter是整个Camera的管理者,负责与底层沟通,读取Buf,并负责分配Buf给各个功能操作者,并包括管理着Camer各种属性和算法,如3A,是否自动对焦等。

Cam1DeviceBase:startPreview()做的最后一件事情就是调用CamAdapter->startPreview();

--》

State:StateIdle::onStartPreview(IStateHandler*pHandler)

--》

MtkDefaultCamAdapter ::onHandleStartPreview()这里根据parameters的不同发送不同的命令

--》

Preview相关的命令由PreviewCmdQueThread接收并处理,主要是往驱动层请求数据,对于驱动返回的数据就会被送到上面提到的两个client处理了。


5.take picture:

接下来看看拍照的流程:

Framework层就不看了,从Cam1DeviceBase开始:

Cam1DeviceBase::takePicture()

--》

CamAdapter::takePicture()

--》

StateIdle::onCapture(IStateHandler*pHandler)

--》

CamAdapter::onHandleCapture()

--》

CaptureCmdQueThread::onCapture()

--》

CaptureCmdQueThread::threadLoop()

--》

CamAdapter::onCaptureThreadLoop()

--》

CapBufShot::sendCommand()

à

CapBufShot::onCmd_capture()

--》

SingleShot::startOne(SensorParam const& rSensorParam)

在这里开始往buf里装载image数据,然后就往回调:

 

CamShotImp::handleDataCallback()

--》

CamShotImp::onDataCallback(CamShotDataInfoconst& msg)

--》

CapBufShot::fgCamShotDataCb()

--》

CapBufShot::handleJpegData()

--》

CamAdapter::onCB_CompressedImage()

然后把数据给到由上层调用takepicture函数时设置的callback里往上传。


以上就是camera的open camera,start preview,take picture三个操作的主要流程。







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值