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

相关文章

MySQL 临时表与复制表操作全流程案例

《MySQL临时表与复制表操作全流程案例》本文介绍MySQL临时表与复制表的区别与使用,涵盖生命周期、存储机制、操作限制、创建方法及常见问题,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小... 目录一、mysql 临时表(一)核心特性拓展(二)操作全流程案例1. 复杂查询中的临时表应用2. 临时

MySQL 升级到8.4版本的完整流程及操作方法

《MySQL升级到8.4版本的完整流程及操作方法》本文详细说明了MySQL升级至8.4的完整流程,涵盖升级前准备(备份、兼容性检查)、支持路径(原地、逻辑导出、复制)、关键变更(空间索引、保留关键字... 目录一、升级前准备 (3.1 Before You Begin)二、升级路径 (3.2 Upgrade

kkFileView在线预览office的常见问题以及解决方案

《kkFileView在线预览office的常见问题以及解决方案》kkFileView在线预览Office常见问题包括base64编码配置、Office组件安装、乱码处理及水印添加,解决方案涉及版本适... 目录kkFileView在线预览office的常见问题1.base642.提示找不到OFFICE组件

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

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 (模块级