ImageReader在Android9增加HardwareBuffer開放了GL鏈路

  1. 如何解決視頻or相機處理。幀失敗和幀渲染 同步問題的呢?TOOD 。 hardwarebuffer是28 android 9開放出來的。 ImagerReader

    1. 優(yōu)化。先繪制到小的buffer上FBO,走glreadpixel讀取yuv數(shù)據(jù)。先計算成yuv數(shù)據(jù)。幀同步。可以是多線程的。在渲染線程。thread mudex
    2. imagereader
      1. 生產(chǎn)方必須走surface流程,消費方只有surfacetexture可選。surfacetexture又必須在gl線程中消費,沒有拿裸rawbuffer的API.
      2. 或者生產(chǎn)方繪制到buffer上。buffer來源可以是 bitmap、hardwarebuffer、surface。消費方有 imageview、uithreadedrender、myGLThread、mediaRecord.
        1. 如果走surface,消費方一定拿不到buffer raw數(shù)據(jù)的。只能回讀出來。通過glReadPixel 或者 FBO寫到Hardwarebuffer上。
        2. HardwareBuffer是個好東西,既可以 作為消費buffer 又可以 作為生產(chǎn)buffer。被封裝成EGLImage或者直接lock出數(shù)據(jù)指針。并且可以是rgba也可以是yuv
      3. imagerreader的出現(xiàn),打破了拿不到surface消費方拿不到 rawbuffer的局限。
        1. 消費方是 同步模式(可背壓) 、 同步+丟棄 、 異步。
        2. controlledByApp 消費方是ture。生產(chǎn)方也是true,觸發(fā)了生產(chǎn)方走的丟棄模式。如果生產(chǎn)方不想走丟棄模式,則可以設置timeout。
        3. queue中至少2個buffer。
        4. 這是SurfaceFlinger,通過surfaceflinger出去的surface,ControlledByApp被永遠設置為false,永遠走背壓模式。有UI、surfaceview。非surfaceflinger默認都是true 比如mediacodec。
          sp<Surface> SurfaceControl::generateSurfaceLocked() const
          {
          // This surface is always consumed by SurfaceFlinger, so the
          // producerControlledByApp value doesn't matter; using false.
          mSurfaceData = new Surface(mGraphicBufferProducer, false);

    return mSurfaceData;
    }

    4. surface的消費方??梢允?ImageReader、SurfaceTexture。
    5. surface、HardwareBuffer、ANativeWindow、PhoneWindow
       1.Graphicbuffer(HardwareBuffer) -》IGraphicBufferProducer-》Surface-》 ANativeWindow
    6. Camera-》ImageReader-》并行
       1. 包裝為EGLImage 借助紋理上屏。void EGLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) { glEGLImageTargetTexture2DOES(texTarget,static_cast<GLeglImageOES>(mEglImage));}
       2. 讀取YUV走NN -》 獲取NN結果變幻矩陣。
       3. 綜合繪制。下一幀的更新可以采用,消費優(yōu)先的原則。生產(chǎn)觸發(fā)還是消費觸發(fā)。兩種。消費觸發(fā)就是,生產(chǎn)只打標,消費在glloop中判斷標記,。image的close什么時候執(zhí)行呢?需要GPU繪制結束后,要用eglsyncfence機制判斷
       4. 把surfacetextue的 updateImageTexture的過程 開放給 開發(fā)者控制。
       5. 并image中的內容是可讀取出來的。
    

mGraphicBuffer 轉為 EglImage
void EGLConsumer::onAcquireBufferLocked(BufferItem* item, SurfaceTexture& st) {
// If item->mGraphicBuffer is not null, this buffer has not been acquired
// before, so any prior EglImage created is using a stale buffer. This
// replaces any old EglImage with a new one (using the new buffer).
int slot = item->mSlot;
if (item->mGraphicBuffer != nullptr || mEglSlots[slot].mEglImage.get() == nullptr) {
mEglSlots[slot].mEglImage = new EglImage(st.mSlots[slot].mGraphicBuffer);
}
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容