Camera Framework 代码分析

xmt@server005:~/frameworks/av/camera/aidl/android/hardware$ tree

.

├—— camera2

│   ├—— CaptureRequest.aidl

│   ├—— ICameraDeviceCallbacks.aidl

│   ├—— ICameraDeviceUser.aidl

│   ├—— impl

│   │  ├—— CameraMetadataNative.aidl

│   │  └—— CaptureResultExtras.aidl

│   ├—— params

│   │  ├—— OutputConfiguration.aidl

│   │  ├—— VendorTagDescriptor.aidl

│   │  └—— VendorTagDescriptorCache.aidl

│   └—— utils

│       └—— SubmitInfo.aidl

├—— CameraInfo.aidl

├—— CameraStatus.aidl

├—— ICamera.aidl

├—— ICameraClient.aidl

├—— ICameraService.aidl

├—— ICameraServiceListener.aidl

└—— ICameraServiceProxy.aidl

4directories, 16 files

frameworks/av/camera/aidl/目录下的 aidl 文件有两种类型:

  • 作为 Binder 中的 IInterface 跨进程通信中能提供的方法

  • 作为 Binder 中的 parcelable 跨进程通信数据传输的数据结构

很容易从名字上区分这两种类型的文件,IInterface 类型的文件都是以 I 开头的,比如:ICameraService.aidl, ICameraDeviceUser.aidl等。不管是哪种类型的 aidl 文件,它们都会生成对应的 .java, .h, .cpp 文件,分别供 Java 层和 CPP 层调用。

四、 IInterface 类型文件


IInterface 类型文件一共有 7 个,它们的 .java, .h, .cpp 文件,绝大部分都是自动生成的。

Java 文件是在 frameworks/base/Android.mk 中定义规则,在编译时自动生成:

//frameworks/base/Android.mk

LOCAL_SRC_FILES +=

…/av/camera/aidl/android/hardware/ICameraService.aidl

…/av/camera/aidl/android/hardware/ICameraServiceListener.aidl

…/av/camera/aidl/android/hardware/ICameraServiceProxy.aidl

…/av/camera/aidl/android/hardware/ICamera.aidl

…/av/camera/aidl/android/hardware/ICameraClient.aidl

…/av/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl

…/av/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl

在 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/dotdot/ 目录下生成对应的 Java 文件:

//out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/dotdot/

av/camera/aidl/android/hardware/ICameraService.java

av/camera/aidl/android/hardware/ICameraServiceListener.java

av/camera/aidl/android/hardware/ICameraServiceProxy.java

av/camera/aidl/android/hardware/ICamera.java

av/camera/aidl/android/hardware/ICameraClient.java

av/camera/aidl/android/hardware/camera2/ICameraDeviceUser.java

av/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.java

.h, .cpp 文件中,ICamera.aidl, ICameraClient.aidl 两个文件是直接以代码形式手动实现的:

// 1. ICameraClient.aidl

frameworks/av/camera/aidl/android/hardware/ICameraClient.aidl

frameworks/av/camera/include/camera/android/hardware/ICameraClient.h

frameworks/av/camera/ICameraClient.cpp

// 2.ICamera.aidl

frameworks/av/camera/aidl/android/hardware/ICamera.aidl

frameworks/av/camera/include/camera/android/hardware/ICamera.h

frameworks/av/camera/ICamera.cpp

其他 5 个 aidl 文件是在 frameworks/av/camera/Android.bp 中定义规则,编译时自动生成对应的 .h, .cpp 文件:

//frameworks/av/camera/Android.bp

