深入理解相機體系 五 相機硬件抽象層 HAL

和你一起終身學習,這里是程序員Android
經(jīng)典好文推薦,通過閱讀本文,您將收獲以下知識點:
一、概覽
二、Camera HIDL 接口
三 、Camera Provider 主程序
四、Camera HAL3 接口
相機硬件抽象層
一、概覽
始于谷歌的Treble開源項目,基于接口與實現(xiàn)的分離的設計原則,谷歌加入了Camera Provider這一抽象層,該層作為一個獨立進程存在于整個系統(tǒng)中,并且通過HIDL這一自定義語言成功地將Camera Hal Module從Camera Service中解耦出來,承擔起了對Camera HAL的封裝工作,縱觀整個Android系統(tǒng),對于Camera Provider而言,對上是通過HIDL接口負責與Camera Service的跨進程通信,對下通過標準的HAL3接口下發(fā)針對Camera的實際操作,這儼然是一個中央樞紐般的調(diào)配中心的角色,而事實上正是如此,由此看來,對Camera Provider的梳理變得尤為重要,接下來就以我個人理解出發(fā)來簡單介紹下Camera Provider。
Camera Provider通過提供標準的HIDL接口給Camera Service進行調(diào)用,保持與Service的正常通信,其中谷歌將HIDL接口的定義直接暴露給平臺廠商進行自定義實現(xiàn),其中為了極大地減輕并降低開發(fā)者的工作量和開發(fā)難度,谷歌很好地封裝了其跨進程實現(xiàn)細節(jié),同樣地,Camera Provider通過標準的HAL3接口,向下控制著具體的Camera HAL Module,而這個接口依然交由平臺廠商負責去實現(xiàn),而進程內(nèi)部則通過簡單的函數(shù)調(diào)用,將HIDL接口與HAL3接口完美的銜接起來,由此構成了Provider整體架構。

程序員Android轉于網(wǎng)絡圖片
由圖中可以看出Camera Provider進程由兩部分組成,一是運行在系統(tǒng)中的主程序通過提供了標準的HIDL接口保持了與Camera Service的跨進程通訊,二是為了進一步擴展其功能,通過dlopen方式加載了一系列So庫,而其中就包括了實現(xiàn)了Camera HAL3接口的So庫,而HAL3接口主要定義了主要用于實現(xiàn)圖像控制的功能,其實現(xiàn)主要交由平臺廠商或者開發(fā)者來完成,所以Camera HAL3 So庫的實現(xiàn)各式各樣,在高通平臺上,這里的實現(xiàn)就是我們本文重點需要分析的CamX-CHI框架。
在開始梳理CamX-CHI之前,不防先從上到下,以接口為主線簡單梳理下Camera Provider的各個部分:
二、Camera HIDL 接口
首先需要明確一個概念,就是HIDL是一種自定義語言,其核心是接口的定義,而谷歌為了使開發(fā)者將注意力落在接口的定義上而不是機制的實現(xiàn)上,主動封裝了HIDL機制的實現(xiàn)細節(jié),開發(fā)者只需要通過*.hal文件定義接口,填充接口內(nèi)部實際的實現(xiàn)即可,接下來來看下具體定義的幾個主要接口:

