从AndroidP 开始,高通camera系统全面使用HAL3,之前的HAL1已经被移除,对应HAL3主流的相机开发接口是camera API2 ,但是依然存在大量的使用Camera API 1开发的相机应用,为此Android专门设计了一套兼容API1调用HAL3的中间转换接口,本门主要从几个方面简要介绍下这部分相关的知识。**

  • opencamera
  • startpreview
  • takepicture
  • setparameter、getparameter

1. opencamera

相机应用在调用

Camera open(int cameraId)

时, 经过Binder IPC进入CameraService.cpp,调用的接口是

CameraService::connectHelper(....){ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and ""Camera API version %d");

ret = makeClient(......))

err <span class="token operator">=</span> client<span class="token operator">-&gt;</span><span class="token function">initialize</span><span class="token punctuation">(</span>mCameraProviderManager<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//重点分析</span>

}

通过makeClient会创建相应的client

Status CameraService::makeClient(.....) {......// Default path: HAL version is unspecified by caller, create CameraClient// based on device version reported by the HAL.switch(deviceVersion) {//Android P 之后不再存在CAMERA_DEVICE_API_VERSION_1_0case CAMERA_DEVICE_API_VERSION_1_0:if (effectiveApiLevel == API_1) {  // Camera1 API route *client = new CameraClient(....),} else { // Camera2 API route}break;case CAMERA_DEVICE_API_VERSION_3_0:case CAMERA_DEVICE_API_VERSION_3_1:case CAMERA_DEVICE_API_VERSION_3_2:case CAMERA_DEVICE_API_VERSION_3_3:case CAMERA_DEVICE_API_VERSION_3_4://API1+HAL3 对应的clientif (effectiveApiLevel == API_1) { // Camera1 API route*client = new Camera2Client(.....);} else { // Camera2 API route//API2+HAL3 对应的client*client = new CameraDeviceClient(.....);}break;default:// Should not be reachableALOGE("Unknown camera device HAL version: %d", deviceVersion);.....}
}

通过上述代码分析发现API1+HAL3对用的client是Camera2Client
其类图如下:

