乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      android?camera框架分析與移植

       昵稱7324690 2012-08-25

      android camera框架分析與移植

      (2011-08-12 23:47:52)
      標(biāo)簽:

      雜談

      分類: Android

      俗話說:知己知彼,百戰(zhàn)不殆,想要移植camera硬件,需要了解android中camera的框架思想和調(diào)用流程,才能事半功倍。

       

      (1)       Android中camera編程思路:

           Camera類介紹:

      常用接口,這些接口是camera編程時作為框架層回調(diào)時候使用:

       

      android <wbr>camera框架分析與移植

      常用方法,這些方法作為camera應(yīng)用編程時使用的API

         android <wbr>camera框架分析與移植

       

      在應(yīng)用層的編程上常用流程為:

      預(yù)覽: 

          mCamera = Camera.open();

      Camera.Parameters p = mCamera.getParameters();

        p.setPreviewSize(w, h);

        mCamera.setParameters(p);
       

      SurfaceView  mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);

        SurfaceHolder  holder = mSurfaceView.getHolder();

        holder.addCallback(this);

        mCamera.setPreviewDisplay(holder);

        mCamera.startPreview();

       

      當(dāng)我們打開攝像頭應(yīng)用的時候首先是預(yù)覽的功能,預(yù)覽就是將攝像頭拍攝下的景物實(shí)時的呈現(xiàn)出來,在android應(yīng)用中能夠顯示給用戶交互的類都是繼承自view類,我們需要給camera預(yù)覽顯示時提供一個畫布一樣的東西,這里我們使用surfaceview類,為什么不直接使用view類呢?關(guān)于view顯示的框架我將在以后的博文中給大家分析,這里使用surfaceview類作為camera的顯示,可以使camera框架層得到一個可以控制顯示框架的代理,使用這個代理可以將camera獲取的幀數(shù)據(jù)發(fā)送到顯示框架去合成顯示,如果我們設(shè)置了預(yù)覽回調(diào):

      android <wbr>camera框架分析與移植

      也可以在回調(diào)中將每一幀的數(shù)據(jù)保存起來形成錄像的功能


      拍照:
          mCamera.takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg)

      拍照本身調(diào)用就需要設(shè)置回調(diào)函數(shù),回調(diào)函數(shù)中可以設(shè)置幾種回調(diào)方式,這幾種都是拍照時框架層提供給應(yīng)用層數(shù)據(jù),有原始數(shù)據(jù),有jpeg數(shù)據(jù),這幾種都是拍攝下來的數(shù)據(jù)的不同儲存方式,供我們在應(yīng)用層處理使用。

       

      小結(jié):在應(yīng)用層上我們可以了解到什么?

      預(yù)覽和拍照都可以通過回調(diào)的方式獲取框架層的數(shù)據(jù),當(dāng)然預(yù)覽也可以不需要把框架層的數(shù)據(jù)獲取,直接發(fā)給顯示框架去顯示。

       

      (2)       現(xiàn)在我們要開始分析camera類代碼了解調(diào)用細(xì)節(jié):

       

       

      Camera.java (frameworks\base\core\java\android\hardware)     

      public static Camera open() {

              return new Camera(); //構(gòu)造camera

          }

       

          Camera() {

              mShutterCallback = null;

              mRawImageCallback = null;

              mJpegCallback = null;

              mPreviewCallback = null;

              mPostviewCallback = null;

              mZoomCallback = null;

       

              Looper looper;

              if ((looper = Looper.myLooper()) != null) { //創(chuàng)建Handler,處理本地的通知事件

                  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)); //調(diào)用本地方法,完成初始化

          }

       

          private native final void native_setup(Object camera_this);

         

      WeakReference 類的作用:如果想觀察一個類什么時候被垃圾回收清除,我們使用WeakReference類來定義,當(dāng)Camera類的引用為null是,可以通過WeakReferenceget方法獲取此類的信息,了解此類是否被垃圾回收

       

      EventHandler調(diào)用流程;

       

       

      android <wbr>camera框架分析與移植

       

       

      (1)        private native final void native_setup(Object camera_this);

      (2)        private native final void native_setParameters(String params);

      (3)        private native final String native_getParameters();

      (4)        private native final void setPreviewDisplay(Surface surface);

      (5)        public native final void startPreview();

       

      camera中我們發(fā)現(xiàn)應(yīng)用層代碼調(diào)用中都調(diào)用了本地(native)方法

       

       

       

      android <wbr>camera框架分析與移植



       

       

       

      Camera在應(yīng)用層做了重要的兩件是,初始化一個EventHandler,等待本地消息通知,調(diào)用本地方法進(jìn)入jni層代碼空間,在這里jni的調(diào)用方向有兩種:

      1):java調(diào)用C/C++代碼,將用戶功能性的代碼放到jni層處理

      2):C/C++代碼調(diào)用java層代碼,將框架層的消息傳遞給應(yīng)用層處理

       

      (2) Camera jni層代碼:

      android_hardware_Camera.cpp (frameworks\base\core\jni)      

       

      int register_android_hardware_Camera(JNIEnv *env)

      {

          field fields_to_find[] = {

              { "android/hardware/Camera", "mNativeContext",   "I", &fields.context },

              { "android/view/Surface",    "mSurface",         "I", &fields.surface }

          };

       

       

      //初始化fields_t結(jié)構(gòu)體contextsurface

          if (find_fields(env, fields_to_find, NELEM(fields_to_find)) < 0)        return -1;

       

          jclass clazz = env->FindClass("android/hardware/Camera");

      //初始化fields_t結(jié)構(gòu)體post_event

          fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",

                                                     "(Ljava/lang/Object;IIILjava/lang/Object;)V");

          if (fields.post_event == NULL) {

              LOGE("Can't find android/hardware/Camera.postEventFromNative");

              return -1;

          }

       

       

          // Register native functions 注冊本地函數(shù)列表

          return AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",

                                                    camMethods, NELEM(camMethods));

      }

       

      int register_android_hardware_Camera方法是首先調(diào)用的方法,作用是將java層的變量域和方法域存在jni層,jni層調(diào)用java層的成員變量和成員方法都要依賴域:

      struct fields_t {

          jfieldID    context;// mNativeContext

          jfieldID    surface;// mSurface

          jmethodID   post_event;// postEventFromNative

      };

       

       

      AndroidRuntime::registerNativeMethods 方法主要是將本地函數(shù)注冊給虛擬機(jī),java層可以通過虛擬機(jī)調(diào)用這些方法

      static JNINativeMethod camMethods[] = {

        { "native_setup",

          "(Ljava/lang/Object;)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 },

        { "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",

          "([B)V",

          (void *)android_hardware_Camera_addCallbackBuffer },

        { "native_autoFocus",

          "()V",

          (void *)android_hardware_Camera_autoFocus },

        { "native_cancelAutoFocus",

          "()V",

          (void *)android_hardware_Camera_cancelAutoFocus },

        { "native_takePicture",

          "()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 },

      };

       

      JNINativeMethod列出java層方法和c/c++層方法的映射表:

       

       

      android <wbr>camera框架分析與移植

       

       

      1android_hardware_Camera_native_setup方法

       

      這個方法主要作用是建立如圖的聯(lián)系:

       

      android <wbr>camera框架分析與移植

       sp<Camera> camera = Camera::connect();//初始化三組proxy/stub聯(lián)系

          sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);

          context->incStrong(thiz);

          camera->setListener(context);//初始化mListener

          env->SetIntField(thiz, fields.context, (int)context.get());

       

        

      隨后產(chǎn)生server和HAL之間的聯(lián)系:

       

      android <wbr>camera框架分析與移植

      void CameraService::Client::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user)

      {

          LOGV("dataCallback(%d)", msgType);

       

          sp<Client> client = getClientFromCookie(user);

          if (client == 0) {

              return;

          }

       

          sp<ICameraClient> c = client->mCameraClient;

          if (dataPtr == NULL) {

              LOGE("Null data returned in data callback");

              if (c != NULL) {

                  c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);

                  c->dataCallback(msgType, NULL);

              }

              return;

          }

             CAMERA_MSG_SHUTTER

       

          switch (msgType) {

              case CAMERA_MSG_PREVIEW_FRAME:

                  client->handlePreviewData(dataPtr);//處理預(yù)覽數(shù)據(jù)函數(shù)

                  break;

              case CAMERA_MSG_POSTVIEW_FRAME:

                  client->handlePostview(dataPtr);

                  break;

              case CAMERA_MSG_RAW_IMAGE: //處理未壓縮照片函數(shù)

                  client->handleRawPicture(dataPtr);

                  break;

              case CAMERA_MSG_COMPRESSED_IMAGE: //處理壓縮處理的照片函數(shù)

                  client->handleCompressedPicture(dataPtr);

                  break;

              default:

                  if (c != NULL) {

                      c->dataCallback(msgType, dataPtr);

                  }

                  break;

          }

       

      #if DEBUG_CLIENT_REFERENCES

          if (client->getStrongCount() == 1) {

              LOGE("++++++++++++++++ (DATA CALLBACK) THIS WILL CAUSE A LOCKUP!");

              client->printRefs();

          }

      #endif

      }

       

      Linux中使用V4L2最為攝像頭驅(qū)動,V4L2在用戶空間通過各種ioctl調(diào)用進(jìn)行控制,并且可以使用mmap進(jìn)行內(nèi)存映射

       android <wbr>camera框架分析與移植

       

      ioctl函數(shù)命令參數(shù)如下:

       .vidioc_querycap  = vidioc_querycap,  //查詢驅(qū)動功能 
       .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,  //獲取當(dāng)前驅(qū)動支持的視頻格式 
       .vidioc_g_fmt_vid_cap  = vidioc_g_fmt_vid_cap,  //讀取當(dāng)前驅(qū)動的頻捕獲格式 
       .vidioc_s_fmt_vid_cap  = vidioc_s_fmt_vid_cap,   //設(shè)置當(dāng)前驅(qū)動的頻捕獲格式 
       .vidioc_try_fmt_vid_cap  = vidioc_try_fmt_vid_cap,  //驗(yàn)證當(dāng)前驅(qū)動的顯示格式 
       .vidioc_reqbufs   = vidioc_reqbufs,   //分配內(nèi)存 
       .vidioc_querybuf  = vidioc_querybuf,  //把VIDIOC_REQBUFS中分配的數(shù)據(jù)緩存轉(zhuǎn)換成物理地址 
       .vidioc_qbuf   = vidioc_qbuf,  //把數(shù)據(jù)從緩存中讀取出來 
       .vidioc_dqbuf   = vidioc_dqbuf,   //把數(shù)據(jù)放回緩存隊(duì)列 
       .vidioc_streamon  = vidioc_streamon,  //開始視頻顯示函數(shù) 
       .vidioc_streamoff  = vidioc_streamoff,   //結(jié)束視頻顯示函數(shù) 

       .vidioc_cropcap   = vidioc_cropcap,   //查詢驅(qū)動的修剪能力 
       .vidioc_g_crop   = vidioc_g_crop,     //讀取視頻信號的矩形邊框
       .vidioc_s_crop   = vidioc_s_crop,     //設(shè)置視頻信號的矩形邊框  .vidioc_querystd  = vidioc_querystd,   //檢查當(dāng)前視頻設(shè)備支持的標(biāo)準(zhǔn),例如PAL或NTSC。 
       .vidioc_default   = vidioc_default,

       

       android <wbr>camera框架分析與移植

       

      HAL首先:初始化的時候進(jìn)行camera基礎(chǔ)參數(shù)的設(shè)置,然后調(diào)用mmap系統(tǒng)調(diào)用將camera驅(qū)動層的數(shù)據(jù)隊(duì)列映射到用戶空間,

      其次:當(dāng)預(yù)覽方法被調(diào)用的時候啟動預(yù)覽線程,循環(huán)的檢測隊(duì)列中是否有幀數(shù)據(jù),如果幀數(shù)據(jù)存在,讀取幀數(shù)據(jù),由于讀取的數(shù)據(jù)為YUV格式的數(shù)據(jù),所有要將YUV數(shù)據(jù)轉(zhuǎn)換成RGB的送給顯示框架顯示,也可以將轉(zhuǎn)換過的數(shù)據(jù)送給視頻編碼模塊,編碼成功后儲存變成錄像的功能,

      最后:當(dāng)用戶使用拍照的功能的時候,拍照線程被調(diào)用(非循環(huán)),檢測隊(duì)列中的幀數(shù)據(jù),將幀數(shù)據(jù)從隊(duì)列中取出,拍照的數(shù)據(jù)一定需要傳到JAVA層,所有可以將數(shù)據(jù)轉(zhuǎn)換成JPEG格式再上傳,也可以轉(zhuǎn)換成RGB的數(shù)據(jù)上傳給java層

      所有上傳的數(shù)據(jù)處理都要經(jīng)過dataCallback,除非實(shí)現(xiàn)了overlay

       

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多