Android4.4之Camera2预览流程(从APP到Driver)

2024-05-24 04:38

本文主要是介绍Android4.4之Camera2预览流程(从APP到Driver),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android4.4之Camera2预览流程(从APP到Driver)
1.APP调用
  packages/apps/Camera2/src/com/android/camera/PhotoModule.java
      private void startPreview() {
        Log.v(TAG, "startPreview");
        mCameraDevice.startPreviewAsync();
        mFocusManager.onPreviewStarted();
    }




2.Java层
  packages/apps/Camera/src/com/android/camera/CameraManager.java
      public void startPreviewAsync() {
            mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);//发消息:START_PREVIEW_ASYNC
        }
      public void handleMessage(final Message msg) {
            try {
                switch (msg.what) {
                    case START_PREVIEW_ASYNC:
                        mCamera.startPreview();
                        return;  // no need to call mSig.open()
}         
        }




3.定义JNI层
  frameworks/base/core/java/android/hardware/Camera.java
   public native final void startPreview();




4.JNI层
  frameworks/base/core/jni/android_hardware_Camera.cpp、
   static JNINativeMethod camMethods[] = {
   { 
       "startPreview", "()V", (void *)android_hardware_Camera_startPreview },
   };




   static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
   {
    ALOGV("startPreview");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;




    if (camera->startPreview() != NO_ERROR) {
        jniThrowRuntimeException(env, "startPreview failed");
        return;
    }
   }




5.C++层
  frameworks/av/camera/Camera.cpp
  status_t Camera::startPreview()
  {
    ALOGV("startPreview");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->startPreview();
  }




6.frameworks/av/camera/ICamera.cpp //代理端目录
   Binder调用,因为BpCamera和BBinder都继承与IBinder类,在BBinder实现代理端的代码,查找IBinder定义或调用,看谁继承他了,然后在此类里找到startPreview()方法,就是在BBinder服务端实现的服务,与代理端对应。    
   服务端目录:frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
  class BpCamera: public BpInterface<ICamera>
 {
 public:
    BpCamera(const sp<IBinder>& impl)
        : BpInterface<ICamera>(impl)
    {
    }




    // start preview mode, must call setPreviewTarget first
    status_t startPreview()
    {
        ALOGV("startPreview");
        Parcel data, reply;
        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
        remote()->transact(START_PREVIEW, data, &reply);//根据START_PREVIEW跳到对应的Case
        return reply.readInt32();
    }
  };
  对应START_PREVIEW的Case
  IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
  // ----------------------------------------------------------------------
  status_t BnCamera::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
  {
    switch(code) {
        case DISCONNECT: {




        case START_PREVIEW: {
            ALOGV("START_PREVIEW");
            CHECK_INTERFACE(ICamera, data, reply);
            reply->writeInt32(startPreview());
            return NO_ERROR;
        } break;
  }


7.frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp //服务端目录
  <1> CAMERA_PREVIEW_MODE
    status_t CameraClient::startPreview() {
      LOG1("startPreview (pid %d)", getCallingPid());
      return startCameraMode(CAMERA_PREVIEW_MODE);
   }
  
  <2>对应CAMERA_PREVIEW_MODE的Case
    status_t CameraClient::startCameraMode(camera_mode mode) {
    switch(mode) {
        case CAMERA_PREVIEW_MODE:
            if (mSurface == 0 && mPreviewWindow == 0) {
                LOG1("mSurface is not set yet.");
                // still able to start preview in this case.
            }
            return startPreviewMode();
}
   
   <3>startPreviewMode()函数调用mHardware->startPreview();
    status_t CameraClient::startPreviewMode() {




    // if preview has been enabled, nothing needs to be done
    if (mHardware->previewEnabled()) {
        return NO_ERROR;
    }


    if (mPreviewWindow != 0) {
        native_window_set_scaling_mode(mPreviewWindow.get(),
                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
        native_window_set_buffers_transform(mPreviewWindow.get(),
                mOrientation);
    }
    mHardware->setPreviewWindow(mPreviewWindow);
    result = mHardware->startPreview();




    return result;
   }


8.frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h
      status_t startPreview()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->start_preview)
            return mDevice->ops->start_preview(mDevice);
        return INVALID_OPERATION;
    }


9.HAL头文件
  <1>start_preview头文件位置
     hardware/libhardware/include/hardware/camera.h
    
  <2>结构体:camera_device mDevice;
     typedef struct camera_device {
      hw_device_t common;
      camera_device_ops_t *ops;//ops
      void *priv;
    } camera_device_t;//mDevice




  <3>结构体:camera_device_ops ops;
  typedef struct camera_device_ops {




    int (*start_preview)(struct camera_device *);
   } camera_device_ops_t;




10.HAL层源码位置:
     hardware/leadcore/libcamera/ComipCameraHWInterface.cpp
     
   <1> extern "C" {
     struct camera_module HAL_MODULE_INFO_SYM = {
        common : {
            tag        : HARDWARE_MODULE_TAG,
            module_api_version    : CAMERA_MODULE_API_VERSION_1_0,//0x0100, add by zgs 2012.12.28 ,to choose HAL version
            hal_api_version    : HARDWARE_HAL_API_VERSION,//0x00
            id        : CAMERA_HARDWARE_MODULE_ID,//硬件标识的ID
            name        : "Leadcore camera HAL",
            author        : "Leadcore Corporation",
            methods        : &camera_module_methods,//HAL操作方法集
            dso:        NULL,
            reserved:    {0},
        },
        get_number_of_cameras  : HAL_getNumberOfCameras,
        get_camera_info        : HAL_getCameraInfo,
        set_callbacks          : HAL_setCallbacks,
        get_vendor_tag_ops     : HAL_getVendorTagOps,
        reserved               : {0}
      };
   }




  <2>HAL操作方法集
   static hw_module_methods_t camera_module_methods = {
    open : HAL_camera_device_open
   };




  <3>HAL_camera_device_open()函数
     static int HAL_camera_device_open(const struct hw_module_t* module,
                    const char *id,
                    struct hw_device_t** device)
   {
    LOG2("HAL_camera_device_open");




    int cameraId = atoi(id);
    if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) {
        ALOGE("invalid camera ID %s", id);
        return -EINVAL;
    }




    if (g_cam_device) {
        if (obj(g_cam_device)->getCameraId() == cameraId) {
            LOG2("returning existing camera ID %s", id);
            goto done;
        } else {
            ALOGE("cannot open camera %d. camera %d is already running!",
                cameraId, obj(g_cam_device)->getCameraId());
            return -ENOSYS;
        }
    }




    g_cam_device = (camera_device_t *)malloc(sizeof(camera_device_t));
    if (!g_cam_device)
        return -ENOMEM;




    g_cam_device->common.tag    = HARDWARE_DEVICE_TAG;
    g_cam_device->common.version    = 1;
    g_cam_device->common.module    = const_cast<hw_module_t *>(module);
    g_cam_device->common.close    = HAL_camera_device_close;




    g_cam_device->ops = &camera_device_ops; //HAL功能操作集
    g_cam_device->priv = new CameraHardwareComip(cameraId, g_cam_device);




 done:
    *device = (hw_device_t *)g_cam_device;
    LOG2("opened camera %s (%p)", id, *device);
    return 0;
  }
  
  <4>camera_device_ops();//HAL功能操作集函数
     #define SET_METHOD(m) m : HAL_camera_device_##m
      
     static camera_device_ops_t camera_device_ops = {
        SET_METHOD(stop_preview),//SET_METHOD()函数的功能即,把start_preview()变为HAL_camera_device_start_preview()的功能。
     };




  <5>把start_preview()变为HAL_camera_device_start_preview()函数
     static int HAL_camera_device_start_preview(struct camera_device *dev)
   {
    LOG2("HAL_camera_device_start_preview");
    return obj(dev)->startPreview();
   }




  <6>startPreview()函数
     status_t CameraHardwareComip::startPreview()
     {
       int ret = startPreviewInternal();
     }




  <7>startPreviewInternal()函数
     status_t CameraHardwareComip::startPreviewInternal()
    {
      ret = mComipCamera->startPreview();
    }




11.HAL调用V4L2操作
  <1>startPreview()函数调用
     hardware/leadcore/libcamera/ComipCamera.cpp
     int ComipCamera::startPreview(void)
   {
    int ret = v4l2_streamon(m_cam_fd, m_preview_buf_type);
   }




 <2>v4l2_streamon()函数
    static int v4l2_streamon(int fp, enum v4l2_buf_type type)
  {
    ret = ioctl(fp, VIDIOC_STREAMON, &type);
  }




12.Kernel层调用V4L2驱动
   kernel/linux-3.10/drivers/media/v4l2-core/v4l2-dev.c
   static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
   {
     if(vdev->fops->unlocked_ioctl) {
ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
   }



这篇关于Android4.4之Camera2预览流程(从APP到Driver)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/997397

相关文章

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

Java实现预览与打印功能详解

《Java实现预览与打印功能详解》在Java中,打印功能主要依赖java.awt.print包,该包提供了与打印相关的一些关键类,比如PrinterJob和PageFormat,它们构成... 目录Java 打印系统概述打印预览与设置使用 PageFormat 和 PrinterJob 类设置页面格式与纸张

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

使用JavaConfig配置Spring的流程步骤

《使用JavaConfig配置Spring的流程步骤》JavaConfig是Spring框架提供的一种基于Java的配置方式,它通过使用@Configuration注解标记的类来替代传统的XML配置文... 目录一、什么是 JavaConfig?1. 核心注解2. 与 XML 配置的对比二、JavaConf