从上边看Camera2Client继承实现了ICamera定义的camera API1接口,但是其内部的成员变量mDevice是`Camera3Device 类型,其是针对HAL3设计的,其类的备注如下:

/*** CameraDevice for HAL devices with version CAMERA_DEVICE_API_VERSION_3_0 or higher.*/
class Camera3Device :public CameraDeviceBase,virtual public hardware::camera::device::V3_2::ICameraDeviceCallback,private camera3_callback_ops

Camera3Device类图如下:


Camera3Device内部类HalInterface中的sp<hardware::camera::device::V3_2::ICameraDeviceSession>mHidlSession成员变量,是在opencamera是获取的对象,之后所有的constructDefaultRequestSettings,configureStreams等操作,都是通过该对象与HAL3进行通信完成的。
下边给出ICameraDeviceSession类图:

该类是定义在hardware\interfaces\camera\device中,是cameraservice与cameraprovider通信的接口。
下边分析 openCamera具体流程

从流程图上看,opencamera主要完成了两件事:

  • makeclient 创建camera2client对象及Camera3Device对象
  • 初始化camera2client,真正完成打开相机的地方

从上述过程看,Camera2Client实现的是Camera API1的接口,在opencamera时,通过Camera3Device中的BpHwCameraDevice类型对象deviceInfo3->mInterface的open方法完成与HAL3通信来打开相机,并该方法返回结果为ICameraDeviceSession类型对象session,表示相机成功打开,之后所有的相机相关操作全是通过该对象完成。

2. startpreview

startPreview时序图如下:

从上述时序图看,startpreive过程主要有两个过程,

  • configureStreams
  • 将request插入到mRepeatingRequests队列中,并启动RequestThread,向HAL层不断发送processCaptureRequest申请

3. takepicture

开启相机后会启动一个拍照处理线程mCaptureSequencer:

template<typename TProviderPtr>
status_t Camera2Client::initializeImpl(TProviderPtr providerPtr)
{ATRACE_CALL();ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);status_t res;
res <span class="token operator">=</span> Camera2ClientBase<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">initialize</span><span class="token punctuation">(</span>providerPtr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>

#ifdef USE_QTI_CAMERA2CLIENT
mQTICamera2Client = new QTICamera2Client(this);
#endif

mStreamingProcessor <span class="token operator">=</span> new <span class="token function">StreamingProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-StreamProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>mFrameProcessor <span class="token operator">=</span> new <span class="token function">FrameProcessor</span><span class="token punctuation">(</span>mDevice<span class="token punctuation">,</span> this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-FrameProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mFrameProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//创建拍照处理线程并启动</span>
mCaptureSequencer <span class="token operator">=</span> new <span class="token function">CaptureSequencer</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-CaptureSeq"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mCaptureSequencer<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>mJpegProcessor <span class="token operator">=</span> new <span class="token function">JpegProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> mCaptureSequencer<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-JpegProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mJpegProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

#ifdef USE_QTI_CAMERA2CLIENT
mRawProcessor = new RawProcessor(this, mCaptureSequencer);
threadName = String8::format(“C2-%d-RawProc”,
mCameraId);
mRawProcessor->run(threadName.string());
#endif

mZslProcessor <span class="token operator">=</span> new <span class="token function">ZslProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> mCaptureSequencer<span class="token punctuation">)</span><span class="token punctuation">;</span>threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-ZslProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mZslProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>mCallbackProcessor <span class="token operator">=</span> new <span class="token function">CallbackProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-CallbkProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mCallbackProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">return</span> OK<span class="token punctuation">;</span>

}

线程中包含有一个状态机,不断检测是否有拍照命令下发,
状态机状态定义如下:

    enum CaptureState {IDLE,START,ZSL_START,ZSL_WAITING,ZSL_REPROCESSING,STANDARD_START,STANDARD_PRECAPTURE_WAIT,STANDARD_CAPTURE,STANDARD_CAPTURE_WAIT,DONE,ERROR,NUM_CAPTURE_STATES} mCaptureState;

对应的状态处理函数定义如下:

const CaptureSequencer::StateManagerCaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {&CaptureSequencer::manageIdle,&CaptureSequencer::manageStart,&CaptureSequencer::manageZslStart,&CaptureSequencer::manageZslWaiting,&CaptureSequencer::manageZslReprocessing,&CaptureSequencer::manageStandardStart,&CaptureSequencer::manageStandardPrecaptureWait,&CaptureSequencer::manageStandardCapture,&CaptureSequencer::manageStandardCaptureWait,&CaptureSequencer::manageDone,
};

在有拍照命令下发时,状态机进入下一状态START,否则一直停留在IDLE状态


bool CaptureSequencer::threadLoop() {
sp<span class="token operator">&lt;</span>Camera2Client<span class="token operator">&gt;</span> client <span class="token operator">=</span> mClient<span class="token punctuation">.</span><span class="token function">promote</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>client <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> false<span class="token punctuation">;</span>CaptureState currentState<span class="token punctuation">;</span>
<span class="token punctuation">{</span>Mutex<span class="token punctuation">:</span><span class="token punctuation">:</span>Autolock <span class="token function">l</span><span class="token punctuation">(</span>mStateMutex<span class="token punctuation">)</span><span class="token punctuation">;</span>currentState <span class="token operator">=</span> mCaptureState<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//状态机处理流程</span>
currentState <span class="token operator">=</span> <span class="token punctuation">(</span>this<span class="token operator">-&gt;</span><span class="token operator">*</span>kStateManagers<span class="token punctuation">[</span>currentState<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">(</span>client<span class="token punctuation">)</span><span class="token punctuation">;</span>Mutex<span class="token punctuation">:</span><span class="token punctuation">:</span>Autolock <span class="token function">l</span><span class="token punctuation">(</span>mStateMutex<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>currentState <span class="token operator">!=</span> mCaptureState<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span>mCaptureState <span class="token operator">!=</span> IDLE<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">ATRACE_ASYNC_END</span><span class="token punctuation">(</span>kStateNames<span class="token punctuation">[</span>mCaptureState<span class="token punctuation">]</span><span class="token punctuation">,</span> mStateTransitionCount<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span>mCaptureState <span class="token operator">=</span> currentState<span class="token punctuation">;</span>mStateTransitionCount<span class="token operator">++</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>mCaptureState <span class="token operator">!=</span> IDLE<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">ATRACE_ASYNC_BEGIN</span><span class="token punctuation">(</span>kStateNames<span class="token punctuation">[</span>mCaptureState<span class="token punctuation">]</span><span class="token punctuation">,</span> mStateTransitionCount<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">ALOGV</span><span class="token punctuation">(</span><span class="token string">"Camera %d: New capture state %s"</span><span class="token punctuation">,</span>client<span class="token operator">-&gt;</span><span class="token function">getCameraId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> kStateNames<span class="token punctuation">[</span>mCaptureState<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>mStateChanged<span class="token punctuation">.</span><span class="token function">signal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">if</span> <span class="token punctuation">(</span>mCaptureState <span class="token operator">==</span> ERRORmanageStart<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"Camera %d: Stopping capture sequencer due to error"</span><span class="token punctuation">,</span>client<span class="token operator">-&gt;</span><span class="token function">getCameraId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> false<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">return</span> true<span class="token punctuation">;</span>

}

状态图如下:

4. setparameter、getparameter

待续。。。。

android camera API1调用camera HAL3流程学习总结相关推荐

  1. MTK6735 camera 闪光灯Flashlight驱动调试流程学习

    MTK6735 camera 闪光灯Flashlight驱动调试流程学习 一.Flash驱动涉及到的文件包含: kernel-3.10/drivers/misc/mediatek/flashlight ...

  2. Android编程中调用Camera时预览画面有旋转问题的解决方法

    本文实例讲述了Android编程中调用Camera时预览画面有旋转问题的解决方法.分享给大家供大家参考,具体如下: 在调用Camera写应用的时候,前后摄像头的情况有时候是不一样的.有时候,明明后摄像 ...

  3. Android开发:调用camera API 创建MediaRecorder

    本文出自 "whithin's" 博客,请务必保留此出处http://whithin.blog.51cto.com/690417/1063573 1. add  below thr ...

  4. android 相机故障 代码 解决,android – 如何在调用Camera时解决ANR错误?

    我在主菜单中有两个按钮.我按下第一个按钮时调用相机.在这里,我没有遇到任何问题.相机正常工作.拍完照片后,我回到主菜单,再次按下第一个按钮.我在这里得到了这个问题.相机正确调用.但是当我拍照时,我得到 ...

  5. Android 利用V4L2 调用camera

    为何要使用V4L2进行开发 出于安全原因,使用Android 原生的Camera接口,必须要使用可见的surface显示摄像头的preview图像,即必须要让用户看到你的应用正在使用摄像头.另外And ...

  6. android app unlock sim pin,android Sim卡锁定 pin解锁流程学习

    1.Android自帶的pin解鎖部份在framework/base/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java ...

  7. android Sim卡锁定 pin解锁流程学习

    1.Android自帶的pin解鎖部份在framework/base/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java ...

  8. Android Camera 流程学习记录(五)—— Camera.takePicture() 流程解析

    简介 在前面的几篇笔记中,我已经把 Camera 控制流的部分梳理得比较清楚了.在 Camera 流程中,还有一个重要的部分,即数据流. Camera API 1 中,数据流主要是通过函数回调的方式, ...

  9. 骁龙camera预览拍照录像流程 api1和api2

    首先说api1的预览流程 CameraActivity的onCreate先区分是不是安全模式(锁屏进入就是安全模式),如果是安全模式会设置flag indowManager.LayoutParams. ...

  10. 25000字总结Android优秀的第三方框架、各种学习资料汇集 二 Camera、Video、指纹、聊天IM、投屏等等

    前言 前几天总结了Android中常用到的系统组件.Design组件.自定义组件等等系列 点击跳转地址: 25000字总结Android优秀的第三方框架.各种学习资料汇集 一 系统组件.Design组 ...

最新文章

  1. 二维平面内无人机的路径规划——势场法-改进
  2. 贝叶斯推断及其互联网应用(一):定理简介
  3. Get 与 Post 【总结】 (实例:从a.html到b.aspx传值)
  4. 【安全牛学习笔记】抓包嗅探
  5. android field 类型,Gradle buildConfigField 使用Hashmap ArrayList 等类型
  6. 对linux下loop设备的理解。
  7. 人,人,还是人-对需求、沟通、辅导、会议、改变、学习的狂想
  8. linux自动ping脚本,linux 自动ping ip的shell脚本
  9. 基础面试题:JSP和Servlet
  10. 如何找出电脑里的流氓软件_可怕:正版的流氓软件,100个人的电脑里99台都安装了...
  11. Kali Linux工具大全-信息收集
  12. Kubernetes总结一:初识Kubernetes
  13. 学习java第15天
  14. MySql 新增数据
  15. not annotated with HTTP method type (ex. GET, POST) 问题解决
  16. 破解IntelliJ IDEA 2017.1到2099年
  17. 【程序人生】机灵鹤七月份的月度总结
  18. 【NodeJs-5天学习】第四天存储篇① ——安装使用mysql 8.0
  19. Template by 2015ljn
  20. 开发网页需要学什么?

热门文章

  1. 韩国被申遗 (转自果壳)
  2. 如何删除动态数组的指定元素 - 回复 Splendour 的部分问题
  3. 用DropDownList做的日期
  4. android 点击屏幕 回调,Android 点击回调传递
  5. c语言复杂度为o(n)的排序算法,计数排序算法——时间复杂度O(n+k)
  6. jquery mini下载_【福利】iPhone 12 Pro Maxamp;mini预售开始啦!
  7. [译]应用内搜索功能实现 Android TV应用程序手册教程十三
  8. Xcode8报错:No code signature found
  9. C# 如何理解如下泛型约束 class AT:where T:class{}
  10. Javascript链式调用案例