android Camera API1+HAL1 open camera流程 & Android M

Camera API2从android 5.0就已经支持了,API1早已经被谷歌标记为过时了,谷歌也一直在推camera API2,并且前不久伴随着Android 10的发布,谷歌推出了CameraX 库,为了更方便的使用API2。但目前仍然有很多camera相关的应用因为一开始使用的就是API1,业务框架流程都已经稳定,不会耗费人力去迁移camera API2。所以在很长一段时间内,camera API1还是会有应用在使用,当然后续API2也会分析的,毕竟这是大趋势。

本文是基于android 6.0源码,搭配camera HAL1进行分析,这对Android 8.0之前的系统来说都是通用的。android 8.0以后加入了Treble机制,cameraService层和HAL层之间加入了一层Camera HIDL层,流程和结构上发生了些变化,但核心没变,后续有时间会分析下。android 9.0以后的新设备都必须升级到HAL3,后续也会分析HAL3,这也是大势所趋。

尽管camera api1的的相关流程都已经被写烂了,之所以还写,一是想作为一个自己学习的记录,慢慢培养写东西的习惯;二是只有自己真正的去理一遍代码流程,才能真正的搞清楚代码逻辑,印象也更加深刻,就好比只看代码是永远也学不会编程的,必须要实操。

0 创建camera framework层实例

camera API1的接口简单易用,现在依然有很多人喜欢使用这套接口快捷的编写camera apk。本文应用相关的代码来源于android develop 官方示例

// 官方示例
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
   
    Camera c = null;
    try {
   
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
   
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}
  • frameworks/base/core/java/android/hardware/Camera.java
  • 获取当前设备挂载的camera个数,查询后置摄像头并创建camera实例
    public static Camera open() {
   
        int numberOfCameras = getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
   
            getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
   
                return new Camera(i);
            }
        }
        return null;
    }
    /** used by Camera#open, Camera#open(int) */
    Camera(int cameraId) {
   
        int err = cameraInitNormal(cameraId);
        if (checkInitErrors(err)) {
   
            if (err == -EACCES) {
   
                throw new RuntimeException("Fail to connect to camera service");
            } else if (err == -ENODEV) {
   
                throw new RuntimeException("Camera initialization failed");
            }
            // Should never hit this.
            throw new RuntimeException("Unknown camera error");
        }
    }
    private int cameraInitNormal(int cameraId) {
   
        return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
    }
  • 注意上面的实参是CAMERA_HAL_API_VERSION_NORMAL_CONNECT,后面会用到
  • native_setup 是本地函数调用,函数实现在JNI层
    private int cameraInitVersion(int cameraId, int halVersion) {
   
		....
        return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,
                ActivityThread.currentOpPackageName());
    }

1 camera 本地设置

  • frameworks/base/core/jni/android_hardware_Camera.cpp
  {
    "native_setup",
    "(Ljava/lang/Object;IILjava/lang/String;)I",
    (void*)android_hardware_Camera_native_setup },

// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
   
  ……
    sp<Camera> camera;
    if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {
     
        // Default path: hal version is don't care, do normal camera connect.
        camera = Camera::connect(cameraId, clientName,
                Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);   1-1
    } else {
   
        jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
                Camera::USE_CALLING_UID, camera);
        if (status != NO_ERROR) {
   
            return status;
        }
    }
   ……
    // We use a weak reference so the Camera object can be garbage collected.
    // The reference is only used as a proxy for callbacks.
    sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);  1-2
    context->incStrong((void*)android_hardware_Camera_native_setup);
    camera->setListener(context); 	1-3
 } 
  • 因为之前传入的API版本是CAMERA_HAL_API_VERSION_NORMAL_CONNECT,所以会调用1-1处的Camera::connect,这个函数是个静态函数,直接用类名调用
  • 1-2处的JNICameraContext继承了CameraListener,负责回调拍照、预览、录像等数据。
  • 1-3设置监听对象,供camera数据回调

2 Camera本地客户端层

