1. 程式人生 > >Android Camera資料流分析全程記錄(overlay方式二)

Android Camera資料流分析全程記錄(overlay方式二)

Android Camera資料流分析全程記錄(overlay方式)
這篇文章接著上一篇文章繼續:http://blog.chinaunix.net/uid-26765074-id-3568436.html
上一篇文章overlay這個過程已經走了一遍,但是根本是這個流程還沒有走完,由上一篇文章知道,最後呼叫了postFrame方法,postFrame這個方法都實現了什麼樣的功能呢???他是怎樣是的從driver獲得的資料最終顯示成影象的呢??
這個問題我一直在尋求答案,不過很悲催啊??這個postFrame方法我始終沒有理解清楚,這裡有多少說多少自己的看法,希望有大神能指點指點
這裡就從postFrame入手了:

  1. status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::DisplayFrame &dispFrame)
  2. {
  3.     status_t ret = NO_ERROR;
  4.     uint32_t actualFramesWithDisplay = 0;
  5.     android_native_buffer_t *buffer = NULL;
  6.     GraphicBufferMapper &mapper = GraphicBufferMapper:
    :get();
  7.     int i;
  8.     ///@todo Do cropping based on the stabilized frame coordinates
  9.     ///@todo Insert logic to drop frames here based on refresh rate of
  10.     ///display or rendering rate whichever is lower
  11.     ///Queue the buffer to overlay
  12.     if ( NULL == mANativeWindow ) {
  13.         return NO_INIT;

  14.     }
  15.     if (!mBuffers || !dispFrame.mBuffer) {
  16.         CAMHAL_LOGEA("NULL sent to PostFrame");
  17.         return BAD_VALUE;
  18.     }
  19.     for ( i = 0; i < mBufferCount; i++ )
  20.         {
  21.         if ( dispFrame.mBuffer == &mBuffers[i] )
  22.             {
  23.             break;
  24.         }
  25.     }
  26.     mFramesType.add( (int)mBuffers[i].opaque ,dispFrame.mType );
  27.     if ( mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_STARTED &&
  28.                 (!mPaused || CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType) &&
  29.                 !mSuspend)
  30.     {
  31.         Mutex::Autolock lock(mLock);
  32.         uint32_t xOff = (dispFrame.mOffset% PAGE_SIZE);
  33.         uint32_t yOff = (dispFrame.mOffset / PAGE_SIZE);
  34.         // Set crop only if current x and y offsets do not match with frame offsets
  35.         if((mXOff!=xOff) || (mYOff!=yOff))
  36.         {
  37.             CAMHAL_LOGDB("Offset %d xOff = %d, yOff = %d", dispFrame.mOffset, xOff, yOff);
  38.             uint8_t bytesPerPixel;
  39.             ///Calculate bytes per pixel based on the pixel format
  40.             if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
  41.                 {
  42.                 bytesPerPixel = 2;
  43.                 }
  44.             else if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
  45.                 {
  46.                 bytesPerPixel = 2;
  47.                 }
  48.             else if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0)
  49.                 {
  50.                 bytesPerPixel = 1;
  51.                 }
  52.             else
  53.                 {
  54.                 bytesPerPixel = 1;
  55.             }
  56.             CAMHAL_LOGVB(" crop.left = %d crop.top = %d crop.right = %d crop.bottom = %d",
  57.                           xOff/bytesPerPixel, yOff , (xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight);
  58.             // We'll ignore any errors here, if the surface is
  59.             // already invalid, we'll know soon enough.
  60.             mANativeWindow->set_crop(mANativeWindow, xOff/bytesPerPixel, yOff,
  61.                                      (xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight);
  62.             ///Update the current x and y offsets
  63.             mXOff = xOff;
  64.             mYOff = yOff;
  65.         }
  66.         //這裡說說自己對以上程式碼的理解,上面通過傳入的displayFrame型別變數check,傳入的配置是否與系統此時實際顯示屬性一致,不一致,則從新進行裁剪,配置顯示大小,位置等
  67.         {
  68.             buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
  69.             // unlock buffer before sending to display
  70.             mapper.unlock(*handle);
  71.             ret = mANativeWindow->enqueue_buffer(mANativeWindow, handle);//這裡將buffer入棧,下面會分析道這個函式的由來
  72.         }
  73.         if ( NO_ERROR != ret ) {
  74.             CAMHAL_LOGE("Surface::queueBuffer returned error %d", ret);
  75.         }
  76.         mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) dispFrame.mBuffer->opaque);
  77.         // HWComposer has not minimum buffer requirement. We should be able to dequeue
  78.         // the buffer immediately
  79.         TIUTILS::Message msg;
  80.         mDisplayQ.put(&msg);
  81. #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
  82.         if ( mMeasureStandby )
  83.             {
  84.             CameraHal::PPM("Standby to first shot: Sensor Change completed - ", &mStandbyToShot);
  85.             mMeasureStandby = false;
  86.             }
  87.         else if (CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType)
  88.             {
  89.             CameraHal::PPM("Shot to snapshot: ", &mStartCapture);
  90.             mShotToShot = true;
  91.             }
  92.         else if ( mShotToShot )
  93.             {
  94.             CameraHal::PPM("Shot to shot: ", &mStartCapture);
  95.             mShotToShot = false;
  96.         }
  97. #endif
  98.     }
  99.     else
  100.     {
  101.         Mutex::Autolock lock(mLock);
  102.         buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
  103.         // unlock buffer before giving it up
  104.         mapper.unlock(*handle);
  105.         // cancel buffer and dequeue another one
  106.         ret = mANativeWindow->cancel_buffer(mANativeWindow, handle);
  107.         if ( NO_ERROR != ret ) {
  108.             CAMHAL_LOGE("Surface::cancelBuffer returned error %d", ret);
  109.         }
  110.         mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) dispFrame.mBuffer->opaque);
  111.         TIUTILS::Message msg;
  112.         mDisplayQ.put(&msg);
  113.         ret = NO_ERROR;
  114.     }
  115.     return ret;
  116. }