程序員Android轉于網(wǎng)絡圖片
因為HIDL機制本身是跨進程通訊的,所以Camera Service本身通過HIDL接口獲取的對象都會有Bn端和Bp端,分別代表了Binder兩端,接下來為了方便理解,我們都省略掉Bn/Bp說法,直接用具體接口類代表,忽略跨進程兩端的區(qū)別。
ICameraProvider.hal源碼如下:
package android.hardware.camera.provider@2.4;
import ICameraProviderCallback;
import android.hardware.camera.common@1.0::types;
import android.hardware.camera.device@1.0::ICameraDevice;
import android.hardware.camera.device@3.2::ICameraDevice;
interface ICameraProvider {
setCallback(ICameraProviderCallback callback) generates (Status status);
getVendorTags() generates (Status status, vec<VendorTagSection> sections);
getCameraIdList() generates (Status status, vec<string> cameraDeviceNames);
isSetTorchModeSupported() generates (Status status, bool support);
getCameraDeviceInterface_V1_x(string cameraDeviceName) generates (Status status, android.hardware.camera.device@1.0::ICameraDevice device);
getCameraDeviceInterface_V3_x(string cameraDeviceName) generates (Status status, android.hardware.camera.device@3.2::ICameraDevice device);
};
該文件中定義了ICameraProvider接口類,由CameraProvider繼承并實現(xiàn),在Camera Provider啟動的時候被實例化,主要接口如下:
getCameraDeviceInterface_V3_x: 該方法主要用于Camera Service獲取ICameraDevice,通過該對象可以控制Camera 設備的諸如配置數(shù)據(jù)流、下發(fā)request等具體行為。
setCallback:將Camera Service 實現(xiàn)的ICameraProviderCallback傳入Camera Provider,一旦Provider有事件產(chǎn)生時便可以通過該對象通知Camera Service。
ICameraProviderCallback.hal源碼如下:
package android.hardware.camera.provider@2.4;
import android.hardware.camera.common@1.0::types;
interface ICameraProviderCallback {
cameraDeviceStatusChange(string cameraDeviceName, CameraDeviceStatus newStatus);
torchModeStatusChange(string cameraDeviceName, TorchModeStatus newStatus);
};
該文件中定義了ICameraProviderCallback回調(diào)接口類,該接口由Camera Service 中的CameraProviderManager::ProviderInfo繼承并實現(xiàn),在Camera Service 啟動的時候被實例化,通過調(diào)用ICameraProvider::setCallback接口注冊到Camera Provider中,其主要接口如下:
cameraDeviceStatusChange:將Camera 設備狀態(tài)上傳至Camera Service,狀態(tài)由CameraDeviceStatus定義
ICameraDevice.hal源碼如下:
package android.hardware.camera.device@3.2;
import android.hardware.camera.common@1.0::types;
import ICameraDeviceSession;
import ICameraDeviceCallback;
interface ICameraDevice {
getResourceCost() generates (Status status, CameraResourceCost resourceCost);
getCameraCharacteristics() generates (Status status, CameraMetadata cameraCharacteristics);
setTorchMode(TorchMode mode) generates (Status status);
open(ICameraDeviceCallback callback) generates (Status status, ICameraDeviceSession session);
dumpState(handle fd);
};
該文件中定義了ICameraDevice接口類,由CameraDevice::TrampolineDeviceInterface_3_2實現(xiàn),其主要接口如下:
open:用于創(chuàng)建一個Camera設備,并且將Camera Service中繼承ICameraDeviceCallback并實現(xiàn)了相應接口的Camera3Device作為參數(shù)傳入Provider中,供Provider上傳事件或者圖像數(shù)據(jù)。
getCameraCharacteristics:用于獲取Camera設備的屬性。
ICameraDeviceCallback.hal源碼如下:
package android.hardware.camera.device@3.2;
import android.hardware.camera.common@1.0::types;
interface ICameraDeviceCallback {
processCaptureResult(vec<CaptureResult> results);
notify(vec<NotifyMsg> msgs);
};
該文件中定義了ICameraDeviceCallback接口類,由Camera Service中的Camera3Device繼承并實現(xiàn),通過調(diào)用ICameraDevice::open方法注冊到Provider中,其主要接口如下:
processCaptureResult_3_4: 一旦有圖像數(shù)據(jù)產(chǎn)生會通過調(diào)用該方法將數(shù)據(jù)以及meta data上傳至Camera Service。
notify: 通過該方法上傳事件至Camera Service中,比如shutter事件等。
ICameraDeviceSession.hal源碼如下:
package android.hardware.camera.device@3.2;
import android.hardware.camera.common@1.0::types;
interface ICameraDeviceSession {
constructDefaultRequestSettings(RequestTemplate type) generates (Status status, CameraMetadata requestTemplate);
configureStreams(StreamConfiguration requestedConfiguration) generates (Status status, HalStreamConfiguration halConfiguration);
processCaptureRequest(vec<CaptureRequest> requests, vec<BufferCache> cachesToRemove) generates (Status status, uint32_t numRequestProcessed);
getCaptureRequestMetadataQueue() generates (fmq_sync<uint8_t> queue);
getCaptureResultMetadataQueue() generates (fmq_sync<uint8_t> queue);
flush() generates (Status status); close();
};
該文件中定義了ICameraDeviceSession接口類,由CameraDeviceSession::TrampolineSessionInterface_3_2繼承并實現(xiàn),其主要接口如下:
constructDefaultRequestSettings:用于創(chuàng)建默認的Request配置項。
configureStreams_3_5:用于配置數(shù)據(jù)流,其中包括了output buffer/Surface/圖像格式大小等屬性。
processCaptureRequest_3_4:下發(fā)request到Provider中,一個request對應著一次圖像需求。
close: 關閉當前會話。
三 、Camera Provider 主程序
接下來進入到Provider內(nèi)部去看看,整個進程是如何運轉的,以下圖為例進行分析:

