总体介绍 
Android Camera 框架从整体上看是一个 client/service 的架构,有两个进程:
一个是 client 进程,可以看成是 AP 端,主要包括 JAVA 代码与一些 native c/c++代码;
另一个是 service 进 程,属于服务端,是 native c/c++代码,主要负责和 linux kernel 中的 camera driver 交互,搜集 linux kernel 中 camera driver 传上来的数据,并交给显示系统(surface)显示。client 进程与 service 进程通过 Binder 机制通信, client 端通过调用 service 端的接口实现各个具体的功能。 
需要注意的是真正的 preview 数据不会通过 Binder IPC 机制从 service 端复制到 client 端, 但会通过回调函数与消息的机制将 preview 数据 buffer 的地址传到 client 端, 最终可在 JAVA AP 
中操作处理这个 preview 数据。

client 端 
从 JAVA AP 的角度看 camera ap 就是调用 FrameWork 层的 android.hardware.camera 类来实现具体的功能。
JAVA Ap 最终被打包成 APK。 
FrameWork 层主要提供了 android.hardware.camera 类给应用层使用,这个类也是 JAVA 代码实现 。 
Android.hardware.camera 类通过 JNI 调用 native 代码实现具体的功能 。 
Android.hardware.camera 类中提供了如下的一个参数类给应用层使用: 
public class Parameters { 
       // Parameter keys to communicate with the camera driver。 
       private static final String KEY_PREVIEW_SIZE = "preview-size"; 
       private static final String KEY_PREVIEW_FORMAT = "preview-format"; 
       ...... 

参数会以字典(map)的方式组织存储起来,关键字就是 Parameters 类中的这些静态字符 
串。这些参数最终会以形如“preview-size=640X480;preview-format=yuv422sp;....”格式的 
字符串传到 service 端。     
源代码位于:framework/base/core/java/android/hardware/camera.java 
提供的接口示例:

获得一个 android.hardware.camera 类的实例

public static Camera open() { 
       return new Camera(); 

接口直接调用 native 代码(android_hardware_camera.cpp 中的代码) 
public native final void startPreview(); 
public native final void stopPreview(); 
android.hardware.camera 类的 JNI 调用实现在 android_hardware_camera.cpp 文件中,

源代码位置:  framework/base/core/jni/android_hardware_camera.cpp 
(framework/base/core/jni/文件夹下的文件都被编译进 libandroid_runtime.so 公共库中  ) 
android_hardware_camera.cpp 文件中的 JNI 调用实现函数都如下图:

android_hardware_camera.cpp 文件中的 register_android_hardware_Camera(JNIEnv *env)函数 
会将上面的 native 函数注册到虚拟机中,以供 FrameWork 层的 JAVA 代码调用。这些 native 
函数通过调用 libcamera_client.so 中的 Camera 类实现具体的功能。 
核心的 libcamera_client.so 动态库源代码位于:   frameworks/base/libs/camera/,  实现了如下几 
个类: 
Camera---->Camera.cpp/Camera.h 
CameraParameters--->CameraParameters.cpp/CameraParameters.h 
Icamera--->ICamera.cpp/ICamera.h 
IcameraClient--->ICameraClient.cpp/ICameraClient.h 
IcameraService--->ICameraService.cpp/ICameraService.h 
Icamera、IcameraClient、IcameraService 三个类是按照 Binder IPC 通信要求的框架实现的,用 
来与 service 端通信。 
类 CameraParameters 接收 FrameWork 层的 android.hardware.camera::Parameters 类为参数, 
解析与格式化所有的参数设置。 
Camera 是一个很重要的类,     它与 CameraService 端通过 Binder IPC 机制交互来实现具体功能。 
Camera 继承自 BnCameraClient,并最终继承自 ICameraClient。 
Camera 类通过: 
sp sm = defaultServiceManager(); 
sp binder = sm->getService(String16("media.camera")); 
sp mCameraService = interface_cast (binder); 
得到名字为“media.camera”的 CameraService。通过调用 CameraService 的接口 connect()返 
回得到 sp mCamera,并在 CameraService 端 new 一个 CameraService::Client 类 
mClient。mClient 继承自 BnCamera,并最终继承自 ICamera。 
之 后 Camera 类 通 过 这 个 sp mCamera 对 象 调 用 函 数 就 像 直 接 调 用 
CameraService::Client 类 mClient 的函数。CameraService::Client 类实现具体的功能。 
         service 端 
实现在动态库 libcameraservice.so 中,  源代码位于:  frameworks/base/camera/libcameraservice

Libcameraservice.so 中主要有下面两个类: 
Libcameraservice.so::CameraService 类 , 继 承 自 BnCameraService , 并 最 终 继 承 自 
    ICameraService 
 Libcameraservice.so::CameraService::Client 类, 继承自 BnCamera,    并最终继承自 ICamera 
CameraService::Client 类通过调用 Camera HAL 层来实现具体的功能。目前的 code 中只支持 
一个 CameraService::Client 实例。 
Camera Service 在 系 统 启 动 时 new 了 一 个 实 例 , 以 “ media.camera ” 为 名 字 注 册 到 
ServiceManager 中。在 init.rc 中有如下代码执行可执行文件/system/bin/mediaserver,启动多 
媒体服务进程。 
service media /system/bin/mediaserver 
Mediaserver 的 c 代码如下: 
int main(int argc,char** argv) 

   sp proc(ProcessState::self()); 
   sp sm = defaultServiceManager(); 
   LOGI("ServiceManager: %p",sm。get()); 
   AudioFlinger::instantiate(); 
   MediaPlayerService::instantiate(); 
   CameraService::instantiate(); 
   AudioPolicyService::instantiate(); 
   ProcessState::self()->startThreadPool(); 
   IPCThreadState::self()->joinThreadPool(); 

                                          
Camera HAL(硬件抽象层) 
Libcameraservice.so::CameraService::Client 类调用 camera HAL 的代码实现具体功能,camera 
HAL 一般实现为一个动态库 libcamera.so(动态库名字可以改,只需要与 Android.mk 一致即 
可)。Android 只给了一个定义文件: 
/home/miracle/Work/android/android_src/froyo/frameworks/base/include/camera/CameraHard 
wareInterface.h 
class CameraHardwareInterface : public virtual RefBase { 
public: 
    virtual ~CameraHardwareInterface() { } 
    virtual sp getPreviewHeap() const = 0; 
    virtual sp getRawHeap() const = 0; 
    virtual void setCallbacks(notify_callback notify_cb,data_callback data_cb, 
                    data_callback_timestamp data_cb_timestamp,void* user) = 0; 
    virtual void       enableMsgType(int32_t msgType) = 0; 
    virtual void       disableMsgType(int32_t msgType) = 0; 
    virtual bool       msgTypeEnabled(int32_t msgType) = 0; 
    virtual status_t startPreview() = 0; 
    virtual bool        useOverlay() {return false;} 
    virtual status_t setOverlay(const sp &overlay) {return BAD_VALUE;} 
    virtual void         stopPreview() = 0; 
    virtual bool         previewEnabled() = 0; 
    virtual status_t      startRecording() = 0; 
    virtual bool         recordingEnabled() = 0; 
    virtual status_t      autoFocus() = 0; 
    virtual status_t      cancelAutoFocus() = 0; 
    virtual status_t      takePicture() = 0; 
    virtual status_t      cancelPicture() = 0; 
    virtual status_t      setParameters(const CameraParameters& params) = 0; 
    virtual CameraParameters getParameters() const = 0; 
    virtual status_t sendCommand(int32_t cmd,int32_t arg1,int32_t arg2) = 0; 
    virtual void release() = 0; 
    virtual status_t dump(int fd,const Vector & args) const = 0; 
}; 
extern "C" sp openCameraHardware(); 
}; // namespace android 
可以看到在 JAVA Ap 中的功能调用最终会调用到 HAL 层这里,Camera HAL 层的实现是主要 
的工作,      它一般通过 V4L2 command 从 linux kernel 中的 camera driver 得到 preview 数据。然 
后交给 surface(overlay)显示或者保存为文件。在 HAL 层需要打开对应的设备文件,并通过 
ioctrl 访问 camera driver。Android 通过这个 HAL 层来保证底层硬件(驱动)改变,只需修改 
对应的 HAL 层代码,FrameWork 层与 JAVA Ap 的都不用改变。 
          Preview 数据流程 
Android 框架中 preview 数据的显示过程如下: 
1、 打开内核设备文件。CameraHardwareInterface.h 中定义的 openCameraHardware()打开 
     linux kernel 中的 camera driver 的设备文件(如/dev/video0)      ,创建初始化一些相关的类 
     的实例。 
2、 设置摄像头的工作参数。CameraHardwareInterface.h 中定义的 setParameters()函数,在 
     这一步可以通过参数告诉 camera HAL 使用哪一个硬件摄像头,  以及它工作的参数  (size, 
   format 等) ,并在 HAL 层分配存储 preview 数据的 buffers(如果 buffers 是在 linux kernel 
   中的 camera driver 中分配的,在这一步也会拿到这些 buffers mmap 后的地址指针)                      。 
3、 设置显示目标。需在 JAVA APP 中创建一个 surface 然后传递到 CameraService 中。会调 
   用到 libcameraservice.so 中的 setPreviewDisplay(const sp & surface)函数中。在 
   这里分两种情况考虑:一种是不使用 overlay;一种是使用 overlay 显示。如果不使用 
   overlay 那设置显示目标最后就在 libcameraservice.so 中,不会进 Camera HAL 动态库。 
   并将上一步拿到的 preview 数据 buffers 地址注册到 surface 中。 如果使用 overlay 那在 
   libcameraservice.so 中会通过传进来的 Isurface 创建 Overlay 类的实例,然后调用 
   CameraHardwareInterface.h 中定义的 setOverlay()设置到 Camera HAL 动态库中。 
4、 开始 preview 工作。最终调用到 CameraHardwareInterface.h 中定义的 startPreview()函数。 
   如果不使用 overlay,Camera HAL 得到 linux kernel 中的 preview 数据后回调通知到 
   libcameraservice.so 中。在 libcameraservice.so 中会使用上一步的 surface 进行显示。如 
   果使用 overlay,    Camera HAL 得到 linux kernel 中的 preview 数据后直接交给 Overlay 对象, 
   然后有 Overlay HAL 去显示。 
        模拟器中的虚拟 camera 
如果没有 camera 硬件,不实现真正的 Camera HAL 动态库,可以使用虚拟 camera。源代码 
位于: 
frameworks/base/camera/libcameraservice/FakeCamera.cpp 
frameworks/base/camera/libcameraservice/CameraHardwareStub.cpp 
FakeCamera.cpp 文件提供虚拟的 preview 数据。CameraHardwareStub.cpp 文件中实现了 
camera HAL(硬件抽象层)的功能。当宏 USE_CAMERA_STUB 为 true 时可以使用这个虚拟的 
camera。 
ifeq ($(USE_CAMERA_STUB),true) 
   LOCAL_STATIC_LIBRARIES += libcamerastub //虚拟的 camera 
#if want show LOGV message,should use follow define。 add 0929 
#LOCAL_CFLAGS += -DLOG_NDEBUG=0 
   LOCAL_CFLAGS += -include CameraHardwareStub。h 
else 
   LOCAL_SHARED_LIBRARIES += libcamera //真正的 camera HAL 库 
endif 
          框架图

介绍 Android 的 Camera 框架相关推荐