cc_library_shared {

name: “libcamera_client”,

aidl: {

export_aidl_headers: true,

local_include_dirs: [“aidl”],

include_dirs: [

“frameworks/native/aidl/gui”,

],

},

srcs: [

// AIDL files for camerainterfaces

// The headers for theseinterfaces will be

// available to anymodules that

// include libcamera_client,at the path “aidl/package/path/BnFoo.h”

“aidl/android/hardware/ICameraService.aidl”,

“aidl/android/hardware/ICameraServiceListener.aidl”,

“aidl/android/hardware/ICameraServiceProxy.aidl”,

“aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl”,

“aidl/android/hardware/camera2/ICameraDeviceUser.aidl”,

// Source for camerainterface parcelables,

// and manually-writteninterfaces

“Camera.cpp”,

“CameraMetadata.cpp”,

“CameraParameters.cpp”,

}

在 out/soong/.intermediates/frameworks/av/camera/libcamera_client/ 目录下生成对应的 .h, .cpp 文件,通常在该目录下会同时生成 32 和 64 位两套代码,但实际两份代码是一样的,这里选取 64 位的:

  • 64 位:android_arm64_armv8-a_shared_core

  • 32 位:android_arm_armv7-a-neon_cortex-a53_shared_core

// 目录__out/soong/.intermediates/frameworks/av/camera/libcamera_client_// 64_ android_arm64_armv8-a_shared_core/gen/aidl/

android/hardware/ICameraService.h

android/hardware/BnCameraService.h

frameworks/av/camera/aidl/android/hardware/ICameraService.cpp

android/hardware/ICameraServiceListener.h

android/hardware/BnCameraServiceListener.h

frameworks/av/camera/aidl/android/hardware/ICameraServiceListener.cpp

android/hardware/ICameraServiceProxy.h

android/hardware/BnCameraServiceProxy.h

frameworks/av/camera/aidl/android/hardware/ICameraServiceProxy.cpp

android/hardware/camera2/ICameraDeviceUser.h

android/hardware/camera2/BnCameraDeviceUser.h

frameworks/av/camera/aidl/android/hardware/camera2/ICameraDeviceUser.cpp

android/hardware/camera2/ICameraDeviceCallbacks.h

android/hardware/camera2/BnCameraDeviceCallbacks.h

frameworks/av/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.cpp

五、 parcelable 类型文件

parcelable 类型文件一共有 9 个,它们都是手动编写的代码。

Java 文件目录为 frameworks/base/core/java/android/hardware/ :

//frameworks/base/core/java/android/hardware/

camera2/CaptureRequest.java

camera2/impl/CameraMetadataNative.java

camera2/impl/CaptureResultExtras.java

camera2/params/OutputConfiguration.java

camera2/params/VendorTagDescriptor.java

camera2/params/VendorTagDescriptorCache.java

camera2/utils/SubmitInfo.java

CameraInfo.java

CameraStatus.java

.h, .cpp 文件并不一定是和 aidl 文件名称一一对应的,而是在 aidl 文件中定义的,比如 CameraStatus.aidl 定义如下:

packageandroid.hardware;

/** @hide */

parcelable CameraStatus cpp_header “camera/CameraBase.h”;

parcelable 类型的 aidl 文件对应的 .h, .cpp 文件目录为 frameworks/av/camera ,对应关系整理如下:

// .h, .cpp 文件目录 frameworks/av/camera_//CaptureRequest.aidl_include/camera/camera2/CaptureRequest.h

camera2/CaptureRequest.cpp

_//CameraMetadataNative.aidl_include/camera/CameraMetadata.h

CameraMetadata.cpp

_//CaptureResultExtras.aidl_include/camera/CaptureResult.h

CaptureResult.cpp

_//OutputConfiguration.aidl_include/camera/camera2/OutputConfiguration.h

camera2/OutputConfiguration.cpp

//VendorTagDescriptor.aidl _和__VendorTagDescriptorCache.aidl_include/camera/VendorTagDescriptor.h

VendorTagDescriptor.cpp

_//SubmitInfo.aidl_include/camera/camera2/SubmitInfo.h

camera2/SubmitInfo.cpp

//CameraInfo.aidl _CameraStatus.aidl_include/camera/CameraBase.h

CameraBase.cpp

六、ICameraService 相关

分为客户端向服务端的请求 ICameraService.aidl 和客户端监听服务端的变化 ICameraServiceListener.aidl 。这两个 AIDL 是在 CameraService.cpp 中实现对应功能的。

interface

{

constintCAMERA_TYPE_BACKWARD_COMPATIBLE = 0;

constint CAMERA_TYPE_ALL= 1;

// 返回指定类型的相机设备数量

intgetNumberOfCameras(int type);

// 根据 id 返回当前相机设备信息

CameraInfo getCameraInfo(intcameraId);

constintCAMERA_HAL_API_VERSION_UNSPECIFIED = -1;

// api1 + hal1

ICamera connect(ICameraClientclient,

int cameraId,

String opPackageName,

intclientUid, intclientPid);

// api2 + hal3

ICameraDeviceUser connectDevice(ICameraDeviceCallbackscallbacks,

String cameraId,

String opPackageName,

intclientUid);

// api1 + 指定 hal 版本(通常为 hal1_)_

ICamera connectLegacy(ICameraClientclient,

int cameraId,

inthalVersion,

String opPackageName,

intclientUid);

// 添加和移除 ICameraServiceListener 监听

CameraStatus[] addListener(ICameraServiceListenerlistener);

voidremoveListener(ICameraServiceListenerlistener);

// 根据 id 返回相机支持的属性

CameraMetadataNative getCameraCharacteristics(StringcameraId);

// 获取 vendor tag

VendorTagDescriptor getCameraVendorTagDescriptor();

VendorTagDescriptorCache getCameraVendorTagCache();

// camera api 1 获取参数信息

String getLegacyParameters(intcameraId);

constintAPI_VERSION_1 = 1;

constintAPI_VERSION_2 = 2;

// 指定 id 支持的 API 版本

booleansupportsCameraApi(StringcameraId, intapiVersion);

// 指定 id 设置手电筒模式

voidsetTorchMode(StringcameraId, boolean enabled,

IBinder clientBinder);

// 服务端向系统打印系统消息

constintEVENT_NONE = 0;

constintEVENT_USER_SWITCHED = 1;

oneway voidnotifySystemEvent(int eventId,in int[] args);

}

_// 2.ICameraServiceListener.aidl_interfaceICameraServiceListener

{

constintSTATUS_NOT_PRESENT      = 0;

constintSTATUS_PRESENT          = 1;

constintSTATUS_ENUMERATING      = 2;

constintSTATUS_NOT_AVAILABLE    = -2;

constintSTATUS_UNKNOWN          = -1;

// 相机设备状态变化事件

oneway voidonStatusChanged(int status,String cameraId);

constintTORCH_STATUS_NOT_AVAILABLE = 0;

constintTORCH_STATUS_AVAILABLE_OFF = 1;

constintTORCH_STATUS_AVAILABLE_ON  = 2;

constintTORCH_STATUS_UNKNOWN = -1;

// 手电筒状态变化事件

oneway voidonTorchStatusChanged(int status,String cameraId);

}

七、 ICameraServiceProxy.aidl 文件


CameraServiceProxy 服务是在 Java 层注册的

interfaceICameraServiceProxy

{

// CameraService 向代理服务发送消息,通知用户更新

onewayvoidpingForUserUpdate();

constintCAMERA_STATE_OPEN = 0;

constintCAMERA_STATE_ACTIVE = 1;

constintCAMERA_STATE_IDLE = 2;

constintCAMERA_STATE_CLOSED = 3;

constintCAMERA_FACING_BACK = 0;

constintCAMERA_FACING_FRONT = 1;

constintCAMERA_FACING_EXTERNAL = 2;

// CameraService 向代理服务发送消息,通知相机设备状态更新

onewayvoidnotifyCameraState(String cameraId, int facing,

intnewCameraState, String clientName);

}

八、 ICamera 相关


Camera API1 才会使用到,分为 ICamera.aidl, ICameraClient.aidl

它们的代码是手动实现的,参考:CameraClient.h/cpp, Camera.h/cpp

九、ICameraDevice 相关


Camera API2 才会使用到,分为客户端向服务端的请求 ICameraDeviceUser.aidl 和服务端发给客户端的回调 ICameraDeviceCallbacks.aidl 。

表示相机设备具备的能力,能够提供的函数;这两个 AIDL 是在 CameraDeviceClient 中实现对应功能的

// 1.ICameraDeviceUser.aidl interfaceICameraDeviceUser

{

voiddisconnect();

constintNO_IN_FLIGHT_REPEATING_FRAMES = -1;

// 向设备提交捕获请求

SubmitInfo submitRequest(inCaptureRequest request, boolean streaming);

SubmitInfo submitRequestList(inCaptureRequest[] requestList,

boolean streaming);

// 取消置顶 id 的重复请求,并返回上次请求的帧 id

longcancelRequest(intrequestId);

constintNORMAL_MODE = 0;

constintCONSTRAINED_HIGH_SPEED_MODE = 1;

constintVENDOR_MODE_START = 0x8000;

// 在流处理前执行配置请求

voidbeginConfigure();

// 根据指定输出配置,创建流

intcreateStream(inOutputConfiguration outputConfiguration);

voidendConfigure(intoperatingMode);

voiddeleteStream(intstreamId);

// 创建输入流,返回流 id

intcreateInputStream(int width, int height, int format);

// 返回输入流的 Surface

Surface getInputSurface();

// Keep in sync withpublic API in

//frameworks/base/core/java/android/hardware/camera2/CameraDevice.java

constintTEMPLATE_PREVIEW = 1;

constintTEMPLATE_STILL_CAPTURE = 2;

constintTEMPLATE_RECORD = 3;

constintTEMPLATE_VIDEO_SNAPSHOT = 4;

constintTEMPLATE_ZERO_SHUTTER_LAG = 5;

constintTEMPLATE_MANUAL = 6;

// 根据模板创建默认请求,返回相机参数信息

CameraMetadataNative createDefaultRequest(inttemplateId);

// 获取相机参数信息

CameraMetadataNative getCameraInfo();

voidwaitUntilIdle();

longflush();

voidprepare(intstreamId);

voidtearDown(intstreamId);

voidprepare2(int maxCount,intstreamId);

voidfinalizeOutputConfigurations(int streamId,

in OutputConfigurationoutputConfiguration);

}

_// 2.ICameraDeviceCallbacks.aidl_interfaceICameraDeviceCallbacks

{

oneway voidonDeviceError(interrorCode,

in CaptureResultExtrasresultExtras);

oneway voidonDeviceIdle();

oneway voidonCaptureStarted(inCaptureResultExtras resultExtras,

longtimestamp);

oneway voidonResultReceived(inCameraMetadataNative result,

inCaptureResultExtras resultExtras);

oneway voidonPrepared(intstreamId);

// 重复请求引起的错误回调

oneway voidonRepeatingRequestError(in longlastFrameNumber,

in intrepeatingRequestId);

oneway voidonRequestQueueEmpty();

}

十、Services 目录下的文件介绍


frameworks/av/services/camera/libcameraservice AOSP 中这个目录下是 87 个文件,而 Qcom 的基线中增加了 27 个文件,分别为 api1/qticlient2 目录下的 25 个文件,以及 QTICamera2Client.cpp, QTICamera2Client.h 两个文件。

.

├—— Android.mk

├—— api1

│   ├—— client2

│   └—— qticlient2

├—— api2

├—— CameraFlashlight.cpp

├—— CameraFlashlight.h

├—— CameraService.cpp

├—— CameraService.h

├—— common

├—— device1

├—— device3

├—— gui

├—— MODULE_LICENSE_APACHE2

├—— NOTICE

├—— tests

└—— utils

从目录结构上可以看出,API1/2 和 HAL1/3 就是在这一层体现的。

十一、 API1/API2


APP Java 客户端调用服务端方法时,Camera API1/2 接口对应功能都是在 CameraService 中实现的,而这里的 API1/2 目录对应的就是对上层不同版本接口的处理

api1

├—— Camera2Client.cpp

├—— Camera2Client.h

├—— CameraClient.cpp

├—— CameraClient.h

├—— client2

│   ├—— CallbackProcessor.cpp

│   ├—— CallbackProcessor.h

│   ├—— Camera2Heap.h

│   ├—— CaptureSequencer.cpp

│   ├—— CaptureSequencer.h

│   ├—— FrameProcessor.cpp

│   ├—— FrameProcessor.h

│   ├—— JpegCompressor.cpp

│   ├—— JpegCompressor.h

│   ├—— JpegProcessor.cpp

│   ├—— JpegProcessor.h

│   ├—— Parameters.cpp

│   ├—— Parameters.h

│   ├—— StreamingProcessor.cpp

│   ├—— StreamingProcessor.h

│   ├—— ZslProcessor.cpp

│   └—— ZslProcessor.h

├—— QTICamera2Client.cpp

最后

一线互联网Android面试题含详解(初级到高级专题)

这些题目是今年群友去腾讯、百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。并且大多数都整理了答案,熟悉这些知识点会大大增加通过前两轮技术面试的几率

如果设置门槛,很多开发者朋友会因此错过这套高级架构资料,错过提升成为架构师的可能。这就失去了我们的初衷;让更多人都能通过高效高质量的学习,提升自己的技术和格局,升职加薪。

最后送给大家一句话,望共勉,永远不要放弃自己的梦想和追求;

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

or.cpp

│   ├—— JpegCompressor.h

│   ├—— JpegProcessor.cpp

│   ├—— JpegProcessor.h

│   ├—— Parameters.cpp

│   ├—— Parameters.h

│   ├—— StreamingProcessor.cpp

│   ├—— StreamingProcessor.h

│   ├—— ZslProcessor.cpp

│   └—— ZslProcessor.h

├—— QTICamera2Client.cpp

最后

一线互联网Android面试题含详解(初级到高级专题)

这些题目是今年群友去腾讯、百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。并且大多数都整理了答案,熟悉这些知识点会大大增加通过前两轮技术面试的几率

[外链图片转存中…(img-2NW5scNG-1714482661934)]

如果设置门槛,很多开发者朋友会因此错过这套高级架构资料,错过提升成为架构师的可能。这就失去了我们的初衷;让更多人都能通过高效高质量的学习,提升自己的技术和格局,升职加薪。

最后送给大家一句话,望共勉,永远不要放弃自己的梦想和追求;

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值