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

相关文章

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

Java对接Dify API接口的完整流程

《Java对接DifyAPI接口的完整流程》Dify是一款AI应用开发平台,提供多种自然语言处理能力,通过调用Dify开放API,开发者可以快速集成智能对话、文本生成等功能到自己的Java应用中,本... 目录Java对接Dify API接口完整指南一、Dify API简介二、准备工作三、基础对接实现1.

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式