• 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

  • 相关阅读:
    代码随想录刷题day52 300.最长递增子序列;674. 最长连续递增序列;718. 最长重复子数组
    Hadoop的基本框架
    在 centos7 上安装Docker
    【Linux】Linux进程间通信——有名管道
    Android学习笔记 1.1 Android的发展和历史
    软考高级信息系统项目管理师系列之:信息系统项目管理师论文评分参考标准
    安装OceanBase的机器如果出现故障,应该如何处理
    Rust 从入门到精通09-模式解构
    最新Jn建站系统2.0 已集成各类源码 【附视频安装教程】
    Qml中的那些坑(三)---MouseArea上的ListView滚轮事件穿透
  • 原文地址:https://blog.csdn.net/cfc1243570631/article/details/128033812