  1. 这可能是介绍Android UvcCamera最详细的文章了

    设备外接usb摄像头,进行基本的预览.拍照.录像.相信有些同学在工作中有遇到类似的需求. uvc camera?不管你之前有没用过,有没遇到过,相信看完这篇文章,一定会带给你一些收获. 这篇文章将从下 ...

  2. Android Camera框架

    总体介绍 Android Camera 框架从整体上看是一个 client/service 的架构, 有两个进程: client 进程,可以看成是 AP 端,主要包括 JAVA 代码与一些 nativ ...

  3. 2018年android常用的框架介绍

    转载地址:http://blog.csdn.net/RuingMan/article/details/73546718 http://www.cnblogs.com/jincheng-yangchao ...

  4. 增加录像时间戳水印、 camera框架介绍

    最近项目上要在mtk6589机器上增加录像的水印功能,那个纠结呀--  一大通 度娘.google啊-- 最终整个变通的方案:做好10几个bmp(8位深度黑底白字)贴图,把文件使用ue去除掉bmp文件 ...

  5. Android之Camera介绍

    Android Camera 使用小结 Android手机关于Camera的使用,一是拍照,二是摄像,由于Android提供了强大的组件功能,为此对于在Android手机系统上进行Camera的开发, ...

  6. android.hardware.Camera类及其标准接口介绍

