1. 程式人生 > >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/include/camera/ICamera.h

  class ICamera: public IInterface
  {

virtual status_t    sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;

  };

  frameworks/av/camera/ICamera.cpp //代理端目錄

   Binder呼叫,因為BpCamera、IInterface和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 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/usb/uvc/uvc_v4l2.c
   const struct v4l2_file_operations uvc_fops = {
.owner = THIS_MODULE,
.open= uvc_v4l2_open,
.release = uvc_v4l2_release,
.unlocked_ioctl= uvc_v4l2_ioctl, //對應用層ioctl
   }

13.貼一張圖幫助理解