在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);