我們還是著重分析一下這個方法吧:mANativeWindow->enqueue_buffer(mANativeWindow, handle)
首先要找的mANativewindow這個變數型別的定義,找了好久才找到的,悲催:system\core\include\system\Window.h
  1. struct ANativeWindow
  2. {
  3. #ifdef __cplusplus
  4.     ANativeWindow()
  5.         : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
  6.     {
  7.         common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
  8.         common.version = sizeof(ANativeWindow);
  9.         memset(common.reserved, 0, sizeof(common.reserved));
  10.     }
  11.     /* Implement the methods that sp<ANativeWindow> expects so that it
  12.        can be used to automatically refcount ANativeWindow's. */
  13.     void incStrong(

    相關推薦

    Android Camera資料分析全程記錄overlay方式

    Android Camera資料流分析全程記錄(overlay方式) 這篇文章接著上一篇文章繼續:http://blog.chinaunix.net/uid-26765074-id-3568436.html 上一篇文章overlay這個過程已經走了一遍,但是根

    Android4.4 Camera 資料分析

    開門見山: 這裡給出rk 在cameraHAL層的camera資料結構: typedef struct FramInfo { int phy_addr; int vir_addr; int frame_width; int f

    操作資料表中的記錄增刪改查

    插入資料: INTO關鍵字可以省略,若沒有指明欄位,VALUES內一定要匹配所有值,哪怕是預設自增的id欄位 預設的自增id欄位可以寫為NULL,也可以寫成DEFAULT,數字欄位可

    RocketMQ 原始碼分析 訊息儲存預備知識轉載+整理

    前言 在RMQ中為了提高commitlog檔案的讀寫效率,而採用了一個叫做記憶體對映的技術。按照我的理解,記憶體對映在處理大檔案上有非常大的效能提升,所以這篇來記錄一下我對記憶體對映的理解。 使用者態和核心態 我們都知道作業系統分為使用者態和核心態,核心態表示當前為核心程式

    實驗吧CTF刷題記錄web篇

    8.上傳繞過 直接上傳.php會被攔截。嘗試上傳圖片馬,能上傳但不符合題目要求。 嘗試bp抓包改字尾名無果,並非在客戶端javascript驗證。 嘗試截斷路徑繞過,上傳1.jpg檔案,bp抓包,路徑upload後新增1.php空格,將hex中空格20改為00,forw

    實現view跟著手指滑動的效果實現方式

    方式二的這個方法相當於系統提供的一個對左右、上下移動的API的封裝。當計算出偏移量後,只需要使用如下程式碼就可以完成view的重新佈局,效果於使用layout方法一樣,程式碼如下: //同時對left和right進行偏移 offsetLeftAndRight(offset

    androidcamera資料分析

    首先從上層講解下來Packages/apps/camera/src/com/android/camera/camera.javaprivate void capture() {            mCaptureOnlyData = null;            // See android.hard

    靜態分析資料分析與 SSA 入門

    什麼是靜態單賦值 SSA SSA 是 static single assignment 的縮寫,也就是靜態單賦值形式。顧名思義,就是每個變數只有唯一的賦值。 以下圖為例,左圖是原始程式碼,裡面有分支, y 變數在不同路徑中有不同賦值,最後列印 y 的值。右圖是等價的 SS

    Android Audio 系統框架資料分析

        ----------前言      今天是感恩節,突然意識到2014年又接近尾聲了,歲月匆匆,白駒過隙,恍然間覺得,時間在鍵盤敲打的節奏裡一去不復返了; 在這似水流年裡,每天忙於工作,一年下來,自己都忙了些什麼,不禁暗自喟嘆,時間都去哪兒了;為了給時間貼個標籤,開始

    android sensor 框架分析---sensor資料分析

    5,sensor資料流分析 前面幾章做了很多準備和鋪墊,這章終於可以分析sensor資料的傳輸流程了。主要步驟如下, 1,服務端通過HAL從驅動檔案節點中獲取sensor資料。 2,服務端通過管道傳送資料。 3,客戶端通過管道讀取資料。 4,客戶端吐出資料。 5.1服務端獲

    基於Hi3559AV100 RFCN實現細節解析-2RFCN資料分析

      下面隨筆系列將對Hi3559AV100 RFCN實現細節進行解析,整個過程涉及到VI、VDEC、VPSS、VGS、VO、NNIE,其中涉及的內容,大家可以參考之前我寫的部落格: Hi3559AV100的VI細節處理說明: https://www.cnblogs.com/iFrank/p/14374658.

    Hi3559AV100 NNIE開發6RFCN中NNIE實現關鍵執行緒函式->SAMPLE_SVP_NNIE_Rfcn_ViToVo()進行資料分析

      前面隨筆給出了NNIE開發的基本知識,下面幾篇隨筆將著重於Mobilefacenet NNIE開發,實現mobilefacenet.wk的chip版本,並在Hi3559AV100上實現mobilefacenet網路功能,外接USB攝像頭通過MPP平臺輸出至VO HDMI顯示結果。下文是Hi3559AV10

    Java/Android 獲取資料夾的檔案列表file.listFiles()並按名稱排序,中文優先

    排序規則 因為是中國人,習慣性看中文資料夾放前面比較順眼,所以在別人部落格(https://blog.csdn.net/da_caoyuan/article/details/56664673)的基礎上,加上了自己的排序規則。 預設排序規則是按照ASCII碼錶排序(http://asci

    FortiGate資料分析 debug flow

    1.工具說明   在防火牆部署中,經常會遇到防火牆接收到了資料包,但並未進行轉發。可以通過diagnose debug flow 命令來對資料包的處理過程進行跟蹤,可以清晰檢視資料包再各個功能模組內的處理過程,判斷出資料包如何被轉發或者丟棄。 2.命令介紹   diagnose debug enable

    伺服器部署全程記錄centos6.5 170217、nginx 安裝時候報錯:make: *** No rule to make target `build', needed by `default'. Stop. centos7 cannot find a valid base

    1.安裝nginx 上傳安裝包:put E:\yz_index\installPackage\nginx-1.14.0.tar.gz 解壓:tar zxvf nginx-1.14.0.tar.gz 切換:cd nginx-1.14.0 準備編譯:./configure 編譯:ma

    Android進階記錄寫給自己

    2018年已經過了大半,在目前較為空閒的時間,對著大半年的工作做個總結 近況 目標 期望 近況 這一年,團隊的主專案都是iOS專案,雖然也算入了門,參與並完成開發工作,但是僅僅是完成初級工作,而且因為自

    ELK實時日誌分析平臺環境部署--完整記錄ElasticSearch+Logstash+Kibana

    在日常運維工作中,對於系統和業務日誌的處理尤為重要。今天,在這裡分享一下自己部署的ELK(+Redis)-開源實時日誌分析平臺的記錄過程(僅依據本人的實際操作為例說明,如有誤述,敬請指出)~================概念介紹================日誌主要包括系統日誌、應用程式日誌和安全日誌。系

    資料圖詳解DFD

    一、概念 它是將提供給使用者的業務流程圖(“物理模型”)進行功能建模,轉化成開發人員能夠理解的一系列“邏輯模型”圖,即以圖形化的方法描繪資料在系統中的流動和處理的過程,這些圖都應該用規範的DFD描述。 二、原理 DFD設計過程就是將資料和處理進行逐層分解就形成了若干層次的D

    linux_sound_alsa_ALSA體系SOC子系統中資料分析

    前言:     linux中,無論是oss還是alsa體系,錄音和放音的資料流必須分析清楚。先分析alsa驅動層,然後關聯到alsa庫層和應用層。 連結分析:     core/pcm_native.c檔案中.mmap = snd_pcm_mmap呼叫snd_pcm_mma

    (轉)資料圖詳解DFD

    一、概念 它是將提供給使用者的業務流程圖(“物理模型”)進行功能建模,轉化成開發人員能夠理解的一系列“邏輯模型”圖,即以圖形化的方法描繪資料在系統中的流動和處理的過程,這些圖都應該用規範的DFD描述。 二、原理 DFD設計過程就是將資料和處理進行逐層分解就形成了若干