2.1 Camera::connect

  • frameworks/av/camera/Camera.cpp
  • frameworks/av/camera/CameraBase.cpp
// Camera.cpp
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
        int clientUid, int clientPid)
{
   
    return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}

// CameraBase.cpp
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
                                               const String16& clientPackageName,
                                               int clientUid)
{
   
    ALOGV("%s: connect", __FUNCTION__);
    sp<TCam> c = new TCam(cameraId);
    sp<TCamCallbacks> cl = c;
    status_t status = NO_ERROR;
    const sp<ICameraService>& cs = getCameraService();	2-1

    if (cs != 0) {
   
        TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        status = (cs.get()->connect)(cl, cameraId, clientPackageName, clientUid,   /*out*/ c->mCamera); 	2-2
    }
    if 
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android相机硬件抽象层(Camera HAL)是Android系统中的一个组件,它提供了一个标准的接口,使应用程序可以与不同类型的相机硬件进行通信。Camera HAL负责管理相机硬件的驱动程序,并将相机数据传递给应用程序。它还提供了一些功能,如自动对焦、曝光控制和图像处理。Camera HAL是Android相机架构中的重要组成部分,它使得开发人员可以轻松地开发出高质量的相机应用程序。 ### 回答2: Android Camera HAL(硬件抽象层)是一种软件层,它实现了操作系统和相机硬件之间的通信。它为相机硬件提供了一种标准的接口,并允许操作系统与硬件之间进行通信,使用户可以在操作系统的界面上控制相机硬件。HAL为开发人员提供了一种开发相机驱动的标准接口,使他们能够使用相同的API在多个设备上编写相机应用程序。 Android Camera HAL提供了一些常见的功能,例如设置相机参数(如曝光时间、焦距、白平衡等)、捕获图像、处理传感器数据和检测触发事件等。HAL将这些功能作为API提供给应用程序,允许应用程序使用这些功能进行自定义图像处理。 除了这些常见的功能,HAL还放宽了操作系统和硬件之间的联系,因为它提供了一个统一的接口。这意味着开发人员可以通过编写HAL来支持新的相机硬件,而不必修改操作系统的源代码。这种可扩展性使得HAL成为一个非常强大的工具,使开发人员能够轻松地集成新硬件和新功能。 总的来说,Android Camera HAL允许开发人员轻松访问和控制相机硬件,并通过使用标准API开发相机应用程序。HAL还促进了相机硬件的可扩展性和可配置性,因为它提供了一个单一的接口,使得不同的设备可以使用相同的API访问底层硬件。 ### 回答3: Android相机HAL(硬件抽象层)是一种旨在提高Android设备相机性能和兼容性的软件组件。HAL是指在底层(硬件、驱动程序、操作系统等)运行的一组软件接口,它们负责把应用程序的请求翻译成与底层硬件通信的命令。 Android相机HAL负责控制相机的硬件功能,例如焦距、曝光、闪光灯、白平衡和图像处理等。HAL相当于一个中间层,使应用程序能够从硬件细节中解放出来,并以一种统一的方式使用不同的摄像头硬件。 不同厂商的相机硬件有很多不同之处,例如像素密度、传感器类型、镜头质量等等。HAL的设计是为了让所有Android设备的应用程序在不同的相机硬件上都能很好地运行。 在HAL中,有两个主要组件:HAL模块和框架层。HAL模块是用于控制硬件的代码库,包括相机驱动程序、图像处理和传感器控制等。框架层按照HAL接口规范与HAL模块通信,并向应用程序提供相机服务。 与传统的相机API不同,Android相机HAL的架构是在原生级别上实现的。这意味着Android设备的各个供应商可以自由地为硬件开发HAL模块,以适应各自的需求。 总之,Android相机HAL的目的是提高相机性能和兼容性。HAL的设计使所有Android设备的应用程序都能使用不同的摄像头硬件,并简化了与底层硬件的通信。这种设计为各个供应商提供了灵活的发展空间,也推动了Android相机的发展和普及。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值