CameraService是如何將camera3_stream_buffer_t類型buffer轉換爲ANativeWindowBuffer_t類型的

在CameraService中將camera3_stream_buffer轉換爲ANativeWindowBuffer的方法是:

//frameworks\av\services\camera\libcameraservice\device3\Camera3OutputStream.cpp
status_t Camera3OutputStream::returnBufferCheckedLocked(
            const camera3_stream_buffer &buffer,
            nsecs_t timestamp,
            bool output,
            /*out*/
            sp<Fence> *releaseFenceOut) {
    ....
#ifndef container_of
#define container_of(ptr, type, member) \
    (type *)((char*)(ptr) - offsetof(type, member))
#endif
    //自測offsetof(ANativeWindowBuffer,handle)=60
    //那指針(char*)buffer.buffer-60爲什麼就是ANativeWindowBuffer??
    ANativeWindowBuffer *anwBuffer = container_of(buffer.buffer, ANativeWindowBuffer, handle);
    ...
}

帶着上述疑問,研究了下源碼

其實camera3_stream_buffer_t和ANativeWindowBuffer_t定義完全不同,
camera3_stream_buffer 和ANativeWindowBuffer的類型定義如下:

//hardware\libhardware\include\hardware\camera3.h
typedef struct camera3_stream_buffer {
    /**
     * The handle of the stream this buffer is associated with
     */
    camera3_stream_t *stream;

    /**
     * The native handle to the gralloc buffer
     */
    //typedef const native_handle_t* buffer_handle_t;
    //native_handle_t** buffer;
    buffer_handle_t *buffer;
    int acquire_fence;
    int release_fence;
}

//frameworks/native/libs/nativebase/include/nativebase/nativebase.h
typedef struct ANativeWindowBuffer
{
    ...
    struct android_native_base_t common;
    int width;
    int height;
    int stride;
    int format;
    int usage_deprecated;
    uintptr_t layerCount;
    void* reserved[1];

    const native_handle_t* handle;
    uint64_t usage;
}

從他們的定義看,ANativeWindowBuffer的handle類型是native_handle_t*
而camera3_stream_buffer的buffer的類型爲buffer_handle_t ,即native_handle_t** ,他們的類型並不相同。

之所以CameraService可以通過container_of來獲取ANativeWindowBuffer是因爲
在封裝camera3_stream_buffer_t型buffer時,傳遞的是ANativeWindowBuffer結構體成員handle的地址
handoutBufferLocked(*buffer, &(anb->handle), /acquireFence/fenceFd,
/releaseFence/-1, CAMERA3_BUFFER_STATUS_OK, /output/true);
而並不是直接傳遞的anb->handle指向的地址。

代碼如下:

//frameworks\av\services\camera\libcameraservice\device3\Camera3OutputStream.cpp
status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer,
        const std::vector<size_t>&) {

    //graphics buffer類型是GraphicBuffer
    //ANativeWindowBuffer是GraphicBuffer的父類
    ANativeWindowBuffer* anb;
    int fenceFd = -1;
    status_t res;
    //申請graphics buffer及對應的fence並保存到anb和fenceFd
    res = currentConsumer->dequeueBuffer(currentConsumer.get(), anb, fenceFd);
    ....
    //handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
                        ///*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
    buffer.stream = this;
    buffer.buffer = &(anb->handle);
    buffer.acquire_fence = fenceFd;
    buffer.release_fence = -1;
    buffer.status = CAMERA3_BUFFER_STATUS_OK;
    return OK;
}

通過上述代碼看,camera3_stream_buffer中buffer.buffer保存的是anb->handle成員的地址,而並不是anb->handle。
地址anb和和地址&(anb->handle)之間的關係是:
anb-&(anb->handle)=定值,(這個就是就是offsetof(ANativeWindowBuffer, native_handle_t),自測爲60)
所有才有:
ANativeWindowBuffer *anwBuffer = container_of(buffer.buffer, ANativeWindowBuffer, handle);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章