CameraMetadata 知识学习整理

一、涉及的相关代码路径

system/media/camera/src/camera_metadata.c  // metadata的核心内容,包含metadata内存分配,扩容规则,update, find等

system/media/camera/src/camera_metadata_tag_info.c // 所有android原生tag的在内存里面section的定义

frameworks/av/camera/CameraMetadata.cpp  // camera_metadata.c 的封装

hardware/interface/camera/...... 目录下也有一个CameraMetadata.cpp,看不出来干什么用的

二、重要数据结构

整个camera_metadata的结构体

size: 整个metadata内存大小,计算方式如下

结构体头的大小 + camera_metadata_buffer_entry_t总大小(每个metadata的内存结构)+  大于4字节的metadata数据部分(后面介绍) ;ALGIN_TO字节对齐,不用深究。

version:版本号,不重要

flags:不重要

entry_count:已经添加的metadata个数

entry_capacity:整个metadata空间可容纳最多metadata个数

entries_start:metadata结构体存储开始的地方

可以看到entries_start就是紧接着camera_metada_t结构体之后

data_count:数据部分大于4字节的metadata的数据部分总大小

data_capacity:数据部分大于4字节的metadata的数据部分最大容量

data_start:数据部分大于4字节的metadata的数据部分开始地址

可以看到data_start紧接着一堆 camera_metadata_buffer_entry_t 类型数据之后

padding:不重要

vendor_id:不重要

单个具体metadata结构体

从注释可以看到,如果该metadata的数据部分大于4个字节,就存储到父数组里面,就是所有camera_metadata_buffer_entry_t 之后;如果小于等于4字节,直接存储到value[4]里面。

tag:就是下面的枚举值,基于各个section的偏移,标识唯一的tag

count:个人理解count=1是基本数据,count > 1就是数组了;未深入最终过

data.offset:如果数据部分超过4字节,offset就表示该tag的数据存放在 data_start + offset开始处

data.value:如果数据部分不超过4字节, 表示该tag的数据存放在value数组里面。

type:metadata的数据类型,如下是数据类型和数据类型大小

reserved:不重要

 以上就是metadata两个最重要数据结构的介绍,理解数据怎么存储的,才能继续去理解代码逻辑

camera_metadata.c开头的一幅图再回来看一下

三、 添加、更新、查找 metadata方法学习

CameraMetadata.cpp里面定义了各个类型的metadata的update方法,通过注释看到,如果这个tag有了就做更新操作,没有就创建。

主要方法是updateImpl,先获取tag的类型,然后根据类型和data_count计算data_size,计算data_size的目的就是为了扩容做准备,resizeIfNeeded 就是扩容的具体做法。接着会根据tag到metadata里面找对应的camera_metadata_entry_t项,找到了就更新,找不到就创建

【扩容】:

resizeIfNeeded  是非常重要的扩容方法,如果之前没有创建过metadata,是第一个metadata,那么mBuffer一定是空的,就先创建;如果metadata创建过了,会分别计算新的entryCount和dataCount,如果有一个超过了capacity就需要重新分配camera_metadata的空间了,append_camera_metadata会将旧的数据拷到新的空间中, free_camera_metadata将旧的控件释放掉。

另外扩容的大小都是在现有的基础上乘以2,指数级的增加,所以扩容操作其实不频繁。

【添加】:

接下来在看一下add_camera_metadata_entry_raw方法,内存在上面分配好了之后就可以往里面填写数据了,data_bytes就是计算该tag数据部分占用多少个字节,如果不超过4字节,就返回0,走第一个memcpy;如果超过4字节就做了8字节对齐,走下面一个memcpy。data_payload_bytes是真正要拷贝的数据大小,就是简单的  个数 x 类型大小, 而dst buffer的大小肯定大于等于这个数值。

【更新】:

个人人为最精彩的就是 update_camera_metadata_entry的逻辑了,该方法里面的每一行都很精彩,所以在几乎每一行后面加了个人理解。

 

最后用一幅图简单说明update的时候内存怎么挪动的

【查询】:

最后的最后看看 find_camera_metadata_entry方法就很简单了,根据metadata是否被排过序进行查找,排过序就用二分查找(根据tag), 没有排过序就遍历entries找到目标tag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值