Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互.docx
- 文档编号:10034431
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:18
- 大小:70.43KB
Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互.docx
《Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互.docx》由会员分享,可在线阅读,更多相关《Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互.docx(18页珍藏版)》请在冰豆网上搜索。
AndroidCameraAPI2中采用CameraMetadata用于从APP到HAL的参数交互
AndroidCameraAPI2中采用CameraMetadata用于从APP到HAL的参数交互
前沿:
在全新的CameraAPI2架构下,常常会有人疑问再也看不到熟悉的SetParameter/Paramters等相关的身影,取而代之的是一种全新的CameraMetadata结构的出现,他不仅很早就出现在CameraAPI1/API2结构下的Camera2Device、Camera3Device中用于和HAL3的数据交互,而现在在API2的驱使下都取代了Parameter,实现了Java到native到hal3的参数传递。
那么现在假如需要在APP中设置某一项控制参数,对于CameraAPI2而言,涉及到对Sensor相关参数的set/control时又需要做哪些工作呢?
1.camera_metadata类整体布局结构
主要涉及到的源文件包括camera_metadata_tags.h,camera_metadata_tag_info.c,CameraMetadata.cpp,camera_metadata.c。
对于每个Metadata数据,其通过不同业务控制需求,将整个camera工作需要的参数划分成多个不同的Section,其中在camera_metadata_tag_info.c表定义了所有Camera需要使用到的Section段的Name:
[cpp] viewplaincopy
1.const char *camera_metadata_section_names[ANDROID_SECTION_COUNT] = {
2. [ANDROID_COLOR_CORRECTION] = "android.colorCorrection",
3. [ANDROID_CONTROL] = "android.control",
4. [ANDROID_DEMOSAIC] = "android.demosaic",
5. [ANDROID_EDGE] = "android.edge",
6. [ANDROID_FLASH] = "android.flash",
7. [ANDROID_FLASH_INFO] = "android.flash.info",
8. [ANDROID_GEOMETRIC] = "android.geometric",
9. [ANDROID_HOT_PIXEL] = "android.hotPixel",
10. [ANDROID_HOT_PIXEL_INFO] = "android.hotPixel.info",
11. [ANDROID_JPEG] = "android.jpeg",
12. [ANDROID_LENS] = "android.lens",
13. [ANDROID_LENS_INFO] = "android.lens.info",
14. [ANDROID_NOISE_REDUCTION] = "android.noiseReduction",
15. [ANDROID_QUIRKS] = "android.quirks",
16. [ANDROID_REQUEST] = "android.request",
17. [ANDROID_SCALER] = "android.scaler",
18. [ANDROID_SENSOR] = "android.sensor",
19. [ANDROID_SENSOR_INFO] = "android.sensor.info",
20. [ANDROID_SHADING] = "android.shading",
21. [ANDROID_STATISTICS] = "android.statistics",
22. [ANDROID_STATISTICS_INFO] = "android.statistics.info",
23. [ANDROID_TONEMAP] = "android.tonemap",
24. [ANDROID_LED] = "android.led",
25. [ANDROID_INFO] = "android.info",
26. [ANDROID_BLACK_LEVEL] = "android.blackLevel",
27.};
对于每个Section端而言,其都占据一个索引区域section_bounds,比如ANDROID_CONTROLSection他所代表的control区域是从ANDROID_CONTROL_START到ANDROID_CONTROL_END之间,且每个Section所拥有的Index范围理论最大可到(1<<16)大小,完全可以满足统一Section下不同的控制参数的维护。
以ANDROID_CONTROL为列,他的Sectionindex=1,即对应的sectionindex区间可到(1<<16,2<<16),但一般以实际section中维护的tag的数量来结束,即ANDROID_CONTROL_END决定最终的sectionindex区间。
对于每一个section,其下具备不同数量的tag,这个tag是一个指定section下的index值,通过该值来维护一个tag所在的数据区域,此外每个tag都有相应的string name,在camera_metadata_tag_info.c通过struct tag_info_t来维护一个tag的相关属性:
[cpp] viewplaincopy
1.typedef struct tag_info {
2. const char *tag_name;
3. uint8_t tag_type;
4.} tag_info_t;
其中tag_name为对应section下不同tag的name值,tag_type指定了这个tag所维护的数据类型,包括如下:
[cpp] viewplaincopy
1.enum {
2. // Unsigned 8-bit integer (uint8_t)
3. TYPE_BYTE = 0,
4. // Signed 32-bit integer (int32_t)
5. TYPE_INT32 = 1,
6. // 32-bit float (float)
7. TYPE_FLOAT = 2,
8. // Signed 64-bit integer (int64_t)
9. TYPE_INT64 = 3,
10. // 64-bit float (double)
11. TYPE_DOUBLE = 4,
12. // A 64-bit fraction (camera_metadata_rational_t)
13. TYPE_RATIONAL = 5,
14. // Number of type fields
15. NUM_TYPES
16.};
对每一个section所拥有的tag_info信息,通过全局结构体tag_info_t*tag_info[ANDROID_SECTION_COUNT]来定义。
下图是对整个CameraMetadata对不同section以及相应section下不同tag的布局图,下图以最常见的android.control Section为例进行了描述:
2.CameraMetadata通过camera_metadata来维护数据信息
假设现在存在一个CameraMetadata对象,那么他是如何将一个tag标记的参数维护起来的呢?
[cpp] viewplaincopy
1.CameraMetadata:
:
CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
2. mLocked(false)
3.{
4. mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
5.}
[cpp] viewplaincopy
1.camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
2. size_t data_capacity) {
3. if (entry_capacity == 0) return NULL;
4.
5. size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
6. data_capacity);
7. void *buffer = malloc(memory_needed);
8. return place_camera_metadata(buffer, memory_needed,
9. entry_capacity,
10. data_capacity);
11.}
一个CameraMetadata数据内存块中组成的最小基本单元是struct camera_metadata_buffer_entry,总的entry数目等信息需要struct camera_metadata_t来维护:
[cpp] viewplaincopy
1.struct camera_metadata {
2. size_t size;
3. uint32_t version;
4. uint32_t flags;
5. size_t entry_count;//当前实际的entry数目
6. size_t entry_capacity;//entry最大可以存储的数目
7. uptrdiff_t entries_start; // Offset from camera_metadata
8. size_t data_count;//当前占据的数据空间
9. size_t data_capacity;//最大可操作的数据容量
10. uptrdiff_t data_start; // Offset from camera_metadata,大容量数据存储的起始地址
11. void *user; // User set pointer, not copied with buffer
12. uint8_t reserved[0];
13.};
对于每一个entry主要记录他的所代表的TAG,以及这个TAG的需要存储的数据类型,此外还需要记录这个entry是否是需要一个unionoffset来表示他当前数据量过大时的数据存储位置,
[cpp] viewplaincopy
1.typedef struct camera_metadata_buffer_entry {
2. uint32_t tag;//表示当时这个entry代表的tag值,即上文提到的section中不同的tag index值
3. size_t count;
4. union {
5. size_t offset;
6. uint8_t value[4];
7. } data;//如果存储的数据量不大于4则直接存储。
否则需要指点一个offset来表示便宜
8. uint8_t type;//维护的数据类型
9. uint8_t reserved[3];
10.} camera_metadata_buffer_entry_t;
3. update更新并建立参数
CameraMetadata支持不同类型的数据更新或者保存到camera_metadata_t中tag所在的entry当中去,以一个更新单字节的数据为例,data_count指定了数据的个数,而tag指定了要更新的entry。
[cpp] viewplaincopy
1.status_t CameraMetadata:
:
update(uint32_t tag,
2. const uint8_t *data, size_t data_count) {
3. status_t res;
4. if (mLocked) {
5. ALOGE("%s:
CameraMetadata is locked", __FUNCTION__);
6. return INVALID_OPERATION;
7. }
8. if ( (res = checkType(tag, TYPE_BYTE)) !
= OK) {
9. return res;
10. }
11. return updateImpl(tag, (const void*)data, data_count);
12.}
首先是通过checkType,主要是通过tag找到get_camera_metadata_tag_type其所应当支持的tag_type(因为具体的TAG是已经通过camera_metadata_tag_info.c源文件中的tag_info这个表指定了其应该具备的tag_type),比较两者是否一致,一致后才允许后续的操作,如这里需要TYPE_BYTE一致。
updataImpl函数主要是讲所有要写入的数据进行update操作。
[cpp] viewplaincopy
1.status_t CameraMetadata:
:
updateImpl(uint32_t tag, const void *data,
2. size_t data_count) {
3. status_t res;
4. if (mLocked) {
5. ALOGE("%s:
CameraMetadata is locked", __FUNCTION__);
6. return INVALID_OPERATION;
7. }
8. int type = get_camera_metadata_tag_type(tag);
9. if (type == -1) {
10. ALOGE("%s:
Tag %d not found", __FUNCTION__, tag);
11. return BAD_VALUE;
12. }
13. size_t data_size = calculate_camera_metadata_entry_data_size(type,
14. data_count);
15.
16. res = resizeIfNeeded(1, data_size);//新建camera_metadata_t
17.
18. if (res == OK) {
19. camera_metadata_entry_t entry;
20. res = find_camera_metadata_entry(mBuffer, tag, &entry);
21. if (res == NAME_NOT_FOUND) {
22. res = add_camera_metadata_entry(mBuffer,
23. tag, data, data_count);//将当前新的tag以及数据加入到camera_metadata_t
24. } else if (res == OK) {
25. res = update_camera_metadata_entry(mBuffer,
26. entry.index, data, data_count, NULL);
27. }
28. }
29.
30. if (res !
= OK) {
31. ALOGE("%s:
Unable to update metadata entry %s.%s (%x):
%s (%d)",
32. __FUNCTION__, get_camera_metadata_section_name(tag),
33. get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
34. }
35.
36. IF_ALOGV() {
37. ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !
=
38. OK,
39.
40. "%s:
Failed to validate metadata structure after update %p",
41. __FUNCTION__, mBuffer);
42. }
43.
44. return res;
45.}
主要分为以下几个过程:
a.通过tag_type存储的数据类型,由calculate_camera_metadata_entry_data_size计算要写入的entry中的数据量。
b. resizeIfNeeded通过已有entry的数量等,增加entry_capacity,或者重建整个camera_metadata_t,为后续增加数据创建内存空间基础。
c.通过find_camera_metadata_entry获取一个entry的入口camera_metadata_entry_t,如果存在这个tag对应的entry,则将camera_metadata_buffer_entry_t的属性信息转为camera_metadata_entry_t。
[cpp] viewplaincopy
1.typedef struct camera_metadata_entry {
2. size_t index;//在当前的entry排序中,其所在的index值
3. uint32_t tag;
4. uint8_t type;
5. size_t count;
6. union {
7. uint8_t *u8;
8. int32_t *i32;
9. float *f;
10. int64_t *i64;
11. double *d;
12. camera_metadata_rational_t *r;
13. } data;//针对不同数据类型,u8表示数据存储的入口地址,不大于4字节即为value[4].
14.} camera_metadata_entry_t;
d.add_camera_metadata_entry完成全新的entry更新与写入,即这个TAG目前不存在于这个camera_metadata_t中;update_camera_metadata_entry则是直接完成数据的更新。
[cpp] viewplaincopy
1.mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE,
2. CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
3. mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,
4. CaptureRequest.CONTROL_AE_MODE_
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互 API2 采用 CameraMetadata 用于 APP HAL 参数 交互
链接地址:https://www.bdocx.com/doc/10034431.html