程序員Android轉于網(wǎng)絡圖片
在系統(tǒng)初始化的時候,系統(tǒng)會去運行[email protected]_64程序啟動Provider進程,并加入HW Service Manager中接受統(tǒng)一管理,在該過程中實例化了一個LegacyCameraProviderImpl_2_4對象,并在其構造函數(shù)中通過hw_get_module標準方法獲取HAL的camera_module_t結構體,并將其存入CameraModule對象中,之后通過調(diào)用該camera_modult_t結構體的init方法初始化HAL Module,緊接著調(diào)用其get_number_of_camera方法獲取當前HAL支持的Camera數(shù)量,最后通過調(diào)用其set_callbacks方法將LegcyCameraProviderImpl_2_4(LegcyCameraProviderImpl_2_4繼承了camera_modult_callback_t)作為參數(shù)傳入CamX-CHI中,接受來自CamX-CHI中的數(shù)據(jù)以及事件,當這一系列動作完成了之后,Camera Provider進程便一直便存在于系統(tǒng)中,監(jiān)聽著來自Camera Service的調(diào)用。

程序員Android轉于網(wǎng)絡圖片
接下來以上圖為例簡單介紹下Provider中幾個重要流程:
Camera Service通過調(diào)用ICameraProvider的getCameraDeviceInterface_v3_x接口獲取ICameraDevice,在此過程中,Provider會去實例化一個CameraDevice對象,并且將之前存有camera_modult_t結構體的CameraModule對象傳入CameraDevice中,這樣就可以在CameraDevice內(nèi)部通過CameraModule訪問到camera_module_t的相關資源,然后將CameraDevice內(nèi)部類TrampolineDeviceInterface_3_2(該類繼承并實現(xiàn)了ICameraDevice接口)返回給Camera Service。
Camera Service通過之前獲取的ICameraDevice,調(diào)用其open方法來打開Camera設備,接著在Provider中會去調(diào)用CameraDevice對象的open方法,在該方法內(nèi)部會去調(diào)用camera_module_t結構體的open方法,從而獲取到HAL部分的camera3_device_t結構體,緊接著Provider會實例化一個CameraDeviceSession對象,并且將剛才獲取到的camera3_device_t結構體以參數(shù)的方式傳入CameraDeviceSession中,在CameraDeviceSession的構造方法中又會調(diào)用CameraDeviceSession的initialize方法,在該方法內(nèi)部又會去調(diào)用camera3_device_t結構體的ops內(nèi)的initialize方法開始HAL部分的初始化工作,最后CameraDeviceSession對象被作為camera3_callback_ops的實現(xiàn)傳入HAL,接收來自HAL的數(shù)據(jù)或者具體事件,當一切動作都完成后,Provider會將CameraDeviceSession::TrampolineSessionInterface_3_2(該類繼承并實現(xiàn)了ICameraDeviceSession接口)對象通過HIDL回調(diào)的方法返回給Camera Service中。
Camera Service通過調(diào)用ICameraDevcieSession的configureStreams_3_5接口進行數(shù)據(jù)流的配置,在Provider中,最終會通過調(diào)用之前獲取的camera3_device_t結構體內(nèi)ops的configure_streams方法下發(fā)到HAL中進行處理。
Camera Service通過調(diào)用ICameraDevcieSession的processCaptureRequest_3_4接口下發(fā)request請求到Provider中,在Provider中,最終依然會通過調(diào)用獲取的camera3_device_t結構體內(nèi)ops中的process_capture_request方法將此次請求下發(fā)到HAL中進行處理。
從整個流程不難看出,這幾個接口最終對應的是HAL3的接口,并且Provider并沒有經(jīng)過太多復雜的額外的處理。
四、Camera HAL3 接口
HAL硬件抽象層(Hardware Abstraction Layer),是谷歌開發(fā)的用于屏蔽底層硬件抽象出來的一個軟件層, 每一個平臺廠商可以將不開源的代碼封裝在這一層,僅僅提供二進制文件。
該層定義了自己的一套通用標準接口,平臺廠商務必按照以下規(guī)則定義自己的Module:
每一個硬件模塊都通過hw_module_t來描述,具有固定的名字HMI
每一個硬件模塊都必須實現(xiàn)hw_module_t里面的open方法,用于打開硬件設備,并返回對應的操作接口集合
硬件的操作接口集合使用hw_device_t 來描述,并可以通過自定義一個更大的包含hw_device_t的結構體來拓展硬件操作集合
其中代表硬件模塊的是hw_module_t,對應的設備是通過hw_device_t來描述,這兩者的定義如下:
hw_module_t/hw_device_t源碼如下:
typedef struct hw_module_t {
uint32_t tag; //HMI
struct hw_module_methods_t* methods;
} hw_module_t;
typedef struct hw_module_methods_t {
int (*open)(const struct hw_module_t* module, const char* id, struct hw_device_t** device);
} hw_module_methods_t;
typedef struct hw_device_t {
struct hw_module_t* module;
int (*close)(struct hw_device_t* device);
} hw_device_t;
從上面的定義可以看出,主要是通過hw_module_t 代表了模塊,通過其open方法用來打開一個設備,而該設備是用hw_device_t來表示,其中除了用來關閉設備的close方法外,并無其它方法,由此可見谷歌定義的HAL接口,并不能滿足絕大部分HAL模塊的需要,所以谷歌想出了一個比較好的解決方式,那便是將這兩個基本結構嵌入到更大的結構體內(nèi)部,同時在更大的結構內(nèi)部定義了各自模塊特有的方法,用于實現(xiàn)模塊的功能,這樣,一來對上保持了HAL的統(tǒng)一規(guī)范,二來也擴展了模塊的功能。
基于上面的方式,谷歌便針對Camera 提出了HAL3接口,其中主要包括了用于代表一系列操作主體的結構體以及具體操作函數(shù),接下來我們分別進行詳細介紹:
1. 核心結構體解析
HAL3中主要定義了camera_module_t/camera3_device_t/camera3_stream_configuration/camera3_stream以及camera3_stream_buffer幾個主要結構體。
其中camera_module_t以及camera3_device_t代碼定義如下:
typedef struct camera_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
nt (*set_callbacks)(const camera_module_callbacks_t *callbacks);
void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);
int (*open_legacy)(const struct hw_module_t* module, const char* id, uint32_t halVersion, struct hw_device_t** device);
int (*set_torch_mode)(const char* camera_id, bool enabled);
int (*init)();
int (*get_physical_camera_info)(int physical_camera_id, int (*is_stream_combination_supported)(int camera_id,const camera_stream_combination_t *streams);
int (*is_stream_combination_supported)(int camera_id, const camera_stream_combination_t *streams);
void (*notify_device_state_change)(uint64_t deviceState);
} camera_module_t;
typedef struct camera3_device {
hw_device_t common;
camera3_device_ops_t *ops; //拓展接口,Camera HAL3定義的標準接口
void *priv;
} camera3_device_t;
由定義不難發(fā)現(xiàn),camera_module_t包含了hw_module_t,主要用于表示Camera模塊,其中定義了諸如get_number_of_cameras以及set_callbacks等擴展方法,而camera3_device_t包含了hw_device_t,主要用來表示Camera設備,其中定義了camera3_device_ops操作方法集合,用來實現(xiàn)正常獲取圖像數(shù)據(jù)以及控制Camera的功能。
結構體camera3_stream_configuration代碼定義如下:
typedef struct camera3_stream_configuration {
uint32_t num_streams;
camera3_stream_t **streams;
uint32_t operation_mode;
const camera_metadata_t *session_parameters;
} camera3_stream_configuration_t;
該結構體主要用來代表配置的數(shù)據(jù)流列表,內(nèi)部裝有上層需要進行配置的數(shù)據(jù)流的指針,內(nèi)部的定義簡單介紹下:
num_streams: 代表了來自上層的數(shù)據(jù)流的數(shù)量,其中包括了output以及input stream。
streams: 是streams的指針數(shù)組,包括了至少一條output stream以及至多一條input stream。
operation_mode: 當前數(shù)據(jù)流的操作模式,該模式在camera3_stream_configuration_mode_t中被定義,HAL通過這個參數(shù)可以針對streams做不同的設置。
session_parameters: 該參數(shù)可以作為缺省參數(shù),直接設置為NULL即可,CAMERA_DEVICE_API_VERSION_3_5以上的版本才支持。
結構體camera3_stream_t的代碼定義如下:
typedef struct camera3_stream {
int stream_type;
uint32_t width;
uint32_t height;
int format;
uint32_t usage;
uint32_t max_buffers;
void *priv;
android_dataspace_t data_space;
int rotation;
const char* physical_camera_id;
}camera3_stream_t;
該結構體主要用來代表具體的數(shù)據(jù)流實體,在整個的配置過程中,需要在上層進行填充,當下發(fā)到HAL中后,HAL會針對其中的各項屬性進行配置,這里便簡單介紹下其內(nèi)部的各個元素的意義:
stream_type: 表示數(shù)據(jù)流的類型,類型在camera3_stream_type_t中被定義。
width:表示當前數(shù)據(jù)流中的buffer的寬度。
height: 表示當前數(shù)據(jù)流中buffer的高度。
format: 表示當前數(shù)據(jù)流中buffer的格式,該格式是在system/core/include/system/graphics.h中被定義。
usage:表示當前數(shù)據(jù)流的gralloc用法,其用法定義在gralloc.h中。
max_buffers:指定了當前數(shù)據(jù)流中可能支持的最大數(shù)據(jù)buffer數(shù)量。
data_space: 指定了當前數(shù)據(jù)流buffer中存儲的圖像數(shù)據(jù)的顏色空間。
rotation:指定了當前數(shù)據(jù)流的輸出buffer的旋轉角度,其角度的定義在camera3_stream_rotation_t中,該參數(shù)由Camera Service進行設置,必須在HAL中進行設置,該參數(shù)對于input stream并沒有效果。
physical_camera_id:指定了當前數(shù)據(jù)流從屬的物理camera Id。
結構體camera3_stream_buffer_t定義如下:
typedef struct camera3_stream_buffer {
camera3_stream_t *stream;
buffer_handle_t *buffer
int status;
int acquire_fence;
int release_fence;
} camera3_stream_buffer_t;
該結構體主要用來代表具體的buffer對象,其中重要元素如下:
stream: 代表了從屬的數(shù)據(jù)流
buffer:buffer句柄
2. 核心接口函數(shù)解析
HAL3的核心接口都是在camera3_device_ops中被定義,代碼定義如下:
typedef struct camera3_device_ops {
int (*initialize)(const struct camera3_device *, const camera3_callback_ops_t *callback_ops);
int (*configure_streams)(const struct camera3_device *, camera3_stream_configuration_t *stream_list);
int (*register_stream_buffers)(const struct camera3_device *,const camera3_stream_buffer_set_t *buffer_set);
const camera_metadata_t* (*construct_default_request_settings)(const struct camera3_device *, int type);
int (*process_capture_request)(const struct camera3_device *, camera3_capture_request_t *request);
void (*get_metadata_vendor_tag_ops)(const struct camera3_device*, vendor_tag_query_ops_t* ops);
void (*dump)(const struct camera3_device *, int fd);
int (*flush)(const struct camera3_device *);
void (*signal_stream_flush)(const struct camera3_device*, uint32_t num_streams, const camera3_stream_t* const* streams);
int (*is_reconfiguration_required)(const struct camera3_device*, const camera_metadata_t* old_session_params, const camera_metadata_t* new_session_params);
} camera3_device_ops_t;
從代碼中可以看見,該結構體定義了一系列的函數(shù)指針,用來指向平臺廠商實際的實現(xiàn)方法,接下來就其中幾個方法簡單介紹下:
a) initialize
該方法必須在camera_module_t中的open方法之后,其它camera3_device_ops中方法之前被調(diào)用,主要用來將上層實現(xiàn)的回調(diào)方法注冊到HAL中,并且根據(jù)需要在該方法中加入自定義的一些初始化操作,另外,谷歌針對該方法在性能方面也有嚴格的限制,該方法需要在5ms內(nèi)返回,最長不能超過10ms。
b) configure_streams
該方法在完成initialize方法之后,在調(diào)用process_capture_request方法之前被調(diào)用,主要用于重設當前正在運行的Pipeline以及設置新的輸入輸出流,其中它會將stream_list中的新的數(shù)據(jù)流替換之前配置的數(shù)據(jù)流。在調(diào)用該方法之前必須確保沒有新的request下發(fā)并且當前request的動作已經(jīng)完成,否則會引起無法預測的錯誤。一旦HAL調(diào)用了該方法,則必須在內(nèi)部配置好滿足當前數(shù)據(jù)流配置的幀率,確保這個流程的運行的順暢性。
其中包含了兩個參數(shù),分別是camera3_device以及stream_list(camera3_stream_configuration_t ),其中第二個參數(shù)是上層傳入的數(shù)據(jù)流配置列表,該列表中必須包含至少一個output stream,同時至多包含一個input stream。
另外,谷歌針對該方法有著嚴格的性能要求,平臺廠商在實現(xiàn)該方法的時候,需要在500ms內(nèi)返回,最長不能超過1000ms。
c) construct_default_request_settings
該方法主要用于構建一系列默認的Camera Usecase的capture 設置項,通過camera_metadata_t來進行描述,其中返回值是一個camera_metadata_t指針,其指向的內(nèi)存地址是由HAL來進行維護的,同樣地,該方法需要在1ms內(nèi)返回,最長不能超過5ms。
d) process_capture_request
該方法用于下發(fā)單次新的capture request到HAL中, 上層必須保證該方法的調(diào)用都是在一個線程中完成,而且該方法是異步的,同時其結果并不是通過返回值給到上層,而是通過HAL調(diào)用另一個接口process_capture_result()來將結果返回給上層的,在使用的過程中,通過in-flight機制,保證短時間內(nèi)下發(fā)足夠多的request,從而滿足幀率要求。
該方法的性能依然受到谷歌的嚴格要求,規(guī)定其需要在一幀圖像處理完的時長內(nèi)返回,最長不超過4幀圖像處理完成的時長,比如當前預覽幀率是30幀,則該方法的操作耗時最長不能超過120ms,否則便會引起明顯的幀抖動,從而影響用戶體驗。
e) dump
該方法用于打印當前Camera設備的狀態(tài),一般是由上層通過dumpsys工具輸出debug dump信息或者主動抓取bugreport的時候被調(diào)用,該方法必須是非阻塞實現(xiàn),同時需要保證在1ms內(nèi)返回,最長不能超過10ms。
f) flush
當上層需要執(zhí)行新的configure_streams的時候,需要調(diào)用該方法去盡可能快地清除掉當前已經(jīng)在處理中的或者即將處理的任務,為配置數(shù)據(jù)流提供一個相對穩(wěn)定的環(huán)境,其具體工作如下:
所有的還在流轉的request會盡可能快的返回
并未開始進行流轉的request會直接返回,并攜帶錯誤信息
任何可以打斷的硬件操作會立即被停止
任何無法進行打斷的硬件操作會在當前狀態(tài)下進行休眠
flush會在所有的buffer都得以釋放,所有request都成功返回后才真正返回,該方法需要在100ms內(nèi)返回,最長不能超過1000ms。
上面的一系列方法是上層直接對下控制Camera Hal,而一旦Camera Hal產(chǎn)生了數(shù)據(jù)或者事件的時候,可以通過camera3_callback_ops中定義的回調(diào)方法將數(shù)據(jù)或者事件返回至上層,該結構體定義如下:
typedef struct camera3_callback_ops {
void (*process_capture_result)(const struct camera3_callback_ops *, const camera3_capture_result_t *result);
void (*notify)(const struct camera3_callback_ops *, const camera3_notify_msg_t *msg);
camera3_buffer_request_status_t (*request_stream_buffers)(
const struct camera3_callback_ops *,
uint32_t num_buffer_reqs,
const camera3_buffer_request_t *buffer_reqs,
/*out*/uint32_t *num_returned_buf_reqs,
/*out*/camera3_stream_buffer_ret_t *returned_buf_reqs);
void (*return_stream_buffers)( const struct camera3_callback_ops *, uint32_t num_buffers, const camera3_stream_buffer_t* const* buffers);
} camera3_callback_ops_t;
其中常用的回調(diào)方法主要有兩個:用于返回數(shù)據(jù)的process_capture_result以及用于返回事件的notify,接下來分別介紹下:
a) process_capture_result
該方法用于返回HAL部分產(chǎn)生的metadata和image buffers,它與request是多對一的關系,同一個request,可能會對應到多個result,比如可以通過調(diào)用一次該方法用于返回metadata以及低分辨率的圖像數(shù)據(jù),再調(diào)用一次該方法用于返回jpeg格式的拍照數(shù)據(jù),而這兩次調(diào)用時對應于同一個process_capture_request動作。
同一個Request的Metadata以及Image Buffers的先后順序無關緊要,但是同一個數(shù)據(jù)流的不同Request之間的Result必須嚴格按照Request的下發(fā)先后順序進行依次返回的,如若不然,會導致圖像數(shù)據(jù)顯示出現(xiàn)順序錯亂的情況。
該方法是非阻塞的,而且并且必須要在5ms內(nèi)返回。
b) notify
該方法用于異步返回HAL事件到上層,必須非阻塞實現(xiàn),而且要在5ms內(nèi)返回。
谷歌為了將系統(tǒng)框架和平臺廠商的自定義部分相分離,在Android上推出了Treble項目,該項目直接將平臺廠商的實現(xiàn)部分放入vendor分區(qū)中進行管理,進而與system分區(qū)保持隔離,這樣便可以在相互獨立的空間中進行各自的迭代升級,而互不干擾,而在相機框架體系中,便將Camera HAL Module從Camera Service中解耦出來,放入獨立進程Camera Provider中進行管理,而為了更好的進行跨進程訪問,谷歌針對Provider提出了HIDL機制用于Camera Servic對于Camera Provier的訪問,而HIDL接口的實現(xiàn)是在Camera Provider中實現(xiàn),針對Camera HAL Module的控制又是通過谷歌制定的Camera HAL3接口來完成,所以由此看來,Provider的職責也比較簡單,通過HIDL機制保持與Camera Service的通信,通過HAL3接口控制著Camera HAL Module。
原文鏈接:https://blog.csdn.net/u012596975/article/details/107137523
友情推薦:
至此,本篇已結束。轉載網(wǎng)絡的文章,小編覺得很優(yōu)秀,歡迎點擊閱讀原文,支持原創(chuàng)作者,如有侵權,懇請聯(lián)系小編刪除,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!
點擊閱讀原文,為大佬點贊!
