Android Overlay學習

來源:互聯網
上載者:User

前文僅瞭解了overlay HAL的架構,下面繼續看看系統層是如何調用Overlay模組。

1、 測試代碼

frameworks/base/libs/surfaceflinger/tests/overlays/overlays.cpp提供了一個簡單的overlay調用流程,可惜這個測試程式有錯誤,
   
在sp<Surface> surface = client->createSurface(getpid(), 0, 320,
240, PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);
這句話編譯不過去,錯誤在Surface的申請,和overlay無關。

我們來看看這段代碼:

int main(int argc, char** argv)
{
    // set up the thread-pool 建立線程池
    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    // create a client to surfaceflinger 建立一個SurfaceFlinger client
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
   
    // create pushbuffer surface 建立一個surface,最後那個參數是類型?
    sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240,
            PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);

    // get to the isurface 取得isurface介面
    sp<ISurface> isurface = Test::getISurface(surface);
    printf("isurface = %p/n", isurface.get());
   
    // now request an overlay 建立一個overlay
    sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
    sp<Overlay> overlay = new Overlay(ref);
   
    /*
     * here we can use the overlay API 建立好overlay後,即可使用overlay的API,這些都對應到overlay HAL的具體實現
     */
   
    overlay_buffer_t buffer;
    overlay->dequeueBuffer(&buffer);
    printf("buffer = %p/n", buffer);
   
    void* address = overlay->getBufferAddress(buffer);
    printf("address = %p/n", address);

    overlay->queueBuffer(buffer);//最重要的操作就是通過queueBuffer將buffer列隊

    return 0;
}

2、Android系統建立中Overlay(調用createOverlay)

1)網路攝影機相關 CameraService.cpp (frameworks/base/camera/libcameraservice)
setPreviewDisplay()、startPreviewMode()
|
setOverlay()
|
creatOverlay()

2)介面相關 ISurface.cpp (frameworks/base/libs/ui)
LayerBaseClient::Surface::onTransact() <--該函數位於LayerBase.cpp,好像是用於ibind進程通訊的函數
|
BnSurface::onTransact() //有5種方式,只有確定有overlay硬體支援時才會調用case CREATE_OVERLAY
|
... ...
switch(code) {
        case REQUEST_BUFFER: {
            CHECK_INTERFACE(ISurface, data, reply);
            int bufferIdx = data.readInt32();
            int usage = data.readInt32();
            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage));
            return GraphicBuffer::writeToParcel(reply, buffer.get());
        }
        case REGISTER_BUFFERS: {
            CHECK_INTERFACE(ISurface, data, reply);
            BufferHeap buffer;
            buffer.w = data.readInt32();
            buffer.h = data.readInt32();
            buffer.hor_stride = data.readInt32();
            buffer.ver_stride= data.readInt32();
            buffer.format = data.readInt32();
            buffer.transform = data.readInt32();
            buffer.flags = data.readInt32();
            buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
            status_t err = registerBuffers(buffer);
            reply->writeInt32(err);
            return NO_ERROR;
        } break;
        case UNREGISTER_BUFFERS: {
            CHECK_INTERFACE(ISurface, data, reply);
            unregisterBuffers();
            return NO_ERROR;
        } break;
        case POST_BUFFER: {
            CHECK_INTERFACE(ISurface, data, reply);
            ssize_t offset = data.readInt32();
            postBuffer(offset);
            return NO_ERROR;
        } break;
        case CREATE_OVERLAY: {
            CHECK_INTERFACE(ISurface, data, reply);
            int w = data.readInt32();
            int h = data.readInt32();
            int f = data.readInt32();
            sp<OverlayRef> o = createOverlay(w, h, f);
            return OverlayRef::writeToParcel(reply, o);
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
... ...

3)LayerBuffer.cpp (frameworks/base/libs/surfaceflinger) 這兒其實是createOverlay的實現
sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t format)
|
sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
|
sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f); //通過OverlaySource來建立overlay

LayerBuffer::OverlaySource::OverlaySource()//該函數調用了Overlay HAL的API createOverlay
{
    overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();//get HAL
    overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);//HAL API

    // enable dithering...
    overlay_dev->setParameter(overlay_dev, overlay, OVERLAY_DITHER, OVERLAY_ENABLE);
//設定參數,初始化OverlayRef類,OverlayRef的建構函式在Overlay.cpp中
    mOverlay = overlay;
    mWidth = overlay->w;
    mHeight = overlay->h;
    mFormat = overlay->format;
    mWidthStride = overlay->w_stride;
    mHeightStride = overlay->h_stride;
    mInitialized = false;
... ...
    *overlayRef = new OverlayRef(mOverlayHandle, channel,mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
}

3、Overlay HAL模組管理

Overlay.cpp (frameworks/base/libs/ui)負責管理overlay HAL,並對HAL的API進行封裝

1)開啟Overlay HAL模組
Overlay::Overlay(const sp<OverlayRef>& overlayRef)
    : mOverlayRef(overlayRef), mOverlayData(0), mStatus(NO_INIT)
{
    mOverlayData = NULL;
    hw_module_t const* module;
    if (overlayRef != 0) {
        if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
            if (overlay_data_open(module, &mOverlayData) == NO_ERROR) {
                mStatus = mOverlayData->initialize(mOverlayData,
                        overlayRef->mOverlayHandle);
            }
        }
    }
}

2)Overlay HAL的初始化
參考上一段,overlayRef = new OverlayRef(mOverlayHandle, channel,mWidth, mHeight, mFormat, mWidthStride, mHeightStride);

建構函式位於Overlay.cpp
OverlayRef::OverlayRef(overlay_handle_t handle, const sp<IOverlay>& channel,
         uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
    : mOverlayHandle(handle), mOverlayChannel(channel),
    mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs),
    mOwnHandle(false)
{
}

3)封裝了很多的API,但是沒有查到那兒有調用,看來還需要大改架構才能真正將overlay利用起來
比如TI自己寫的opencore函數中到時有用到,主要負責視頻輸出。
Android_surface_output_omap34xx.cpp (hardware/ti/omap3/libopencorehw)

 

4、總結

Overlay的輸出對象有兩種,一種是視頻(主要是YUV格式,調用系統的V4L2),另外一個是ISurface的一些映像資料(RGB格式,直接寫framebuffer)
從代碼實現角度看,目前Android系統預設並沒有使用Overlay功能,雖然提供了Skeleton的Overlay HAL,並對其進行封裝,但是上層幾乎沒有調用到封裝的API。
如果要用好Overlay HAL,需要大量修改上層架構,這對視屏播放可能比較重要,可參考TI的Android_surface_output_omap34xx.cpp。
此外Surface實現的Overlay功能和Copybit的功能有部分重複,從TI的代碼看主要是實現V4L2的Overlay功能。

 

http://hi.baidu.com/aokikyon/blog/item/6e4e622c4fdaaae18a1399d4.html


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.