zoukankan      html  css  js  c++  java
  • Android Camera 运行流程

    首先既然Camera是利用binder通信,它肯定要将它的service注册到ServiceManager里面,以备后续Client引用,那么这一步是在哪里进行的呢?细心的人会发现,在frameworks\base\media\mediaserver\Main_MediaServer.cpp下有个main函数,可以用来注册媒体服务。没错就是在这里,CameraService完成了服务的注册,相关代码如下:

    int main(int argc, char** argv) {      sp<ProcessState> proc(ProcessState::self());      sp<IServiceManager> sm = defaultServiceManager();      LOGI("ServiceManager: %p", sm.get());      AudioFlinger::instantiate();      MediaPlayerService::instantiate();      CameraService::instantiate();      AudioPolicyService::instantiate();      ProcessState::self()->startThreadPool();      IPCThreadState::self()->joinThreadPool(); }

    可是我们到CameraService文件里面却找不到instantiate()这个函数,它在哪?继续追到它的一个父类BinderService,

    CameraService的定义在frameworks/base/services/camera/libcameraservice/CameraService.h中

    class CameraService :      public BinderService<CameraService>,      public BnCameraService {      class Client;      friend class BinderService<CameraService>; public:      static char const* getServiceName() { return "media.camera"; }      .....

        .....

    }

    从以上定义可以看出CameraService 继承于BinderService,所以CameraService::instantiate(); 其实是调用BinderService中的instantiate

    BinderService的定义在frameworks/base/include/binder/BinderService.h中

    // --------------------------------------------------------------------------- namespace android {
    template<typename SERVICE> class BinderService { public:     static status_t publish() {         sp<IServiceManager> sm(defaultServiceManager());         return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());     }
        static void publishAndJoinThreadPool() {         sp<ProcessState> proc(ProcessState::self());         sp<IServiceManager> sm(defaultServiceManager());         sm->addService(String16(SERVICE::getServiceName()), new SERVICE());         ProcessState::self()->startThreadPool();         IPCThreadState::self()->joinThreadPool();     }
        static void instantiate() { publish(); }
        static status_t shutdown() {         return NO_ERROR;     } };
    }; // namespace android // --------------------------------------------------------------------------- 可以发现在publish()函数中,CameraService完成服务的注册 。这里面有个SERVICE,源码中有说明

    template<typename SERVICE>
    这表示SERVICE是个模板,这里是注册CameraService,所以可以用CameraService代替
    return sm->addService(String16(CameraService::getServiceName()), new CameraService());
    好了这样,Camera就在ServiceManager完成服务注册,提供给client随时使用。
    Main_MediaServer主函数由init.rc在启动是调用,所以在设备开机的时候Camera就会注册一个服务,用作binder通信。

    Binder服务已注册,那接下来就看看client如何连上server端,并打开camera模块。咱们先从camera app的源码入手。在onCreate()函数中专门有一个open Camera的线程

    camera app的源码文件在以下目录packages/apps/OMAPCamera/src/com/ti/omap4/android/camera/camera.java      @Override      public void onCreate(Bundle icicle) {          super.onCreate(icicle);          getPreferredCameraId();          String[] defaultFocusModes = getResources().getStringArray(                  R.array.pref_camera_focusmode_default_array);          mFocusManager = new FocusManager(mPreferences, defaultFocusModes);
             /*           * To reduce startup time, we start the camera open and preview threads.           * We make sure the preview is started at the end of onCreate.           */          mCameraOpenThread.start();
             PreferenceInflater inflater = new PreferenceInflater(this);          PreferenceGroup group =                  (PreferenceGroup) inflater.inflate(R.xml.camera_preferences);
             ListPreference gbce = group.findPreference(CameraSettings.KEY_GBCE);          if (gbce != null) {              mGBCEOff = gbce.findEntryValueByEntry(getString(R.string.pref_camera_gbce_entry_off));              if (mGBCEOff == null) {                  mGBCEOff = "";              }          }
             ListPreference autoConvergencePreference = group.findPreference(CameraSettings.KEY_AUTO_CONVERGENCE);          if (autoConvergencePreference != null) {              mTouchConvergence = autoConvergencePreference.findEntryValueByEntry(getString(R.string.pref_camera_autoconvergence_entry_mode_touch));              if (mTouchConvergence == null) {                  mTouchConvergence = "";              }              mManualConvergence = autoConvergencePreference.findEntryValueByEntry(getString(R.string.pref_camera_autoconvergence_entry_mode_manual));              if (mManualConvergence == null) {                  mManualConvergence = "";              }          }
             ListPreference exposure = group.findPreference(CameraSettings.KEY_EXPOSURE_MODE_MENU);          if (exposure != null) {              mManualExposure = exposure.findEntryValueByEntry(getString(R.string.pref_camera_exposuremode_entry_manual));              if (mManualExposure == null) {                  mManualExposure = "";              }          }
             ListPreference temp = group.findPreference(CameraSettings.KEY_MODE_MENU);          if (temp != null) {              mTemporalBracketing = temp.findEntryValueByEntry(getString(R.string.pref_camera_mode_entry_temporal_bracketing));              if (mTemporalBracketing == null) {                  mTemporalBracketing = "";              }
                 mExposureBracketing = temp.findEntryValueByEntry(getString(R.string.pref_camera_mode_entry_exp_bracketing));              if (mExposureBracketing == null) {                  mExposureBracketing = "";              }
                 mZoomBracketing = temp.findEntryValueByEntry(getString(R.string.pref_camera_mode_entry_zoom_bracketing));              if (mZoomBracketing == null) {                  mZoomBracketing = "";              }
                 mHighPerformance = temp.findEntryValueByEntry(getString(R.string.pref_camera_mode_entry_hs));              if (mHighPerformance == null) {                  mHighPerformance = "";              }
                 mHighQuality = temp.findEntryValueByEntry(getString(R.string.pref_camera_mode_entry_hq));              if (mHighQuality == null) {                  mHighQuality = "";              }
                 mHighQualityZsl = temp.findEntryValueByEntry(getString(R.string.pref_camera_mode_entry_zsl));              if (mHighQualityZsl == null) {                  mHighQualityZsl = "";              }          }
             getPreferredCameraId();          mFocusManager = new FocusManager(mPreferences,                  defaultFocusModes);          mTouchManager = new TouchManager();
             mIsImageCaptureIntent = isImageCaptureIntent();          setContentView(R.layout.camera);          if (mIsImageCaptureIntent) {              mReviewDoneButton = (Rotatable) findViewById(R.id.btn_done);              mReviewCancelButton = (Rotatable) findViewById(R.id.btn_cancel);              findViewById(R.id.btn_cancel).setVisibility(View.VISIBLE);          } else {              mThumbnailView = (RotateImageView) findViewById(R.id.thumbnail);              mThumbnailView.enableFilter(false);              mThumbnailView.setVisibility(View.VISIBLE);          }
             mRotateDialog = new RotateDialogController(this, R.layout.rotate_dialog);          mCaptureLayout = getString(R.string.pref_camera_capture_layout_default);
             mPreferences.setLocalId(this, mCameraId);          CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
             mNumberOfCameras = CameraHolder.instance().getNumberOfCameras();          mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
             // we need to reset exposure for the preview          resetExposureCompensation();
             Util.enterLightsOutMode(getWindow());
             // don't set mSurfaceHolder here. We have it set ONLY within          // surfaceChanged / surfaceDestroyed, other parts of the code          // assume that when it is set, the surface is also set.          SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);          SurfaceHolder holder = preview.getHolder();          holder.addCallback(this);
             s3dView = new S3DViewWrapper(holder);
             holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
             // Make sure camera device is opened.          try {              mCameraOpenThread.join();              mCameraOpenThread = null;              if (mOpenCameraFail) {                  Util.showErrorAndFinish(this, R.string.cannot_connect_camera);                  return;              } else if (mCameraDisabled) {                  Util.showErrorAndFinish(this, R.string.camera_disabled);                  return;              }          } catch (InterruptedException ex) {              // ignore          }          mCameraPreviewThread.start();
             if (mIsImageCaptureIntent) {              setupCaptureParams();          } else {              mModePicker = (ModePicker) findViewById(R.id.mode_picker);              mModePicker.setVisibility(View.VISIBLE);              mModePicker.setOnModeChangeListener(this);              mModePicker.setCurrentMode(ModePicker.MODE_CAMERA);          }
             mZoomControl = (ZoomControl) findViewById(R.id.zoom_control);          mOnScreenIndicators = (Rotatable) findViewById(R.id.on_screen_indicators);          mLocationManager = new LocationManager(this, this);
             // Wait until the camera settings are retrieved.          synchronized (mCameraPreviewThread) {              try {                  mCameraPreviewThread.wait();              } catch (InterruptedException ex) {                  // ignore              }          }
             // Do this after starting preview because it depends on camera          // parameters.          initializeIndicatorControl();          mCameraSound = new CameraSound();
             // Make sure preview is started.          try {              mCameraPreviewThread.join();          } catch (InterruptedException ex) {              // ignore          }          mCameraPreviewThread = null;      } 再看看mCameraOpenThread

        Thread mCameraOpenThread = new Thread(new Runnable() {          public void run() {              try {                  mCameraDevice = Util.openCamera(Camera.this, mCameraId);              } catch (CameraHardwareException e) {                  mOpenCameraFail = true;              } catch (CameraDisabledException e) {                  mCameraDisabled = true;              }          }      });

    继续追Util.openCamera ,Util类的定义在以下目录:packages/apps/OMAPCamera/src/com/ti/omap4/android/camera/Util.java      public static android.hardware.Camera openCamera(Activity activity, int cameraId)              throws CameraHardwareException, CameraDisabledException {          // Check if device policy has disabled the camera.          DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService(                  Context.DEVICE_POLICY_SERVICE);          if (dpm.getCameraDisabled(null)) {              throw new CameraDisabledException();          }
             try {              return CameraHolder.instance().open(cameraId);          } catch (CameraHardwareException e) {              // In eng build, we throw the exception so that test tool              // can detect it and report it              if ("eng".equals(Build.TYPE)) {                  throw new RuntimeException("openCamera failed", e);              } else {                  throw e;              }          }      } 又来了个CameraHolder,该类用一个实例openCamera

    CameraHolder的定义在以下目录:packages/apps/OMAPCamera/src/com/ti/omap4/android/camera/CameraHolder.java

        public synchronized android.hardware.Camera open(int cameraId)              throws CameraHardwareException {          Assert(mUsers == 0);          if (mCameraDevice != null && mCameraId != cameraId) {              mCameraDevice.release();              mCameraDevice = null;              mCameraId = -1;          }          if (mCameraDevice == null) {              try {                  Log.v(TAG, "open camera " + cameraId);                  mCameraDevice = android.hardware.Camera.open(cameraId);                  mCameraId = cameraId;              } catch (RuntimeException e) {                  Log.e(TAG, "fail to connect Camera", e);                  throw new CameraHardwareException(e);              }              mParameters = mCameraDevice.getParameters();          } else {              try {                  mCameraDevice.reconnect();              } catch (IOException e) {                  Log.e(TAG, "reconnect failed.");                  throw new CameraHardwareException(e);              }              mCameraDevice.setParameters(mParameters);          }          ++mUsers;          mHandler.removeMessages(RELEASE_CAMERA);          mKeepBeforeTime = 0;          return mCameraDevice;      }

    在这里就开始进入framework层了,调用frameworks\base\core\java\android\hardware\Camera.java类的open方法 。

        public static Camera open(int cameraId) {          return new Camera(cameraId);      } 这里调用了Camera的构造函数,在看看构造函数      Camera(int cameraId) {          mShutterCallback = null;          mRawImageCallback = null;          mJpegCallback = null;          mPreviewCallback = null;          mPostviewCallback = null;          mZoomListener = null;
             Looper looper;          if ((looper = Looper.myLooper()) != null) {              mEventHandler = new EventHandler(this, looper);          } else if ((looper = Looper.getMainLooper()) != null) {              mEventHandler = new EventHandler(this, looper);          } else {              mEventHandler = null;          }
            native_setup(new WeakReference<Camera>(this), cameraId);      } 好,终于来到JNI了

    继续看camera的JNI文件:frameworks/base/core/jni# gedit android_hardware_Camera.cpp

    由于前面Camera的构造函数里调用了native_setup(new WeakReference<Camera>(this), cameraId);

    那么native_setup()的定义在那里呢

    通过我的查看,在frameworks/base/core/jni# gedit android_hardware_Camera.cpp中有这样一个定义,

    我认为通过这个定义,使得native_setup和android_hardware_Camera_native_setup 关联起来

    static JNINativeMethod camMethods[] = {    { "getNumberOfCameras",      "()I",      (void *)android_hardware_Camera_getNumberOfCameras },    { "getCameraInfo",      "(ILandroid/hardware/Camera$CameraInfo;)V",      (void*)android_hardware_Camera_getCameraInfo },   { "native_setup",     "(Ljava/lang/Object;I)V",     (void*)android_hardware_Camera_native_setup },    { "native_release",      "()V",      (void*)android_hardware_Camera_release },    { "setPreviewDisplay",      "(Landroid/view/Surface;)V",      (void *)android_hardware_Camera_setPreviewDisplay },    { "setPreviewTexture",      "(Landroid/graphics/SurfaceTexture;)V",      (void *)android_hardware_Camera_setPreviewTexture },    { "startPreview",      "()V",      (void *)android_hardware_Camera_startPreview },    { "_stopPreview",      "()V",      (void *)android_hardware_Camera_stopPreview },    { "previewEnabled",      "()Z",      (void *)android_hardware_Camera_previewEnabled },    { "setHasPreviewCallback",      "(ZZ)V",      (void *)android_hardware_Camera_setHasPreviewCallback },    { "_addCallbackBuffer",      "([BI)V",      (void *)android_hardware_Camera_addCallbackBuffer },    { "native_autoFocus",      "()V",      (void *)android_hardware_Camera_autoFocus },    { "native_cancelAutoFocus",      "()V",      (void *)android_hardware_Camera_cancelAutoFocus },    { "native_takePicture",      "(I)V",      (void *)android_hardware_Camera_takePicture },    { "native_setParameters",      "(Ljava/lang/String;)V",      (void *)android_hardware_Camera_setParameters },    { "native_getParameters",      "()Ljava/lang/String;",      (void *)android_hardware_Camera_getParameters },    { "reconnect",      "()V",      (void*)android_hardware_Camera_reconnect },    { "lock",      "()V",      (void*)android_hardware_Camera_lock },    { "unlock",      "()V",      (void*)android_hardware_Camera_unlock },    { "startSmoothZoom",      "(I)V",      (void *)android_hardware_Camera_startSmoothZoom },    { "stopSmoothZoom",      "()V",      (void *)android_hardware_Camera_stopSmoothZoom },    { "setDisplayOrientation",      "(I)V",      (void *)android_hardware_Camera_setDisplayOrientation },    { "_startFaceDetection",      "(I)V",      (void *)android_hardware_Camera_startFaceDetection },    { "_stopFaceDetection",      "()V",      (void *)android_hardware_Camera_stopFaceDetection}, };

    所以,native_setup(new WeakReference<Camera>(this), cameraId);这个调用即是对下面android_hardware_Camera_native_setup这个函数的调用

    // connect to camera service static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,     jobject weak_this, jint cameraId) {     sp<Camera> camera = Camera::connect(cameraId);
        if (camera == NULL) {         jniThrowRuntimeException(env, "Fail to connect to camera service");         return;     }
        // make sure camera hardware is alive     if (camera->getStatus() != NO_ERROR) {         jniThrowRuntimeException(env, "Camera initialization failed");         return;     }
        jclass clazz = env->GetObjectClass(thiz);     if (clazz == NULL) {         jniThrowRuntimeException(env, "Can't find android/hardware/Camera");         return;     }
        // 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);     context->incStrong(thiz);     camera->setListener(context);
        // save context in opaque field     env->SetIntField(thiz, fields.context, (int)context.get()); } JNI函数里面,我们找到Camera C/S架构的客户端了,它调用connect函数向服务器发送连接请求。JNICameraContext这个类是一个监听类,用于处理底层Camera回调函数传来的数据和消息 看看客户端的connect函数有什么,connect定义在以下路径frameworks/base/libs/camera/camera.cpp

    sp<Camera> Camera::connect(int cameraId) {      LOGV("connect");      sp<Camera> c = new Camera();      const sp<ICameraService>& cs = getCameraService();      if (cs != 0) {          c->mCamera = cs->connect(c, cameraId);      }      if (c->mCamera != 0) {          c->mCamera->asBinder()->linkToDeath(c);          c->mStatus = NO_ERROR;      } else {          c.clear();      }      return c; }

    const sp<ICameraService>& cs =getCameraService();获取CameraService实例。

    进入getCameraService()中

    // establish binder interface to camera service const sp<ICameraService>& Camera::getCameraService() {      Mutex::Autolock _l(mLock);      if (mCameraService.get() == 0) {          sp<IServiceManager> sm = defaultServiceManager();          sp<IBinder> binder;          do {              binder = sm->getService(String16("media.camera"));              if (binder != 0)                  break;              LOGW("CameraService not published, waiting...");              usleep(500000); // 0.5 s          } while(true);          if (mDeathNotifier == NULL) {              mDeathNotifier = new DeathNotifier();          }          binder->linkToDeath(mDeathNotifier);          mCameraService = interface_cast<ICameraService>(binder);      }      LOGE_IF(mCameraService==0, "no CameraService!?");      return mCameraService; } CameraService实例通过binder获取的,mCameraService即为CameraService的实例。   回到sp<Camera> Camera::connect(int cameraId)中 c->mCamera = cs->connect(c, cameraId); 即:执行server的connect()函数,并且返回ICamera对象,赋值给Camera的mCamera,服务端connect()返回的是他内部类的一个实例。 server的connect()函数定义在以下路径:frameworks/base/services/camera/libcameraservice/CameraService.cpp

    sp<ICamera> CameraService::connect(          const sp<ICameraClient>& cameraClient, int cameraId) {      int callingPid = getCallingPid();      sp<CameraHardwareInterface> hardware = NULL;
         LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
         if (!mModule) {          LOGE("Camera HAL module not loaded");          return NULL;      }
         sp<Client> client;      if (cameraId < 0 || cameraId >= mNumberOfCameras) {          LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",              callingPid, cameraId);          return NULL;      }
         char value[PROPERTY_VALUE_MAX];      property_get("sys.secpolicy.camera.disabled", value, "0");      if (strcmp(value, "1") == 0) {          // Camera is disabled by DevicePolicyManager.          LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);          return NULL;      }
         Mutex::Autolock lock(mServiceLock);      if (mClient[cameraId] != 0) {          client = mClient[cameraId].promote();          if (client != 0) {              if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {                  LOG1("CameraService::connect X (pid %d) (the same client)",                      callingPid);                  return client;              } else {                  LOGW("CameraService::connect X (pid %d) rejected (existing client).",                      callingPid);                  return NULL;              }          }          mClient[cameraId].clear();      }
         if (mBusy[cameraId]) {          LOGW("CameraService::connect X (pid %d) rejected"               " (camera %d is still busy).", callingPid, cameraId);          return NULL;      }
         struct camera_info info;      if (mModule->get_camera_info(cameraId, &info) != OK) {          LOGE("Invalid camera id %d", cameraId);          return NULL;      }
         char camera_device_name[10];      snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
         hardware = new CameraHardwareInterface(camera_device_name);      if (hardware->initialize(&mModule->common) != OK) {          hardware.clear();          return NULL;      }
        client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);      mClient[cameraId] = client;      LOG1("CameraService::connect X");      return client; } 实例化Camera Hal接口 hardware,hardware调用initialize()进入HAL层打开Camear驱动。 CameraHardwareInterface中initialize()定义在以下路径:frameworks/base/services/camera/libcameraservice/CameraHardwareInterface.h

    代码如下:

        status_t initialize(hw_module_t *module)      {          LOGI("Opening camera %s", mName.string());          int rc = module->methods->open(module, mName.string(),                                        (hw_device_t **)&mDevice);          if (rc != OK) {              LOGE("Could not open camera %s: %d", mName.string(), rc);              return rc;          } #ifdef OMAP_ENHANCEMENT_CPCAM          initHalPreviewWindow(&mHalPreviewWindow);          initHalPreviewWindow(&mHalTapin);          initHalPreviewWindow(&mHalTapout); #else          initHalPreviewWindow(); #endif          return rc;      } 此处通过module->method->open()方法真正打开Camera设备,

    其中module的定义在以下路径:

    class CameraService :      public BinderService<CameraService>,      public BnCameraService {

        class Client : public BnCamera      {      public:          ......

        private:

            .....

        };

       camera_module_t *mModule;

    };

    此处还必须找到camera_module_t 的定,以更好的理解整个运行流程,通过追根溯源找到了camera_module_t 定义,

    camera_module_t的定义在以下路径:hardware/libhardware/include/hardware/camera.h中,定义如下

    typedef struct camera_module {     hw_module_t common;     int (*get_number_of_cameras)(void);     int (*get_camera_info)(int camera_id, struct camera_info *info); } camera_module_t; 其中包含get_number_of_cameras方法和get_camera_info方法用于获取camera info

    另外hw_module_t common;这个选项十分重要,此处应重点关注,因为是使用hw_module_t结构体中的open()方法打开设备文件的

    继续找到hw_module_t 结构体的定义.在以下路径:hardware/libhardware/include/hardware/hardware.h,代码如下:

    struct hw_module_t; struct hw_module_methods_t; struct hw_device_t;
    /** * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM * and the fields of this data structure must begin with hw_module_t * followed by module specific information. */ typedef struct hw_module_t {     /** tag must be initialized to HARDWARE_MODULE_TAG */     uint32_t tag;
        /** major version number for the module */     uint16_t version_major;
        /** minor version number of the module */     uint16_t version_minor;
        /** Identifier of module */     const char *id;
        /** Name of this module */     const char *name;
        /** Author/owner/implementor of the module */     const char *author;
        /** Modules methods */    struct hw_module_methods_t* methods;
        /** module's dso */     void* dso;
        /** padding to 128 bytes, reserved for future use */     uint32_t reserved[32-7];
    } hw_module_t;

    同样,找到hw_module_methods_t这个结构体的定义,代码如下:

    typedef struct hw_module_methods_t {      /** Open a specific device */     int (*open)(const struct hw_module_t* module, const char* id,             struct hw_device_t** device); } hw_module_methods_t;

    hw_module_methods_t 结构体中只有open()一个方法,用于打开camera driver,实现与硬件层的交互
    到此为止,很容易看出:

    Android中Camera的调用流程可分为以下几个层次:
    Package->Framework->JNI->Camera(cpp)--(binder)-->CameraService->Camera HAL->Camera Driver

  • 相关阅读:
    LeetCode 485. Max Consecutive Ones
    LeetCode 367. Valid Perfect Square
    LeetCode 375. Guess Number Higher or Lower II
    LeetCode 374. Guess Number Higher or Lower
    LeetCode Word Pattern II
    LeetCode Arranging Coins
    LeetCode 422. Valid Word Square
    Session 共享
    java NIO
    非阻塞IO
  • 原文地址:https://www.cnblogs.com/wangxianzhen/p/3013285.html
Copyright © 2011-2022 走看看