    android.hardware.Camera类及其标准接口介绍,API level 19 http://developer.android.com/reference/android/hardwar ...

  7. Android的多媒体框架OpenCore介绍

    网上资料很少, 不过还是找到一个比较详细的说明: 特地在此整理了下: 地址:http://blog.csdn.net/djy1992/article/details/9339787 分为几个阶段: 1 ...

  8. Android主流HOOK框架介绍与应用--游戏破解游戏外挂的必杀技

    概述 使用HOOK方案主要是在分析的时候会经常用到,虽然二次打包重新修改代码也可以做到,但是一方面效率低,另一方面如果APP有校验的逻辑就需要进一步绕过,总体还是比较费时费力.所以,通过动态HOOK的 ...

  9. 萝卜和青菜--Android camera框架与使用

    Android camera主要结构如图所示. 我们可以从三个层次去使用它:JAVA层,service层和hardwareinterface. 流程都大同小异,不同编程语言具体实现上接口略有不同, 流 ...

最新文章

  1. mongodb的聚合操作
  2. JQuery事件绑定,bind与on区别
  3. MICRA OPENCART 自适应主题模板 ABC-0678-02
  4. HttpWatch是强大的网页数据分析工具
  5. 悲观锁和乐观锁的详细分析
  6. Java并发编程—线程同步类
  7. LocalReport Print with C# C#打印RDLC
  8. 计算机没有程序,计算机小知识:想尝试写程序却没有电脑?这个在线编辑器满足你...
  9. Spring Web-Flux – Cassandra后端的功能样式
  10. ubuntu 安装cudnn
  11. php 添加音乐,PHP网站插入音乐
  12. 用API OleLoadPicture通过IStream来加载JPG、GIF格式的图片
  13. 上传文件到阿里云OSS报错-Unable to execute HTTP request: You have no right to access this object because of buc
  14. 响应已被截断_技术:RWD响应式网站网页设计基本原则
  15. P2922 [USACO08DEC]秘密消息Secret Message
  16. [英中双语] Pragmatic Software Development Tips 务实的软件开发提示
  17. rf 遍历列表_RF学习笔记
  18. oracle查看当前用户表空间占用情况
  19. 淘宝客高手必备的14大WordPress插件
  20. java实现身份证归属地查询

热门文章

  1. \045在字符串中输出为%
  2. Ext.widgets-menu
  3. ajax连接mysql数据库查询数据_ajax动态查询数据库数据并显示在前台的方法
  4. 【LeetCode】开始LeetCode的第一题offer03
  5. AOP处理事务静、动态代理(jdk方法)
  6. windows借鉴linux了吗,Windows应该借鉴Linux的10大功能特征
  7. blender php,Blender 源码学习 --- Modifier
  8. 对‘pthread_create’未定义的引用_全球两大引文数据库,都在悄悄少算引用次数...
  9. 怎样调整input框背景颜色_不用花钱,自己也能制作证件照,更换背景色、排版全搞定...
  10. 使用Lambda解决_inbound_nodes错误