【高通SDM660平台】Camera Open 流程 及 后续更新思路
- 后续更新思路
- 一、Camera Open 总结
- 二、Camera Open 代码流程分析
- 2.1 Java 层 Camera Class 使用介绍
- 2.2 Frameworks 层 Camera.java 分析
后续更新思路
《【高通SDM660平台】(1) — Camera 驱动 Bringup Guide》
《【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析》
《【高通SDM660平台】(3) — Camera V4L2 驱动层分析 》
《【高通SDM660平台】(4) — Camera Init 初始化流程 》
《【高通SDM660平台】(5) — Camera Open 流程》
《【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程》
《【高通SDM660平台】(7) — Camera onPreview 代码流程》
《【高通SDM660平台】(8) — Camera MetaData介绍》
《【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析》
《【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析》
《【高通SDM660平台】Camera Capture 流程》
《【高通SDM660平台】Camera mm-qcamera-app 代码分析》
一、Camera Open 总结
整个Camera Open 过程总结如下:
-
Java APP 层
调用 Frameworks 层 Camera.java 中的open()
方法,
在open camera 后,才开始调用对应的getParameters()
,setParameters()
,startPreview()
等 函数,这些后续分析 -
Frameworks 层 Camera.java 中的 open()
(1) 在Camera open()
函数中,如果没有指定open 对应的camera id,则默认打开后摄
(2) 根据传入的 camera id 进行初始化
(3) 注册 EventHandler 循环监听Camera 事件
(4) 调用native_setup()
JNI 函数,并下发 camera id 、当前包名、hal层版本号 -
JNI 层 android_hardware_Camera_native_setup
(1) 调用Camera::connect()
函数,connect 为 AIDL 方法,通过binder 调用到服务端CameraService.cpp
中的CameraService::connect()
方法中
(2) 获取 Camera Class,建立专门负责与java Camera对象通信的对象
(3) 如果没有设置屏幕显示方向,则默认为0,如果不为0,调用sendCommand
下发屏幕显示方向 -
C++ Native 层
CameraService.cpp
中
(1)CameraService.cpp
是camera 初始化中讲过了,在开机时会注册好对应的cameraservice
服务
(2) 前面AIDL中,调用到CameraService.cpp
中的CameraService::connect()
方法 在该方法中,
(3) 首先检查是否存在 client ,如果存在的话直接返回
(4) 关闭所有的 flashlight 对象
(5) 调用makeClient()
创建 Camera Client 对象。 client是通过Camera2ClientBase()
进行创建的,同时创建Camera3Device
对象
(6) 调用client->initialize
对前面创建好的 Camera client 进行初始化
(7) 初始化前先对device 进行初始化 ,在Camera3Device->initialize()
中打开对应的 Camera 节点/dev/videox,进行初始化,获取到 Camera 的操作方法
(8) 初始化 Camera 默认参数
(9) 接着对创建 Camera 运行时的六大线程,
处理preview和录像 stream的线程、处理3A和人脸识别的线程、拍照流程状态机线程、处理拍照 jpeg stream 线程、处理零延时zsl stream使用的线程、处理callback的线程
二、Camera Open 代码流程分析
2.1 Java 层 Camera Class 使用介绍
先看下谷歌官方对 Camera Class 的介绍:
The Camera class is used to set image capture settings, start/stop preview,
snap pictures, and retrieve frames for encoding for video.
This Class is a client for the Camera service, which manages the actual camera hardware.
To access the device camera,
you must declare the {@link android.Manifest.permission#CAMERA} permission in your Android Manifest.
Also be sure to include the uses-feature manifest element to declare camera features used by your application.
For example,
if you use the camera and auto-focus feature, your Manifest should include the following:
uses-permission android:name = “android.permission.CAMERA”
uses-feature android:name = “android.hardware.camera”
uses-feature android:name = “android.hardware.camera.autofocus”
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
2.1.1 拍照官方流程
-
获取 Camera 对象
Obtain an instance of Camera from{@link #open(int)}
. -
获取默认参数(例如默认分辨率、帧率等 )
Get existing (default) settings with{@link #getParameters()}
. -
设置并下发 Camera 参数
If necessary, modify the returned{@link Camera.Parameters}
object and call{@link #setParameters(Camera.Parameters)}
. -
设置屏幕显示方向
If desired, call{@link #setDisplayOrientation(int)}
. -
传递一个完全初始化的
SurfaceHolder
,调用setPreviewDisplay(SurfaceHolder)
,否则无法preview
Important: Pass a fully initialized{@link SurfaceHolder}
to{@link #setPreviewDisplay(SurfaceHolder)}
.
Without a surface, the camerawill be unable to start the preview. -
调用
startPreview()
开始预览,拍照之前必须先预览
Important: Call{@link #startPreview()}
to start updating the preview surface.
Preview must be started before you can take a picture. -
调用
takePicture()
开始拍照时,等待它的回调函数回传数据
When you want, call{@link #takePicture(Camera.ShutterCallback,Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)}
to capture a photo.
Wait for the callbacks to provide the actual image data. -
拍照完后,preview会停止。如果想继续拍照,需重新调用
startPreview()
After taking a picture, preview display will have stopped.
To take morephotos, call{@link #startPreview()}
again first. -
调用
stopPreview()
停止更新预览界面
Call{@link #stopPreview()}
to stop updating the preview surface. -
调用
release()
释放Camera 资源
Important: Call{@link #release()}
to release the camera foruse by other applications.
Applications should release the cameraimmediately in{@link android.app.Activity#onPause()}
(andre-{@link #open()
} it in{@link android.app.Activity#onResume()})
.
2.1.2 录像官方流程
-
获取并初始化 Camera 对像,并调用
startPreview()
Obtain and initialize a Camera and start preview as described above. -
调用
unlock()
允许 media 进程操作Camera
Call {@link #unlock()}
to allow the media process to access the camera. -
调用
setCamera(Camera)
将 Camera 对像传递给MediaRecorder
Pass the camera to{@link android.media.MediaRecorder#setCamera(Camera)}
.
See{@link android.media.MediaRecorder}
information about video recording. -
当录像完毕后,调用
reconnect()
重新锁定Camera
When finished recording, call{@link #reconnect()}
to re-acquireand re-lock the camera. -
如果想拍照,重新preview ,然后拍照
If desired, restart preview and take more photos or videos. -
调用
stopPreview()
和release()
退出预览并释放Camera资源
Call{@link #stopPreview()}
and{@link #release()}
as described above.
This class is not thread-safe, and is meant for use from one event thread.
Most long-running operations (preview, focus, photo capture, etc) happen asynchronously and invoke callbacks as necessary.
Callbacks will be invoked on the event thread {@link #open(int)}
was called from.
This class’s methods must never be called from multiple threads at once.
Caution:
Different Android-powered devicesmay have different hardware specifications,
such as megapixel ratings and auto-focus capabilities.
In order for your application to be compatible with more devices,
you should not make assumptions about the device camera specifications.
2.2 Frameworks 层 Camera.java 分析
调用 Frameworks 层 Camera.java 中的 open() 方法,
在open camera 后,才开始调用对应的 getParameters(),setParameters(), startPreview() 等 函数,这些后续分析
Java 层中调用的 Camera Class 源码位于 frameworks/base/core/java/android/hardware/Camera.java
,
整个过程,主要工作如下:
(1) 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄
(2) 根据传入的 camera id 进行初始化
(3) 注册 EventHandler 循环监听Camera 事件
(4) 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号
@ frameworks/base/core/java/android/hardware/Camera.java
public class Camera {
private static final String TAG = “Camera”;
<span class="token keyword">private</span> CameraDataCallback mCameraDataCallback<span class="token punctuation">;</span>
<span class="token keyword">private</span> CameraMetaDataCallback mCameraMetaDataCallback<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_HAL_API_VERSION_1_0 <span class="token operator">=</span> <span class="token number">0x100</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">CameraInfo</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_FACING_BACK <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_FACING_FRONT <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_SUPPORT_MODE_ZSL <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_SUPPORT_MODE_NONZSL <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> facing<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> orientation<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">boolean</span> canDisableShutterSound<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// 1. 找开指定 id 的Camera</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Camera <span class="token function">open</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Camera</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 2. 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Camera <span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> numberOfCameras <span class="token operator">=</span> <span class="token function">getNumberOfCameras</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
CameraInfo cameraInfo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CameraInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> numberOfCameras<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">getCameraInfo</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> cameraInfo<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>facing <span class="token operator">==</span> CameraInfo<span class="token punctuation">.</span>CAMERA_FACING_BACK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Camera</span><span class="token punctuation">(</span>i<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> null<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 3. 调用 cameraInitNormal() 初始对应 id 的Camera</span>
<span class="token comment">/** used by Camera#open, Camera#open(int) */</span>
<span class="token function">Camera</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> err <span class="token operator">=</span> <span class="token function">cameraInitNormal</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> <span class="token function">cameraInitNormal</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">cameraInitVersion</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> CAMERA_HAL_API_VERSION_NORMAL_CONNECT<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -2</span>
<span class="token punctuation">}</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> <span class="token function">cameraInitVersion</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">,</span> <span class="token keyword">int</span> halVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
mShutterCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
mRawImageCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
mJpegCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
mPreviewCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
mPostviewCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
mUsingPreviewAllocation <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
mZoomListener <span class="token operator">=</span> null<span class="token punctuation">;</span>
<span class="token comment">/* ### QC ADD-ONS: START */</span>
mCameraDataCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
mCameraMetaDataCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
<span class="token comment">/* ### QC ADD-ONS: END */</span>
<span class="token comment">// 1. 注册 EventHandler 循环监听Camera 事件</span>
Looper looper<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>looper <span class="token operator">=</span> Looper<span class="token punctuation">.</span><span class="token function">myLooper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
mEventHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventHandler</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> looper<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>looper <span class="token operator">=</span> Looper<span class="token punctuation">.</span><span class="token function">getMainLooper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
mEventHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventHandler</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> looper<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
mEventHandler <span class="token operator">=</span> null<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 2. 获取当前包名</span>
String packageName <span class="token operator">=</span> ActivityThread<span class="token punctuation">.</span><span class="token function">currentOpPackageName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 3. 如果定义了 prop 属性 "camera.hal1.packagelist" , 则强制使用 HAL1</span>
<span class="token comment">//Force HAL1 if the package name falls in this bucket</span>
String packageList <span class="token operator">=</span> SystemProperties<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"camera.hal1.packagelist"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>packageList<span class="token punctuation">.</span><span class="token function">length</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
TextUtils<span class="token punctuation">.</span>StringSplitter splitter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TextUtils<span class="token punctuation">.</span>SimpleStringSplitter</span><span class="token punctuation">(</span><span class="token string">','</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
splitter<span class="token punctuation">.</span><span class="token function">setString</span><span class="token punctuation">(</span>packageList<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>String str <span class="token operator">:</span> splitter<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>packageName<span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
halVersion <span class="token operator">=</span> CAMERA_HAL_API_VERSION_1_0<span class="token punctuation">;</span>
<span class="token keyword">break</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">// 4. 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号</span>
<span class="token keyword">return</span> <span class="token function">native_setup</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">WeakReference</span><span class="token generics function"><span class="token punctuation"><</span>Camera<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> packageName<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
2.2.1 [JNI] CameraService初始化 native_setup( ) —> android_hardware_Camera_native_setup( )
java 中通过JNI 调用 native 方法,Camera JNI 代码位于
//cameraId = 0
//halVersion = -2
native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);
@ frameworks/base/core/jni/android_hardware_Camera.cpp
static const JNINativeMethod camMethods[] = {
{ “_getNumberOfCameras”, “()I”, (void )android_hardware_Camera_getNumberOfCameras },
{ “_getCameraInfo”, “(ILandroid/hardware/Camera$CameraInfo;)V”, (void)android_hardware_Camera_getCameraInfo },
{ “native_setup”, “(Ljava/lang/Object;IILjava/lang/String;)I”, (void)android_hardware_Camera_native_setup },
{ “native_release”, “()V”, (void)android_hardware_Camera_release },
{ “setPreviewSurface”, “(Landroid/view/Surface;)V”, (void )android_hardware_Camera_setPreviewSurface },
{ “setPreviewTexture”, “(Landroid/graphics/SurfaceTexture;)V”, (void )android_hardware_Camera_setPreviewTexture },
{ “setPreviewCallbackSurface”, “(Landroid/view/Surface;)V”, (void )android_hardware_Camera_setPreviewCallbackSurface },
{ “startPreview”, “()V”, (void )android_hardware_Camera_startPreview },
{ “_stopPreview”, “()V”, (void )android_hardware_Camera_stopPreview },
{ “previewEnabled”, “()Z”, (void )android_hardware_Camera_previewEnabled },
{ “setHasPreviewCallback”,"(ZZ)V", (void )android_hardware_Camera_setHasPreviewCallback },
{ “_addCallbackBuffer”, “([BI)V”, (void )android_hardware_Camera_addCallbackBuffer },
{ “native_autoFocus”, “()V”, (void )android_hardware_Camera_autoFocus },
{ “native_cancelAutoFocus”,"()V", (void )android_hardware_Camera_cancelAutoFocus },
{ “native_takePicture”, “(I)V”, (void )android_hardware_Camera_takePicture },
{ “native_setHistogramMode”,"(Z)V", (void )android_hardware_Camera_setHistogramMode },
{ “native_setMetadataCb”, “(Z)V”, (void )android_hardware_Camera_setMetadataCb },
{ “native_sendHistogramData”,"()V", (void )android_hardware_Camera_sendHistogramData },
{ “native_setLongshot”, “(Z)V”, (void )android_hardware_Camera_setLongshot },
{ “native_setParameters”, “(Ljava/lang/String;)V”, (void )android_hardware_Camera_setParameters },
{ “native_getParameters”, “()Ljava/lang/String;”, (void )android_hardware_Camera_getParameters },
{ “reconnect”, “()V”, (void)android_hardware_Camera_reconnect },
{ “lock”, “()V”, (void)android_hardware_Camera_lock },
{ “unlock”, “()V”, (void)android_hardware_Camera_unlock },
{ “startSmoothZoom”, “(I)V”, (void )android_hardware_Camera_startSmoothZoom },
{ “stopSmoothZoom”, “()V”, (void )android_hardware_Camera_stopSmoothZoom },
{ “setDisplayOrientation”,"(I)V", (void )android_hardware_Camera_setDisplayOrientation },
{ “_enableShutterSound”, “(Z)Z”, (void )android_hardware_Camera_enableShutterSound },
{ “_startFaceDetection”, “(I)V”, (void )android_hardware_Camera_startFaceDetection },
{ “_stopFaceDetection”, “()V”, (void )android_hardware_Camera_stopFaceDetection},
{ “enableFocusMoveCallback”,"(I)V", (void *)android_hardware_Camera_enableFocusMoveCallback},
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
在
// connect to camera service static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName) { // Convert jstring to String16 const char16_t *rawClientName = reinterpret_cast<const char16_t*>(env->GetStringChars(clientPackageName, NULL)); jsize rawClientNameLen = env->GetStringLength(clientPackageName); String16 clientName(rawClientName, rawClientNameLen); env->ReleaseStringChars(clientPackageName, reinterpret_cast<const jchar*>(rawClientName));
sp<span class="token generics function"><span class="token punctuation"><</span>Camera<span class="token punctuation">></span></span> camera<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>halVersion <span class="token operator">==</span> CAMERA_HAL_API_VERSION_NORMAL_CONNECT<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// -2</span> <span class="token comment">// Default path: hal version is don't care, do normal camera connect.</span> <span class="token comment">// 调用 Camera::connect() 函数,connect 为 AIDL 方法,</span> <span class="token comment">// 通过binder 调用到服务端CameraService.cpp中的 CameraService::connect() 方法中</span> camera <span class="token operator">=</span> Camera<span class="token operator">:</span><span class="token operator">:</span><span class="token function">connect</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> clientName<span class="token punctuation">,</span> Camera<span class="token operator">:</span><span class="token operator">:</span>USE_CALLING_UID<span class="token punctuation">,</span> Camera<span class="token operator">:</span><span class="token operator">:</span>USE_CALLING_PID<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">></span> <span class="token operator">+</span> <span class="token comment">// frameworks/av/camera/Camera.cpp</span> <span class="token operator">+</span> <span class="token keyword">return</span> CameraBaseT<span class="token operator">:</span><span class="token operator">:</span><span class="token function">connect</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> clientPid<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">></span> <span class="token operator">+</span> <span class="token comment">// frameworks/av/camera/CameraBase.cpp</span> <span class="token operator">+</span> sp<span class="token generics function"><span class="token punctuation"><</span>TCam<span class="token punctuation">></span></span> CameraBase<span class="token generics function"><span class="token punctuation"><</span>TCam<span class="token punctuation">,</span> TCamTraits<span class="token punctuation">></span></span><span class="token operator">:</span><span class="token operator">:</span><span class="token function">connect</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">,</span> <span class="token keyword">const</span> String16<span class="token operator">&</span> clientPackageName<span class="token punctuation">,</span> <span class="token keyword">int</span> clientUid<span class="token punctuation">,</span> <span class="token keyword">int</span> clientPid<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">{</span> <span class="token operator">+</span> <span class="token operator">-</span> sp<span class="token generics function"><span class="token punctuation"><</span>TCam<span class="token punctuation">></span></span> c <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TCam</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token operator">-</span> sp<span class="token generics function"><span class="token punctuation"><</span>TCamCallbacks<span class="token punctuation">></span></span> cl <span class="token operator">=</span> c<span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token keyword">const</span> sp<span class="token operator"><</span><span class="token operator">:</span><span class="token operator">:</span>android<span class="token operator">:</span><span class="token operator">:</span>hardware<span class="token operator">:</span><span class="token operator">:</span>ICameraService<span class="token operator">></span> cs <span class="token operator">=</span> <span class="token function">getCameraService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">+</span> TCamConnectService fnConnectService <span class="token operator">=</span> TCamTraits<span class="token operator">:</span><span class="token operator">:</span>fnConnectService<span class="token punctuation">;</span> <span class="token operator">+</span> ret <span class="token operator">=</span> <span class="token punctuation">(</span>cs<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token operator">*</span>fnConnectService<span class="token punctuation">)</span><span class="token punctuation">(</span>cl<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> <span class="token comment">/*out*/</span> <span class="token operator">&</span>c<span class="token operator">-</span><span class="token operator">></span>mCamera<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">></span> <span class="token operator">+</span> CameraTraits<span class="token generics function"><span class="token punctuation"><</span>Camera<span class="token punctuation">></span></span><span class="token operator">:</span><span class="token operator">:</span>TCamConnectService CameraTraits<span class="token generics function"><span class="token punctuation"><</span>Camera<span class="token punctuation">></span></span><span class="token operator">:</span><span class="token operator">:</span>fnConnectService <span class="token operator">=</span> <span class="token operator">+</span> <span class="token operator">&</span><span class="token operator">:</span><span class="token operator">:</span>android<span class="token operator">:</span><span class="token operator">:</span>hardware<span class="token operator">:</span><span class="token operator">:</span>ICameraService<span class="token operator">:</span><span class="token operator">:</span>connect<span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token operator">+</span> IInterface<span class="token operator">:</span><span class="token operator">:</span><span class="token function">asBinder</span><span class="token punctuation">(</span>c<span class="token operator">-</span><span class="token operator">></span>mCamera<span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">linkToDeath</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token keyword">return</span> c<span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token punctuation">}</span> <span class="token operator">+</span> <span class="token operator"><=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span> <span class="token operator"><=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> jint status <span class="token operator">=</span> Camera<span class="token operator">:</span><span class="token operator">:</span><span class="token function">connectLegacy</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> clientName<span class="token punctuation">,</span> Camera<span class="token operator">:</span><span class="token operator">:</span>USE_CALLING_UID<span class="token punctuation">,</span> camera<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> status<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// make sure camera hardware is alive</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>camera<span class="token operator">-</span><span class="token operator">></span><span class="token function">getStatus</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> NO_INIT<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 获取 Camera Class</span> jclass clazz <span class="token operator">=</span> env<span class="token operator">-</span><span class="token operator">></span><span class="token function">GetObjectClass</span><span class="token punctuation">(</span>thiz<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>clazz <span class="token operator">==</span> NULL<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// This should never happen</span> <span class="token function">jniThrowRuntimeException</span><span class="token punctuation">(</span>env<span class="token punctuation">,</span> <span class="token string">"Can't find android/hardware/Camera"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> INVALID_OPERATION<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// We use a weak reference so the Camera object can be garbage collected.</span> <span class="token comment">// The reference is only used as a proxy for callbacks.</span> sp<span class="token generics function"><span class="token punctuation"><</span>JNICameraContext<span class="token punctuation">></span></span> context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">JNICameraContext</span><span class="token punctuation">(</span>env<span class="token punctuation">,</span> weak_this<span class="token punctuation">,</span> clazz<span class="token punctuation">,</span> camera<span class="token punctuation">)</span><span class="token punctuation">;</span> context<span class="token operator">-</span><span class="token operator">></span><span class="token function">incStrong</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span>android_hardware_Camera_native_setup<span class="token punctuation">)</span><span class="token punctuation">;</span> camera<span class="token operator">-</span><span class="token operator">></span><span class="token function">setListener</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 专门负责与java Camera对象通信的对象 </span> <span class="token comment">// save context in opaque field</span> env<span class="token operator">-</span><span class="token operator">></span><span class="token function">SetLongField</span><span class="token punctuation">(</span>thiz<span class="token punctuation">,</span> fields<span class="token punctuation">.</span>context<span class="token punctuation">,</span> <span class="token punctuation">(</span>jlong<span class="token punctuation">)</span>context<span class="token punctuation">.</span><span class="token function">get</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">// Update default display orientation in case the sensor is reverse-landscape</span> CameraInfo cameraInfo<span class="token punctuation">;</span> status_t rc <span class="token operator">=</span> Camera<span class="token operator">:</span><span class="token operator">:</span><span class="token function">getCameraInfo</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> <span class="token operator">&</span>cameraInfo<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">int</span> defaultOrientation <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>orientation<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token number">90</span><span class="token operator">:</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>facing <span class="token operator">==</span> CAMERA_FACING_FRONT<span class="token punctuation">)</span> <span class="token punctuation">{</span> defaultOrientation <span class="token operator">=</span> <span class="token number">180</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token number">180</span><span class="token operator">:</span> defaultOrientation <span class="token operator">=</span> <span class="token number">180</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token number">270</span><span class="token operator">:</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>facing <span class="token operator">!=</span> CAMERA_FACING_FRONT<span class="token punctuation">)</span> <span class="token punctuation">{</span> defaultOrientation <span class="token operator">=</span> <span class="token number">180</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">default</span><span class="token operator">:</span> <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"Unexpected camera orientation %d!"</span><span class="token punctuation">,</span> cameraInfo<span class="token punctuation">.</span>orientation<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 如果没有设置屏幕显示方向,则默认为0,如果不为0,调用sendCommand 下发屏幕显示方向</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>defaultOrientation <span class="token operator">!=</span> <span class="token number">0</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">"Setting default display orientation to %d"</span><span class="token punctuation">,</span> defaultOrientation<span class="token punctuation">)</span><span class="token punctuation">;</span> rc <span class="token operator">=</span> camera<span class="token operator">-</span><span class="token operator">></span><span class="token function">sendCommand</span><span class="token punctuation">(</span>CAMERA_CMD_SET_DISPLAY_ORIENTATION<span class="token punctuation">,</span>defaultOrientation<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> NO_ERROR<span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
2.2.2 [AIDL] interface ICameraService
在前面代码中, 经过如下一系列调用,最终走到了 AIDL 层。
native_setup()
—> android_hardware_Camera_native_setup()
—> CameraBaseT::connect
—> sp<TCam> CameraBase<TCam, TCamTraits>::connect
—> ret = (cs.get()->*fnConnectService)
—> ::android::hardware::ICameraService::connect()
fnConnectService 定义如下:
CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = &::android::hardware::ICameraService::connect;
frameworks/av/camera/aidl/android/hardware/ICameraService.aidl
/**
-
Binder interface for the native camera service running in mediaserver.
-
@hide
/
interface ICameraService
{
/* Open a camera device through the old camera API */
ICamera connect(ICameraClient client, int cameraId, String opPackageName, int clientUid, int clientPid);/** Open a camera device through the new camera API Only supported for device HAL versions >= 3.2 */
ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,String opPackageName,int clientUid);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
AIDL 中,我们走的是老方法, ICamera connect().
AIDL——Android Interface Definition Language,是一种接口定义语言,用于生成可以在Android设备上两个进程间进行通信的代码。
Android Java Service Framework提供的大多数系统服务都是使用AIDL语言生成的。使用AIDL语言,可以自动生成服务接口、服务代理、服务Stub代码。
2.2.3 [Native] CameraService.cpp
通过 AIDL 的 Binder 通信,跳转到 CameraService.cpp 中。
CameraService.cpp 是camera 初始化中讲过了,在开机时会注册好对应的 cameraservice 服务
还记得前面我们 《【高通SDM660平台】Camera Init 初始化流程》文章中,CameraService 服务已经注册好了,
此时就是通过Binder通信,调用CameraService 服务中的 connect 方法:
@frameworks/av/services/camera/libcameraservice/CameraService.cpp Status CameraService::connect( const sp<ICameraClient>& cameraClient, int cameraId, const String16& clientPackageName, int clientUid, int clientPid, /*out*/ sp<ICamera>* device) {
String8 id <span class="token operator">=</span> String8<span class="token operator">::</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"%d"</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span> sp<span class="token operator"><</span>Client<span class="token operator">></span> client <span class="token operator">=</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span> ret <span class="token operator">=</span> connectHelper<span class="token operator"><</span>ICameraClient<span class="token punctuation">,</span>Client<span class="token operator">></span><span class="token punctuation">(</span>cameraClient<span class="token punctuation">,</span> id<span class="token punctuation">,</span> CAMERA_HAL_API_VERSION_UNSPECIFIED<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> API_1<span class="token punctuation">,</span> <span class="token comment">/*legacyMode*/</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">/*shimUpdateOnly*/</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">/*out*/</span>client<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">*</span>device <span class="token operator">=</span> client<span class="token punctuation">;</span> <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
进入 connectHelper 函数看下:
- 检查 Client 的权限
- 如果已存在 client 则直接返回
- 在打开Camera 前,所有Flashlight 都应该被关闭
- 调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象
- 调用client->initialize对前面创建好的 Camera client 进行初始化
template<class CALLBACK, class CLIENT> binder::Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, int halVersion, const String16& clientPackageName, int clientUid, int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, /*out*/sp<CLIENT>& device) { binder::Status ret = binder::Status::ok();
String8 <span class="token function">clientName8</span><span class="token punctuation">(</span>clientPackageName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">int</span> originalClientPid <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token function">ALOGI</span><span class="token punctuation">(</span><span class="token string">"CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "</span> <span class="token string">"Camera API version %d"</span><span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> clientName8<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> cameraId<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>halVersion <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token string">"default"</span> <span class="token punctuation">:</span> std<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">to_string</span><span class="token punctuation">(</span>halVersion<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> static_cast<span class="token operator"><</span><span class="token keyword">int</span><span class="token operator">></span><span class="token punctuation">(</span>effectiveApiLevel<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> sp<span class="token operator"><</span>CLIENT<span class="token operator">></span> client <span class="token operator">=</span> nullptr<span class="token punctuation">;</span> <span class="token punctuation">{</span> <span class="token comment">// 1. 检查 Client 的权限</span> <span class="token comment">// Enforce client permissions and do basic sanity checks</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>ret <span class="token operator">=</span> <span class="token function">validateConnectLocked</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> clientName8<span class="token punctuation">,</span> <span class="token comment">/*inout*/</span>clientUid<span class="token punctuation">,</span> <span class="token comment">/*inout*/</span>clientPid<span class="token punctuation">,</span> <span class="token comment">/*out*/</span>originalClientPid<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isOk</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> ret<span class="token punctuation">;</span> <span class="token punctuation">}</span> sp<span class="token operator"><</span>BasicClient<span class="token operator">></span> clientTmp <span class="token operator">=</span> nullptr<span class="token punctuation">;</span> std<span class="token punctuation">:</span><span class="token punctuation">:</span>shared_ptr<span class="token operator"><</span>resource_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>ClientDescriptor<span class="token operator"><</span>String8<span class="token punctuation">,</span> sp<span class="token operator"><</span>BasicClient<span class="token operator">>></span><span class="token operator">></span> partial<span class="token punctuation">;</span> err <span class="token operator">=</span> <span class="token function">handleEvictionsLocked</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> originalClientPid<span class="token punctuation">,</span> effectiveApiLevel<span class="token punctuation">,</span> IInterface<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">asBinder</span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">)</span><span class="token punctuation">,</span> clientName8<span class="token punctuation">,</span> <span class="token comment">/*out*/</span><span class="token operator">&</span>clientTmp<span class="token punctuation">,</span> <span class="token comment">/*out*/</span><span class="token operator">&</span>partial<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2. 如果已存在 client 则直接返回</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>clientTmp<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> nullptr<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Handle special case for API1 MediaRecorder where the existing client is returned</span> device <span class="token operator">=</span> static_cast<span class="token operator"><</span>CLIENT<span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span>clientTmp<span class="token punctuation">.</span><span class="token function">get</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> ret<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 3. 在打开Camera 前,所有Flashlight 都应该被关闭</span> <span class="token comment">// give flashlight a chance to close devices if necessary.</span> mFlashlight<span class="token operator">-></span><span class="token function">prepareDeviceOpen</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// TODO: Update getDeviceVersion + HAL interface to use strings for Camera IDs</span> <span class="token keyword">int</span> id <span class="token operator">=</span> <span class="token function">cameraIdToInt</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">int</span> facing <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">int</span> deviceVersion <span class="token operator">=</span> <span class="token function">getDeviceVersion</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> <span class="token comment">/*out*/</span><span class="token operator">&</span>facing<span class="token punctuation">)</span><span class="token punctuation">;</span> sp<span class="token operator"><</span>BasicClient<span class="token operator">></span> tmp <span class="token operator">=</span> nullptr<span class="token punctuation">;</span> <span class="token comment">// 4. 调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>ret <span class="token operator">=</span> <span class="token function">makeClient</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> cameraCb<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> id<span class="token punctuation">,</span> facing<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> <span class="token function">getpid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> legacyMode<span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">,</span> effectiveApiLevel<span class="token punctuation">,</span> <span class="token comment">/*out*/</span><span class="token operator">&</span>tmp<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isOk</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> ret<span class="token punctuation">;</span> <span class="token punctuation">}</span> client <span class="token operator">=</span> static_cast<span class="token operator"><</span>CLIENT<span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span>tmp<span class="token punctuation">.</span><span class="token function">get</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">// Camera2Client</span> <span class="token function">LOG_ALWAYS_FATAL_IF</span><span class="token punctuation">(</span>client<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> nullptr<span class="token punctuation">,</span> <span class="token string">"%s: CameraService in invalid state"</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5. 调用client->initialize对前面创建好的 Camera client 进行初始化</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>err <span class="token operator">=</span> client<span class="token operator">-></span><span class="token function">initialize</span><span class="token punctuation">(</span>mModule<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> OK<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">"%s: Could not initialize client from HAL module."</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Errors could be from the HAL module open call or from AppOpsManager</span> <span class="token keyword">switch</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> BAD_VALUE<span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_ILLEGAL_ARGUMENT<span class="token punctuation">,</span> <span class="token string">"Illegal argument to HAL module for camera \"%s\""</span><span class="token punctuation">,</span> cameraId<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 keyword">case</span> <span class="token operator">-</span>EBUSY<span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_CAMERA_IN_USE<span class="token punctuation">,</span> <span class="token string">"Camera \"%s\" is already open"</span><span class="token punctuation">,</span> cameraId<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 keyword">case</span> <span class="token operator">-</span>EUSERS<span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_MAX_CAMERAS_IN_USE<span class="token punctuation">,</span> <span class="token string">"Too many cameras already open, cannot open camera \"%s\""</span><span class="token punctuation">,</span> cameraId<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 keyword">case</span> PERMISSION_DENIED<span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_PERMISSION_DENIED<span class="token punctuation">,</span> <span class="token string">"No permission to open camera \"%s\""</span><span class="token punctuation">,</span> cameraId<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 keyword">case</span> <span class="token operator">-</span>EACCES<span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_DISABLED<span class="token punctuation">,</span> <span class="token string">"Camera \"%s\" disabled by policy"</span><span class="token punctuation">,</span> cameraId<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 keyword">case</span> <span class="token operator">-</span>ENODEV<span class="token punctuation">:</span> <span class="token keyword">default</span><span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_INVALID_OPERATION<span class="token punctuation">,</span> <span class="token string">"Failed to initialize camera \"%s\": %s (%d)"</span><span class="token punctuation">,</span> cameraId<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 function">strerror</span><span class="token punctuation">(</span><span class="token operator">-</span>err<span class="token punctuation">)</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Update shim paremeters for legacy clients</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>effectiveApiLevel <span class="token operator">==</span> API_1<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Assume we have always received a Client subclass for API1</span> sp<span class="token operator"><</span>Client<span class="token operator">></span> shimClient <span class="token operator">=</span> reinterpret_cast<span class="token operator"><</span>Client<span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span>client<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> String8 rawParams <span class="token operator">=</span> shimClient<span class="token operator">-></span><span class="token function">getParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> CameraParameters <span class="token function">params</span><span class="token punctuation">(</span>rawParams<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">auto</span> cameraState <span class="token operator">=</span> <span class="token function">getCameraState</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cameraState <span class="token operator">!=</span> nullptr<span class="token punctuation">)</span> <span class="token punctuation">{</span> cameraState<span class="token operator">-></span><span class="token function">setShimParams</span><span class="token punctuation">(</span>params<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s: Cannot update shim parameters for camera %s, no such device exists."</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">,</span> cameraId<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 keyword">if</span> <span class="token punctuation">(</span>shimUpdateOnly<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// If only updating legacy shim parameters, immediately disconnect client</span> mServiceLock<span class="token punctuation">.</span><span class="token function">unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> client<span class="token operator">-></span><span class="token function">disconnect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> mServiceLock<span class="token punctuation">.</span><span class="token function">lock</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">else</span> <span class="token punctuation">{</span> <span class="token comment">// Otherwise, add client to active clients list</span> <span class="token function">finishConnectLocked</span><span class="token punctuation">(</span>client<span class="token punctuation">,</span> partial<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// lock is destroyed, allow further connect calls</span> <span class="token comment">// Important: release the mutex here so the client can call back into the service from its</span> <span class="token comment">// destructor (can be at the end of the call)</span> device <span class="token operator">=</span> client<span class="token punctuation">;</span> <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
2.2.3.1 [HAL] 创建 Camera 客户端 makeClient( )
接着调用
makeClient(this, cameraCb, clientPackageName, id, facing, clientPid, clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel, /*out*/&tmp))
@ frameworks/av/services/camera/libcameraservice/CameraService.cpp
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/out/sp<BasicClient>* client) {
<span class="token keyword">if</span> <span class="token punctuation">(</span>halVersion <span class="token operator"><</span> <span class="token number">0</span> <span class="token operator">||</span> halVersion <span class="token operator">==</span> deviceVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Default path: HAL version is unspecified by caller, create CameraClient</span>
<span class="token comment">// based on device version reported by the HAL.</span>
<span class="token keyword">switch</span><span class="token punctuation">(</span>deviceVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_1_0<span class="token punctuation">:</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>effectiveApiLevel <span class="token operator">==</span> API_1<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Camera1 API route</span>
sp<span class="token operator"><</span>ICameraClient<span class="token operator">></span> tmp <span class="token operator">=</span> static_cast<span class="token operator"><</span>ICameraClient<span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">CameraClient</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> facing<span class="token punctuation">,</span>
clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> <span class="token function">getpid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> legacyMode<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Camera2 API route</span>
<span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Camera using old HAL version: %d"</span><span class="token punctuation">,</span> deviceVersion<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_DEPRECATED_HAL<span class="token punctuation">,</span>
<span class="token string">"Camera device \"%d\" HAL version %d does not support camera2 API"</span><span class="token punctuation">,</span>
cameraId<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_0<span class="token punctuation">:</span>
<span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_1<span class="token punctuation">:</span>
<span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_2<span class="token punctuation">:</span>
<span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_3<span class="token punctuation">:</span>
<span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_4<span class="token punctuation">:</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>effectiveApiLevel <span class="token operator">==</span> API_1<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Camera1 API route</span>
sp<span class="token operator"><</span>ICameraClient<span class="token operator">></span> tmp <span class="token operator">=</span> static_cast<span class="token operator"><</span>ICameraClient<span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">Camera2Client</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> facing<span class="token punctuation">,</span>
clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> servicePid<span class="token punctuation">,</span> legacyMode<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Camera2 API route</span>
sp<span class="token operator"><</span>hardware<span class="token punctuation">:</span><span class="token punctuation">:</span>camera2<span class="token punctuation">:</span><span class="token punctuation">:</span>ICameraDeviceCallbacks<span class="token operator">></span> tmp <span class="token operator">=</span>
static_cast<span class="token operator"><</span>hardware<span class="token punctuation">:</span><span class="token punctuation">:</span>camera2<span class="token punctuation">:</span><span class="token punctuation">:</span>ICameraDeviceCallbacks<span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">CameraDeviceClient</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span>
facing<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> servicePid<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token comment">// A particular HAL version is requested by caller. Create CameraClient</span>
<span class="token comment">// based on the requested HAL version.</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>deviceVersion <span class="token operator">></span> CAMERA_DEVICE_API_VERSION_1_0 <span class="token operator">&&</span>
halVersion <span class="token operator">==</span> CAMERA_DEVICE_API_VERSION_1_0<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Only support higher HAL version device opened as HAL1.0 device.</span>
sp<span class="token operator"><</span>ICameraClient<span class="token operator">></span> tmp <span class="token operator">=</span> static_cast<span class="token operator"><</span>ICameraClient<span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">CameraClient</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> facing<span class="token punctuation">,</span>
clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> servicePid<span class="token punctuation">,</span> legacyMode<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token comment">// Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.</span>
<span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"Invalid camera HAL version %x: HAL %x device can only be"</span>
<span class="token string">" opened as HAL %x device"</span><span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">,</span>
CAMERA_DEVICE_API_VERSION_1_0<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_ILLEGAL_ARGUMENT<span class="token punctuation">,</span>
<span class="token string">"Camera device \"%d\" (HAL version %d) cannot be opened as HAL version %d"</span><span class="token punctuation">,</span>
cameraId<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">,</span> halVersion<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> Status<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">ok</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
接着调用 *client = new Camera2Client(cameraService, tmp, packageName, cameraId, facing, clientPid, clientUid, servicePid, legacyMode);
client是通过 Camera2ClientBase() 进行创建的
@ frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp Camera2Client::Camera2Client(const sp<CameraService>& cameraService, const sp<hardware::ICameraClient>& cameraClient, const String16& clientPackageName, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode): Camera2ClientBase(cameraService, cameraClient, clientPackageName, cameraId, cameraFacing, clientPid, clientUid, servicePid), mParameters(cameraId, cameraFacing) { ATRACE_CALL();
SharedParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>Lock <span class="token function">l</span><span class="token punctuation">(</span>mParameters<span class="token punctuation">)</span><span class="token punctuation">;</span> l<span class="token punctuation">.</span>mParameters<span class="token punctuation">.</span>state <span class="token operator">=</span> Parameters<span class="token punctuation">:</span><span class="token punctuation">:</span>DISCONNECTED<span class="token punctuation">;</span> mLegacyMode <span class="token operator">=</span> legacyMode<span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
创建Camera3Device 对象
// Interface used by CameraService
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
int cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,cameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(cameraId)),
mDeviceActive(false)
{
ALOGI(“Camera %d: Opened. Client: %s (PID %d, UID %d)”, cameraId, String8(clientPackageName).string(), clientPid, clientUid);
mInitialClientPid <span class="token operator">=</span> clientPid<span class="token punctuation">;</span>
mDevice <span class="token operator">=</span> new <span class="token function">Camera3Device</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOG_ALWAYS_FATAL_IF</span><span class="token punctuation">(</span>mDevice <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"Device should never be NULL here."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
@ frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
Camera3Device::Camera3Device(int id):
mId(id),
mIsConstrainedHighSpeedConfiguration(false),
mHal3Device(NULL),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
mUsePartialResult(false),
mNumPartialResults(1),
mTimestampOffset(0),
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
mNextShutterFrameNumber(0),
mNextReprocessShutterFrameNumber(0),
mListener(NULL)
{
ATRACE_CALL();
camera3_callback_ops::notify = &sNotify;
camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
ALOGV("%s: Created device for camera %d", FUNCTION, id);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
2.2.3.2 [HAL] Camera2Client初始化 client->initialize(mModule))
- 调用 Camera3Device::initialize 对/dev/videox 调备节点进行初始化,获取对应的设备的opt 操作函数
- 初始化 Camera 默认参数
- 创建 Camera 运行时的六大线程
3.1 StreamingProcessor:用来处理preview和录像 stream的线程。
3.2 FrameProcessor:用来处理3A和人脸识别的线程。
3.3 CaptureSequencer:拍照流程状态机线程,拍照的场景非常多,后面会发出状态机的运转流程。
3.4 JpegProcessor:用来处理拍照 jpeg stream 线程
3.5 ZslProcessor3:这个处理零延时zsl stream使用的线程
3.6 mCallbackProcessor:处理callback的线程,主要包含对 callback stream 的创建函数 updateStream()以及处理 HAL 层传上来的 callback stream 的线程
@ frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
status_t Camera2Client::initialize(CameraModule *module)
{
ATRACE_CALL();
ALOGV("%s: Initializing client for camera %d", FUNCTION, mCameraId);
status_t res;
<span class="token comment">// 1. 调用 Camera3Device::initialize 进行设备初始化,获取对应的 camera device 的opt 操作函数</span>
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>module<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">></span>
@ frameworks<span class="token operator">/</span>av<span class="token operator">/</span>services<span class="token operator">/</span>camera<span class="token operator">/</span>libcameraservice<span class="token operator">/</span>device3<span class="token operator">/</span>Camera3Device<span class="token punctuation">.</span>cpp
mDevice<span class="token operator">-></span><span class="token function">initialize</span><span class="token punctuation">(</span>module<span class="token punctuation">)</span><span class="token punctuation">;</span>
mDevice<span class="token operator">-></span><span class="token function">setNotifyCallback</span><span class="token punctuation">(</span>weakThis<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator"><=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>
<span class="token comment">// 2. 初始化 Camera 默认参数</span>
<span class="token punctuation">{</span>
SharedParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>Lock <span class="token function">l</span><span class="token punctuation">(</span>mParameters<span class="token punctuation">)</span><span class="token punctuation">;</span>
res <span class="token operator">=</span> l<span class="token punctuation">.</span>mParameters<span class="token punctuation">.</span><span class="token function">initialize</span><span class="token punctuation">(</span><span class="token operator">&</span><span class="token punctuation">(</span>mDevice<span class="token operator">-></span><span class="token function">info</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> mDeviceVersion<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">></span>
<span class="token operator">+</span> @ frameworks<span class="token operator">/</span>av<span class="token operator">/</span>services<span class="token operator">/</span>camera<span class="token operator">/</span>libcameraservice<span class="token operator">/</span>api1<span class="token operator">/</span>client2<span class="token operator">/</span>Parameters<span class="token punctuation">.</span>cpp
<span class="token operator">+</span> status_t Parameters<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">initialize</span><span class="token punctuation">(</span><span class="token keyword">const</span> CameraMetadata <span class="token operator">*</span>info<span class="token punctuation">,</span> <span class="token keyword">int</span> deviceVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token operator">+</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 operator">+</span> videoWidth <span class="token operator">=</span> previewWidth<span class="token punctuation">;</span>
<span class="token operator">+</span> videoHeight <span class="token operator">=</span> previewHeight<span class="token punctuation">;</span>
<span class="token operator">+</span> params<span class="token punctuation">.</span><span class="token function">setPreviewSize</span><span class="token punctuation">(</span>previewWidth<span class="token punctuation">,</span> previewHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span> params<span class="token punctuation">.</span><span class="token function">setVideoSize</span><span class="token punctuation">(</span>videoWidth<span class="token punctuation">,</span> videoHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span> params<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>CameraParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO<span class="token punctuation">,</span>
<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">"%dx%d"</span><span class="token punctuation">,</span> previewWidth<span class="token punctuation">,</span> previewHeight<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span> params<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>CameraParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>KEY_SUPPORTED_PREVIEW_FORMATS<span class="token punctuation">,</span> supportedPreviewFormats<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</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 operator"><=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>
<span class="token punctuation">}</span>
String8 threadName<span class="token punctuation">;</span>
<span class="token comment">// 3. 创建 Camera 运行时的六大线程</span>
<span class="token comment">// 3.1 StreamingProcessor:用来处理preview和录像 stream的线程。</span>
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><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">// 3.2 FrameProcessor:用来处理3A和人脸识别的线程。</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">-></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">// 3.3 CaptureSequencer:拍照流程状态机线程,拍照的场景非常多,后面会发出状态机的运转流程。</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">-></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">// 3.4 JpegProcessor:用来处理拍照 jpeg stream 线程</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">-></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">// 3.5 ZslProcessor3:这个处理零延时zsl stream使用的线程</span>
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">-></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">// 3.6 mCallbackProcessor:处理callback的线程,主要包含对 callback stream 的创建函数 updateStream()以及处理 HAL 层传上来的 callback stream 的线程</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">-></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 keyword">return</span> OK<span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
2.2.3.2.1 [HAL] Camera device 初始化 mDevice->initialize(module)
- 调用 hardware 层的camera_module_t.common 中的 open 方法,传入Camera ID
- 获取 Camera相关的信息
- 初始化 Camera 设备
@ frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp status_t Camera3Device::initialize(CameraModule *module) { ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId); /** Open HAL device */ String8 deviceName = String8::format("%d", mId);
camera3_device_t <span class="token operator">*</span>device<span class="token punctuation">;</span> <span class="token function">ATRACE_BEGIN</span><span class="token punctuation">(</span><span class="token string">"camera3->open"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1. 调用 hardware 层的camera_module_t.common 中的 open 方法,传入Camera ID</span> res <span class="token operator">=</span> module<span class="token operator">-></span><span class="token function">open</span><span class="token punctuation">(</span>deviceName<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> reinterpret_cast<span class="token operator"><</span>hw_device_t<span class="token operator">*</span><span class="token operator">*</span><span class="token operator">></span><span class="token punctuation">(</span><span class="token operator">&</span>device<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">></span> @ frameworks<span class="token operator">/</span>av<span class="token operator">/</span>services<span class="token operator">/</span>camera<span class="token operator">/</span>libcameraservice<span class="token operator">/</span>common<span class="token operator">/</span>CameraModule<span class="token punctuation">.</span>cpp <span class="token operator">+</span> res <span class="token operator">=</span> <span class="token function">filterOpenErrorCode</span><span class="token punctuation">(</span>mModule<span class="token operator">-></span>common<span class="token punctuation">.</span>methods<span class="token operator">-></span><span class="token function">open</span><span class="token punctuation">(</span><span class="token operator">&</span>mModule<span class="token operator">-></span>common<span class="token punctuation">,</span> id<span class="token punctuation">,</span> device<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">></span> <span class="token operator">+</span> @ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>QCamera2Hal<span class="token punctuation">.</span>cpp <span class="token operator">+</span> <span class="token keyword">struct</span> hw_module_methods_t QCamera2Factory<span class="token punctuation">:</span><span class="token punctuation">:</span>mModuleMethods <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">+</span> <span class="token punctuation">.</span>open <span class="token operator">=</span> QCamera2Factory<span class="token punctuation">:</span><span class="token punctuation">:</span>camera_device_open<span class="token punctuation">,</span> <span class="token operator">+</span> <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">></span> <span class="token operator">+</span> @ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>QCamera2Factory<span class="token punctuation">.</span>cpp <span class="token operator">+</span> rc <span class="token operator">=</span> gQCamera2Factory<span class="token operator">-></span><span class="token function">cameraDeviceOpen</span><span class="token punctuation">(</span><span class="token function">atoi</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">,</span> hw_device<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token operator">+</span> <span class="token operator"><=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> <span class="token operator">+</span><span class="token operator"><=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span> <span class="token comment">// 2. 获取 Camera相关的信息</span> camera_info info<span class="token punctuation">;</span> res <span class="token operator">=</span> module<span class="token operator">-></span><span class="token function">getCameraInfo</span><span class="token punctuation">(</span>mId<span class="token punctuation">,</span> <span class="token operator">&</span>info<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3. 初始化 Camera 设备,设置回调函数</span> <span class="token comment">/** Initialize device with callback functions */</span> <span class="token function">ATRACE_BEGIN</span><span class="token punctuation">(</span><span class="token string">"camera3->initialize"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> res <span class="token operator">=</span> device<span class="token operator">-></span>ops<span class="token operator">-></span><span class="token function">initialize</span><span class="token punctuation">(</span>device<span class="token punctuation">,</span> this<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">ATRACE_END</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">></span> <span class="token operator">+</span> @ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>HAL3<span class="token operator">/</span>QCamera3HWI<span class="token punctuation">.</span>cpp <span class="token operator">+</span> camera3_device_ops_t QCamera3HardwareInterface<span class="token punctuation">:</span><span class="token punctuation">:</span>mCameraOps <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">+</span> <span class="token punctuation">.</span>initialize <span class="token operator">=</span> QCamera3HardwareInterface<span class="token punctuation">:</span><span class="token punctuation">:</span>initialize<span class="token punctuation">,</span> <span class="token operator">+</span> <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">></span> <span class="token operator">+</span> <span class="token keyword">int</span> rc <span class="token operator">=</span> hw<span class="token operator">-></span><span class="token function">initialize</span><span class="token punctuation">(</span>callback_ops<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator"><=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span> <span class="token comment">/** Start up status tracker thread */</span> mStatusTracker <span class="token operator">=</span> new <span class="token function">StatusTracker</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span> res <span class="token operator">=</span> mStatusTracker<span class="token operator">-></span><span class="token function">run</span><span class="token punctuation">(</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">"C3Dev-%d-Status"</span><span class="token punctuation">,</span> mId<span class="token punctuation">)</span><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 keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">!=</span> OK<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">SET_ERR_L</span><span class="token punctuation">(</span><span class="token string">"Unable to start status tracking thread: %s (%d)"</span><span class="token punctuation">,</span> <span class="token function">strerror</span><span class="token punctuation">(</span><span class="token operator">-</span>res<span class="token punctuation">)</span><span class="token punctuation">,</span> res<span class="token punctuation">)</span><span class="token punctuation">;</span> device<span class="token operator">-></span>common<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token operator">&</span>device<span class="token operator">-></span>common<span class="token punctuation">)</span><span class="token punctuation">;</span> mStatusTracker<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** Register in-flight map to the status tracker */</span> mInFlightStatusId <span class="token operator">=</span> mStatusTracker<span class="token operator">-></span><span class="token function">addComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** Create buffer manager */</span> mBufferManager <span class="token operator">=</span> new <span class="token function">Camera3BufferManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> bool aeLockAvailable <span class="token operator">=</span> false<span class="token punctuation">;</span> camera_metadata_ro_entry aeLockAvailableEntry<span class="token punctuation">;</span> res <span class="token operator">=</span> <span class="token function">find_camera_metadata_ro_entry</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>static_camera_characteristics<span class="token punctuation">,</span> ANDROID_CONTROL_AE_LOCK_AVAILABLE<span class="token punctuation">,</span> <span class="token operator">&</span>aeLockAvailableEntry<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">==</span> OK <span class="token operator">&&</span> aeLockAvailableEntry<span class="token punctuation">.</span>count <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> aeLockAvailable <span class="token operator">=</span> <span class="token punctuation">(</span>aeLockAvailableEntry<span class="token punctuation">.</span>data<span class="token punctuation">.</span>u8<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** Start up request queue thread */</span> mRequestThread <span class="token operator">=</span> new <span class="token function">RequestThread</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> mStatusTracker<span class="token punctuation">,</span> device<span class="token punctuation">,</span> aeLockAvailable<span class="token punctuation">)</span><span class="token punctuation">;</span> res <span class="token operator">=</span> mRequestThread<span class="token operator">-></span><span class="token function">run</span><span class="token punctuation">(</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">"C3Dev-%d-ReqQueue"</span><span class="token punctuation">,</span> mId<span class="token punctuation">)</span><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 keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">!=</span> OK<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">SET_ERR_L</span><span class="token punctuation">(</span><span class="token string">"Unable to start request queue thread: %s (%d)"</span><span class="token punctuation">,</span> <span class="token function">strerror</span><span class="token punctuation">(</span><span class="token operator">-</span>res<span class="token punctuation">)</span><span class="token punctuation">,</span> res<span class="token punctuation">)</span><span class="token punctuation">;</span> device<span class="token operator">-></span>common<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token operator">&</span>device<span class="token operator">-></span>common<span class="token punctuation">)</span><span class="token punctuation">;</span> mRequestThread<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span> <span class="token punctuation">}</span> mPreparerThread <span class="token operator">=</span> new <span class="token function">PreparerThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** Everything is good to go */</span> mDeviceVersion <span class="token operator">=</span> device<span class="token operator">-></span>common<span class="token punctuation">.</span>version<span class="token punctuation">;</span> mDeviceInfo <span class="token operator">=</span> info<span class="token punctuation">.</span>static_camera_characteristics<span class="token punctuation">;</span> mHal3Device <span class="token operator">=</span> device<span class="token punctuation">;</span> <span class="token comment">// Determine whether we need to derive sensitivity boost values for older devices.</span> <span class="token comment">// If post-RAW sensitivity boost range is listed, so should post-raw sensitivity control</span> <span class="token comment">// be listed (as the default value 100)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mDeviceVersion <span class="token operator"><</span> CAMERA_DEVICE_API_VERSION_3_4 <span class="token operator">&&</span> mDeviceInfo<span class="token punctuation">.</span><span class="token function">exists</span><span class="token punctuation">(</span>ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mDerivePostRawSensKey <span class="token operator">=</span> true<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">internalUpdateStatusLocked</span><span class="token punctuation">(</span>STATUS_UNCONFIGURED<span class="token punctuation">)</span><span class="token punctuation">;</span> mNextStreamId <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> mDummyStreamId <span class="token operator">=</span> NO_STREAM<span class="token punctuation">;</span> mNeedConfig <span class="token operator">=</span> true<span class="token punctuation">;</span> mPauseStateNotify <span class="token operator">=</span> false<span class="token punctuation">;</span> <span class="token comment">// Measure the clock domain offset between camera and video/hw_composer</span> camera_metadata_entry timestampSource <span class="token operator">=</span> mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>timestampSource<span class="token punctuation">.</span>count <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> timestampSource<span class="token punctuation">.</span>data<span class="token punctuation">.</span>u8<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME<span class="token punctuation">)</span> <span class="token punctuation">{</span> mTimestampOffset <span class="token operator">=</span> <span class="token function">getMonoToBoottimeOffset</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">// Will the HAL be sending in early partial result metadata?</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mDeviceVersion <span class="token operator">>=</span> CAMERA_DEVICE_API_VERSION_3_2<span class="token punctuation">)</span> <span class="token punctuation">{</span> camera_metadata_entry partialResultsCount <span class="token operator">=</span> mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_REQUEST_PARTIAL_RESULT_COUNT<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>partialResultsCount<span class="token punctuation">.</span>count <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mNumPartialResults <span class="token operator">=</span> partialResultsCount<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> mUsePartialResult <span class="token operator">=</span> <span class="token punctuation">(</span>mNumPartialResults <span class="token operator">></span> <span class="token number">1</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">else</span> <span class="token punctuation">{</span> camera_metadata_entry partialResultsQuirk <span class="token operator">=</span> mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_QUIRKS_USE_PARTIAL_RESULT<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>partialResultsQuirk<span class="token punctuation">.</span>count <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> partialResultsQuirk<span class="token punctuation">.</span>data<span class="token punctuation">.</span>u8<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mUsePartialResult <span class="token operator">=</span> true<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> camera_metadata_entry configs <span class="token operator">=</span> mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>uint32_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> configs<span class="token punctuation">.</span>count<span class="token punctuation">;</span> i <span class="token operator">+</span><span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED <span class="token operator">&&</span> configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">==</span> ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT<span class="token punctuation">)</span> <span class="token punctuation">{</span> mSupportedOpaqueInputSizes<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token function">Size</span><span class="token punctuation">(</span>configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">2</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>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
2.2.3.2.2 [Hardware] 打开设备 gQCamera2Factory->cameraDeviceOpen( )
@ hardware/qcom/camera/QCamera2/QCamera2Factory.cpp
int QCamera2Factory::cameraDeviceOpen(int camera_id, struct hw_device_t hw_device)
{
LOGI(“Open camera id %d API version %d”,camera_id, mHalDescriptors[camera_id].device_version);
<span class="token keyword">if</span> <span class="token punctuation">(</span> mHalDescriptors<span class="token punctuation">[</span>camera_id<span class="token punctuation">]</span><span class="token punctuation">.</span>device_version <span class="token operator">==</span> CAMERA_DEVICE_API_VERSION_3_0 <span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">CAMSCOPE_INIT</span><span class="token punctuation">(</span>CAMSCOPE_SECTION_HAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
QCamera3HardwareInterface <span class="token operator">*</span>hw <span class="token operator">=</span> new <span class="token function">QCamera3HardwareInterface</span><span class="token punctuation">(</span>mHalDescriptors<span class="token punctuation">[</span>camera_id<span class="token punctuation">]</span><span class="token punctuation">.</span>cameraId<span class="token punctuation">,</span> mCallbacks<span class="token punctuation">)</span><span class="token punctuation">;</span>
rc <span class="token operator">=</span> hw<span class="token operator">-></span><span class="token function">openCamera</span><span class="token punctuation">(</span>hw_device<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
#ifdef QCAMERA_HAL1_SUPPORT
else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
rc <span class="token operator">=</span> hw<span class="token operator">-></span><span class="token function">openCamera</span><span class="token punctuation">(</span>hw_device<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
#endif
return rc;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
初始化 QCamera3HardwareInterface()
@ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp QCamera3HardwareInterface::QCamera3HardwareInterface(uint32_t cameraId, const camera_module_callbacks_t *callbacks) : mCameraId(cameraId), mCameraHandle(NULL), mCameraInitialized(false), mCallbacks(callbacks), ...... //省略一系列Camera 初始化默认值 { // 1. 获取HAL 层 log 等级 getLogLevel(); =========> property_get("persist.camera.hal.debug", prop, "0"); property_get("persist.camera.kpi.debug", prop, "0"); property_get("persist.camera.global.debug", prop, "0");
mCommon<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span>gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">.</span>tag <span class="token operator">=</span> HARDWARE_DEVICE_TAG<span class="token punctuation">;</span> mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">.</span>version <span class="token operator">=</span> CAMERA_DEVICE_API_VERSION_3_4<span class="token punctuation">;</span> mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">.</span>close <span class="token operator">=</span> close_camera_device<span class="token punctuation">;</span> mCameraDevice<span class="token punctuation">.</span>ops <span class="token operator">=</span> <span class="token operator">&</span>mCameraOps<span class="token punctuation">;</span> <span class="token operator">==</span><span class="token operator">=</span>⇒ @ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>HAL3<span class="token operator">/</span>QCamera3HWI<span class="token punctuation">.</span>cpp mCameraDevice<span class="token punctuation">.</span>priv <span class="token operator">=</span> this<span class="token punctuation">;</span> gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token operator">-></span>version <span class="token operator">=</span> CAM_HAL_V3<span class="token punctuation">;</span> <span class="token comment">// TODO: hardcode for now until mctl add support for min_num_pp_bufs</span> <span class="token comment">//TBD - To see if this hardcoding is needed. Check by printing if this is filled by mctl to 3</span> gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token operator">-></span>min_num_pp_bufs <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> pthread_condattr_t mCondAttr<span class="token punctuation">;</span> <span class="token function">pthread_condattr_init</span><span class="token punctuation">(</span><span class="token operator">&</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">pthread_condattr_setclock</span><span class="token punctuation">(</span><span class="token operator">&</span>mCondAttr<span class="token punctuation">,</span> CLOCK_MONOTONIC<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">pthread_cond_init</span><span class="token punctuation">(</span><span class="token operator">&</span>mBuffersCond<span class="token punctuation">,</span> <span class="token operator">&</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">pthread_cond_init</span><span class="token punctuation">(</span><span class="token operator">&</span>mRequestCond<span class="token punctuation">,</span> <span class="token operator">&</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">pthread_cond_init</span><span class="token punctuation">(</span><span class="token operator">&</span>mHdrRequestCond<span class="token punctuation">,</span> <span class="token operator">&</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">pthread_condattr_destroy</span><span class="token punctuation">(</span><span class="token operator">&</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span> mPendingLiveRequest <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> mCurrentRequestId <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token function">pthread_mutex_init</span><span class="token punctuation">(</span><span class="token operator">&</span>mMutex<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> CAMERA3_TEMPLATE_COUNT<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> mDefaultMetadata<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> <span class="token comment">// Getting system props of different kinds</span> <span class="token keyword">char</span> prop<span class="token punctuation">[</span>PROPERTY_VALUE_MAX<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 获取 persist.camera.raw.dump,是否使能 RAW dump 功能</span> <span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.raw.dump"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> mEnableRawDump <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 获取 persist.camera.hal3.force.hdr,是否使能 hdr 功能</span> <span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.hal3.force.hdr"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> mForceHdrSnapshot <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mEnableRawDump<span class="token punctuation">)</span> <span class="token function">LOGD</span><span class="token punctuation">(</span><span class="token string">"Raw dump from Camera HAL enabled"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&</span>mInputStreamInfo<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mInputStreamInfo<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span>mLdafCalib<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mLdafCalib<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.tnr.preview"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> m_bTnrPreview <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.swtnr.preview"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> m_bSwTnrPreview <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.tnr.video"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> m_bTnrVideo <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.avtimer.debug"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> m_debug_avtimer <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"AV timer enabled: %d"</span><span class="token punctuation">,</span> m_debug_avtimer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.cacmode.disable"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> m_cacModeDisabled <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> mRdiModeFmt <span class="token operator">=</span> gCamCapability<span class="token punctuation">[</span>mCameraId<span class="token punctuation">]</span><span class="token operator">-></span>rdi_mode_stream_fmt<span class="token punctuation">;</span> <span class="token comment">//Load and read GPU library.</span> lib_surface_utils <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> LINK_get_surface_pixel_alignment <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> mSurfaceStridePadding <span class="token operator">=</span> CAM_PAD_TO_32<span class="token punctuation">;</span> <span class="token comment">// 打开 libadreno_utils.so</span> lib_surface_utils <span class="token operator">=</span> <span class="token function">dlopen</span><span class="token punctuation">(</span><span class="token string">"libadreno_utils.so"</span><span class="token punctuation">,</span> RTLD_NOW<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>lib_surface_utils<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>LINK_get_surface_pixel_alignment <span class="token operator">=</span> <span class="token function">dlsym</span><span class="token punctuation">(</span>lib_surface_utils<span class="token punctuation">,</span> <span class="token string">"get_gpu_pixel_alignment"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>LINK_get_surface_pixel_alignment<span class="token punctuation">)</span> <span class="token punctuation">{</span> mSurfaceStridePadding <span class="token operator">=</span> <span class="token function">LINK_get_surface_pixel_alignment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">dlclose</span><span class="token punctuation">(</span>lib_surface_utils<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>gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token operator">-></span>is_quadracfa_sensor<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"Sensor support Quadra CFA mode"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> m_bQuadraCfaSensor <span class="token operator">=</span> true<span class="token punctuation">;</span> <span class="token punctuation">}</span> m_bQuadraCfaRequest <span class="token operator">=</span> false<span class="token punctuation">;</span> m_bQuadraSizeConfigured <span class="token operator">=</span> false<span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&</span>mStreamList<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>camera3_stream_configuration_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
接下来,调用 hw->openCamera(hw_device);
@ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp
int QCamera3HardwareInterface::openCamera(struct hw_device_t hw_device)
{
if (mState != CLOSED) {
*hw_device = NULL;
return PERMISSION_DENIED;
}
mPerfLockMgr<span class="token punctuation">.</span><span class="token function">acquirePerfLock</span><span class="token punctuation">(</span>PERF_LOCK_OPEN_CAMERA<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
rc <span class="token operator">=</span> <span class="token function">openCamera</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>rc <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token operator">*</span>hw_device <span class="token operator">=</span> <span class="token operator">&</span>mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token operator">*</span>hw_device <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d"</span><span class="token punctuation">,</span> mCameraId<span class="token punctuation">,</span> rc<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
mState <span class="token operator">=</span> OPENED<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
接下来调用 int QCamera3HardwareInterface::openCamera()
@ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp int QCamera3HardwareInterface::openCamera() { KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_OPENCAMERA); if (mCameraHandle) { LOGE("Failure: Camera already opened"); return ALREADY_EXISTS; }
rc <span class="token operator">=</span> QCameraFlash<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reserveFlashForCamera</span><span class="token punctuation">(</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">LOGE</span><span class="token punctuation">(</span><span class="token string">"Failed to reserve flash for camera id: %d"</span><span class="token punctuation">,</span> mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> UNKNOWN_ERROR<span class="token punctuation">;</span> <span class="token punctuation">}</span> rc <span class="token operator">=</span> <span class="token function">camera_open</span><span class="token punctuation">(</span><span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span>mCameraId<span class="token punctuation">,</span> <span class="token operator">&</span>mCameraHandle<span class="token punctuation">)</span><span class="token punctuation">;</span> rc <span class="token operator">=</span> mCameraHandle<span class="token operator">-></span>ops<span class="token operator">-></span><span class="token function">register_event_notify</span><span class="token punctuation">(</span>mCameraHandle<span class="token operator">-></span>camera_handle<span class="token punctuation">,</span> camEvtHandle<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span> mExifParams<span class="token punctuation">.</span>debug_params <span class="token operator">=</span> <span class="token punctuation">(</span>mm_jpeg_debug_exif_params_t <span class="token operator">*</span><span class="token punctuation">)</span> malloc <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>mm_jpeg_debug_exif_params_t<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>mExifParams<span class="token punctuation">.</span>debug_params<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">memset</span><span class="token punctuation">(</span>mExifParams<span class="token punctuation">.</span>debug_params<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mm_jpeg_debug_exif_params_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</s