Camera MetaData介绍_独家原创

目录

1. Camera MetaData 作用

2. Camera MetaData 定义

2.1 内存分布

2.2 常用 API

2.3 vendor tag 操作集

3. Camera Metadata 参数下发流程分析


1. Camera MetaData 作用

新的 Camera API2 / HAL3 架构将 SetParameter()/GetParameter() 改为 Camera MetaData 的方式设置或获取参数。

Camera MetaData 将参数以有序结构体的形式保存在一块连续内存中。

2. Camera MetaData 定义

编译产物:libcamera_metadata.so

系统位置:/system/lib64/,/system/lib/

源代码位置:/system/media/camera/

看下编译配置文件 Android.bp:

package {
    // http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // the below license kinds from "system_media_license":
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["system_media_license"],
}

subdirs = ["tests"]

cc_library_shared {
    name: "libcamera_metadata",
    vendor_available: true,
    product_available: true,
    // remove when no longer needed.
    native_bridge_supported: true,
    host_supported: true,
    vndk: {
        enabled: true,
    },
    double_loadable: true,
    srcs: ["src/camera_metadata.c"],

    include_dirs: ["system/media/private/camera/include"],
    local_include_dirs: ["include"],
    export_include_dirs: ["include"],

    header_libs: [
        "libcutils_headers",
    ],

    export_header_lib_headers: [
        "libcutils_headers",
    ],

    shared_libs: [
        "liblog",
    ],

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-fvisibility=hidden",
        "-std=c11",
    ],

    product_variables: {
        eng: {
            // Enable assert()
            cflags: [
                "-UNDEBUG",
                "-DLOG_NDEBUG=1",
            ],
        },
    },
}

filegroup {
    name: "libcamera_metadata_tags_file",
    srcs: ["include/system/camera_metadata_tags.h"],
}

2.1 内存分布

一块儿连续的内存空间,数据分布情况代码注释说明:

# system/media/camera/src/camera_metadata.c

/**
 * A packet of metadata. This is a list of entries, each of which may point to
 * its values stored at an offset in data.
 *
 * It is assumed by the utility functions that the memory layout of the packet
 * is as follows:
 *
 *   |-----------------------------------------------|
 *   | camera_metadata_t                             |
 *   |                                               |
 *   |-----------------------------------------------|
 *   | reserved for future expansion                 |
 *   |-----------------------------------------------|
 *   | camera_metadata_buffer_entry_t #0             |
 *   |-----------------------------------------------|
 *   | ....                                          |
 *   |-----------------------------------------------|
 *   | camera_metadata_buffer_entry_t #entry_count-1 |
 *   |-----------------------------------------------|
 *   | free space for                                |
 *   | (entry_capacity-entry_count) entries          |
 *   |-----------------------------------------------|
 *   | start of camera_metadata.data                 |
 *   |                                               |
 *   |-----------------------------------------------|
 *   | free space for                                |
 *   | (data_capacity-data_count) bytes              |
 *   |-----------------------------------------------|
 *
 * With the total length of the whole packet being camera_metadata.size bytes.
 *
 * In short, the entries and data are contiguous in memory after the metadata
 * header.
 */
#define METADATA_ALIGNMENT ((size_t) 4)
struct camera_metadata {
    metadata_size_t          size;
    uint32_t                 version;
    uint32_t                 flags;
    metadata_size_t          entry_count;
    metadata_size_t          entry_capacity;
    metadata_uptrdiff_t      entries_start; // Offset from camera_metadata
    metadata_size_t          data_count;
    metadata_size_t          data_capacity;
    metadata_uptrdiff_t      data_start; // Offset from camera_metadata
    uint32_t                 padding;    // padding to 8 bytes boundary
    metadata_vendor_id_t     vendor_id;
};
  1. 存 camera_metadata_t 结构体具体对象
  2. 保留区:未来扩展使用
  3. 序号为 0~entry_count-1 的 camera_metadata_buffer_entry_t 结构体对象,简称 metadata_entry 结构体对象,每个对象有自己的 tag。
  4. 保留区:保留 entry_capacity-entry_count 个 camera_metadata_buffer_entry_t 的空间
  5. metadata_entry 结构体对象对应 camera_metadata_data_t 数据
  6. 保留区:保留的 metadata_entry 结构体对象对应 camera_metadata_data_t 数据的空间

上面涉及的结构体 camera_metadata_buffer_entry_t 和 camera_metadata_data_t 都是什么呢?直接看注释:

metadata_entry:

/**
 * A single metadata entry, storing an array of values of a given type. If the
 * array is no larger than 4 bytes in size, it is stored in the data.value[]
 * array; otherwise, it can found in the parent's data array at index
 * data.offset.
 */
#define ENTRY_ALIGNMENT ((size_t) 4)
typedef struct camera_metadata_buffer_entry {
    uint32_t tag;
    uint32_t count;
    union {
        uint32_t offset;
        uint8_t  value[4];
    } data;
    uint8_t  type;
    uint8_t  reserved[3];
} camera_metadata_buffer_entry_t;

typedef uint32_t metadata_uptrdiff_t;
typedef uint32_t metadata_size_t;

metadata_data: 

/**
 * A datum of metadata. This corresponds to camera_metadata_entry_t::data
 * with the difference that each element is not a pointer. We need to have a
 * non-pointer type description in order to figure out the largest alignment
 * requirement for data (DATA_ALIGNMENT).
 */
#define DATA_ALIGNMENT ((size_t) 8)
typedef union camera_metadata_data {
    uint8_t u8;
    int32_t i32;
    float   f;
    int64_t i64;
    double  d;
    camera_metadata_rational_t r;
} camera_metadata_data_t;

那问题来了,tag 究竟有哪些?

是这样,tag很多,会分组,每组叫做一个section,先看section。在 system/media/camera/include/system/camera_metadata_tags.h 里定义:

/**
 * Top level hierarchy definitions for camera metadata. *_INFO sections are for
 * the static metadata that can be retrived without opening the camera device.
 * New sections must be added right before ANDROID_SECTION_COUNT to maintain
 * existing enumerations.
 */
typedef enum camera_metadata_section {
    ANDROID_COLOR_CORRECTION,
    ANDROID_CONTROL,
    ANDROID_DEMOSAIC,
    ANDROID_EDGE,
    ANDROID_FLASH,
    ANDROID_FLASH_INFO,
    ANDROID_HOT_PIXEL,
    ANDROID_JPEG,
    ANDROID_LENS,
    ANDROID_LENS_INFO,
    ANDROID_NOISE_REDUCTION,
    ANDROID_QUIRKS,
    ANDROID_REQUEST,
    ANDROID_SCALER,
    ANDROID_SENSOR,
    ANDROID_SENSOR_INFO,
    ANDROID_SHADING,
    ANDROID_STATISTICS,
    ANDROID_STATISTICS_INFO,
    ANDROID_TONEMAP,
    ANDROID_LED,
    ANDROID_INFO,
    ANDROID_BLACK_LEVEL,
    ANDROID_SYNC,
    ANDROID_REPROCESS,
    ANDROID_DEPTH,
    ANDROID_LOGICAL_MULTI_CAMERA,
    ANDROID_DISTORTION_CORRECTION,
    ANDROID_HEIC,
    ANDROID_HEIC_INFO,
    ANDROID_SECTION_COUNT,

    VENDOR_SECTION = 0x8000
} camera_metadata_section_t;

再看详细的所有 tag,我想你应该懂了,没错,每个 tag 都是 section 为前缀的,并且都是以  [section]_START 开始以 [section]_END 结束:

/**
 * Main enum for defining camera metadata tags.  New entries must always go
 * before the section _END tag to preserve existing enumeration values.  In
 * addition, the name and type of the tag needs to be added to
 * system/media/camera/src/camera_metadata_tag_info.c
 */
typedef enum camera_metadata_tag {
    ANDROID_COLOR_CORRECTION_MODE =                   // enum         | public       | HIDL v3.2
            ANDROID_COLOR_CORRECTION_START,
    ANDROID_COLOR_CORRECTION_TRANSFORM,               // rational[]   | public       | HIDL v3.2
    ANDROID_COLOR_CORRECTION_GAINS,                   // float[]      | public       | HIDL v3.2
    ANDROID_COLOR_CORRECTION_ABERRATION_MODE,         // enum         | public       | HIDL v3.2
    ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
                                                      // byte[]       | public       | HIDL v3.2
    ANDROID_COLOR_CORRECTION_END,

    ANDROID_CONTROL_AE_ANTIBANDING_MODE =             // enum         | public       | HIDL v3.2
            ANDROID_CONTROL_START,
    ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,         // int32        | public       | HIDL v3.2
    ANDROID_CONTROL_AE_LOCK,                          // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AE_MODE,                          // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AE_REGIONS,                       // int32[]      | public       | HIDL v3.2
    ANDROID_CONTROL_AE_TARGET_FPS_RANGE,              // int32[]      | public       | HIDL v3.2
    ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,            // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AF_MODE,                          // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AF_REGIONS,                       // int32[]      | public       | HIDL v3.2
    ANDROID_CONTROL_AF_TRIGGER,                       // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AWB_LOCK,                         // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AWB_MODE,                         // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AWB_REGIONS,                      // int32[]      | public       | HIDL v3.2
    ANDROID_CONTROL_CAPTURE_INTENT,                   // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_EFFECT_MODE,                      // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_MODE,                             // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_SCENE_MODE,                       // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,         // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,   // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_AE_AVAILABLE_MODES,               // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,   // int32[]      | public       | HIDL v3.2
    ANDROID_CONTROL_AE_COMPENSATION_RANGE,            // int32[]      | public       | HIDL v3.2
    ANDROID_CONTROL_AE_COMPENSATION_STEP,             // rational     | public       | HIDL v3.2
    ANDROID_CONTROL_AF_AVAILABLE_MODES,               // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_AVAILABLE_EFFECTS,                // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_AVAILABLE_SCENE_MODES,            // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
                                                      // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_AWB_AVAILABLE_MODES,              // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_MAX_REGIONS,                      // int32[]      | ndk_public   | HIDL v3.2
    ANDROID_CONTROL_SCENE_MODE_OVERRIDES,             // byte[]       | system       | HIDL v3.2
    ANDROID_CONTROL_AE_PRECAPTURE_ID,                 // int32        | system       | HIDL v3.2
    ANDROID_CONTROL_AE_STATE,                         // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AF_STATE,                         // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AF_TRIGGER_ID,                    // int32        | system       | HIDL v3.2
    ANDROID_CONTROL_AWB_STATE,                        // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
                                                      // int32[]      | hidden       | HIDL v3.2
    ANDROID_CONTROL_AE_LOCK_AVAILABLE,                // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AWB_LOCK_AVAILABLE,               // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AVAILABLE_MODES,                  // byte[]       | public       | HIDL v3.2
    ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE, // int32[]      | public       | HIDL v3.2
    ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,       // int32        | public       | HIDL v3.2
    ANDROID_CONTROL_ENABLE_ZSL,                       // enum         | public       | HIDL v3.2
    ANDROID_CONTROL_AF_SCENE_CHANGE,                  // enum         | public       | HIDL v3.3
    ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES,
                                                      // int32[]      | ndk_public   | HIDL v3.5
    ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES,
                                                      // float[]      | ndk_public   | HIDL v3.5
    ANDROID_CONTROL_EXTENDED_SCENE_MODE,              // enum         | public       | HIDL v3.5
    ANDROID_CONTROL_ZOOM_RATIO_RANGE,                 // float[]      | public       | HIDL v3.5
    ANDROID_CONTROL_ZOOM_RATIO,                       // float        | public       | HIDL v3.5
    ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION,
                                                      // int32[]      | hidden       | HIDL v3.6
    ANDROID_CONTROL_AF_REGIONS_SET,                   // enum         | fwk_only
    ANDROID_CONTROL_AE_REGIONS_SET,                   // enum         | fwk_only
    ANDROID_CONTROL_AWB_REGIONS_SET,                  // enum         | fwk_only
    ANDROID_CONTROL_END,

    ANDROID_DEMOSAIC_MODE =                           // enum         | system       | HIDL v3.2
            ANDROID_DEMOSAIC_START,
    ANDROID_DEMOSAIC_END,

    ANDROID_EDGE_MODE =                               // enum         | public       | HIDL v3.2
            ANDROID_EDGE_START,
    ANDROID_EDGE_STRENGTH,                            // byte         | system       | HIDL v3.2
    ANDROID_EDGE_AVAILABLE_EDGE_MODES,                // byte[]       | public       | HIDL v3.2
    ANDROID_EDGE_END,

    ANDROID_FLASH_FIRING_POWER =                      // byte         | system       | HIDL v3.2
            ANDROID_FLASH_START,
    ANDROID_FLASH_FIRING_TIME,                        // int64        | system       | HIDL v3.2
    ANDROID_FLASH_MODE,                               // enum         | public       | HIDL v3.2
    ANDROID_FLASH_COLOR_TEMPERATURE,                  // byte         | system       | HIDL v3.2
    ANDROID_FLASH_MAX_ENERGY,                         // byte         | system       | HIDL v3.2
    ANDROID_FLASH_STATE,                              // enum         | public       | HIDL v3.2
    ANDROID_FLASH_END,

    ANDROID_FLASH_INFO_AVAILABLE =                    // enum         | public       | HIDL v3.2
            ANDROID_FLASH_INFO_START,
    ANDROID_FLASH_INFO_CHARGE_DURATION,               // int64        | system       | HIDL v3.2
    ANDROID_FLASH_INFO_END,


// 省略一堆代码

} camera_metadata_tag_t;

每个 tag 的数据结构体定义呢?

由 union 指针指向真实数据。

/**
 * A reference to a metadata entry in a buffer.
 *
 * The data union pointers point to the real data in the buffer, and can be
 * modified in-place if the count does not need to change. The count is the
 * number of entries in data of the entry's type, not a count of bytes.
 */
typedef struct camera_metadata_entry {
    size_t   index;
    uint32_t tag;
    uint8_t  type;
    size_t   count;
    union {
        uint8_t *u8;
        int32_t *i32;
        float   *f;
        int64_t *i64;
        double  *d;
        camera_metadata_rational_t *r;
    } data;
} camera_metadata_entry_t;

2.2 常用 API

在 system/media/camera/include/system/camera_metadata.h 里,用来操作 metadata,太多就不展示了。接口实现在 camera_metadata.c 里,举几个例子:

static camera_metadata_buffer_entry_t *get_entries(
        const camera_metadata_t *metadata) {
    return (camera_metadata_buffer_entry_t*)
            ((uint8_t*)metadata + metadata->entries_start);
}

static uint8_t *get_data(const camera_metadata_t *metadata) {
    return (uint8_t*)metadata + metadata->data_start;
}

size_t get_camera_metadata_alignment() {
    return METADATA_PACKET_ALIGNMENT;
}

camera_metadata_t *allocate_copy_camera_metadata_checked(
        const camera_metadata_t *src,
        size_t src_size) {

    if (src == NULL) {
        return NULL;
    }

    if (src_size < sizeof(camera_metadata_t)) {
        ALOGE("%s: Source size too small!", __FUNCTION__);
        android_errorWriteLog(0x534e4554, "67782345");
        return NULL;
    }

    void *buffer = calloc(1, src_size);
    memcpy(buffer, src, src_size);

    camera_metadata_t *metadata = (camera_metadata_t*) buffer;
    if (validate_camera_metadata_structure(metadata, &src_size) != OK) {
        free(buffer);
        return NULL;
    }

    return metadata;
}

camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
                                            size_t data_capacity) {

    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
                                                          data_capacity);
    void *buffer = calloc(1, memory_needed);
    camera_metadata_t *metadata = place_camera_metadata(
        buffer, memory_needed, entry_capacity, data_capacity);
    if (!metadata) {
        /* This should not happen when memory_needed is the same
         * calculated in this function and in place_camera_metadata.
         */
        free(buffer);
    }
    return metadata;
}

camera_metadata_t *place_camera_metadata(void *dst,
                                         size_t dst_size,
                                         size_t entry_capacity,
                                         size_t data_capacity) {
    if (dst == NULL) return NULL;

    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
                                                          data_capacity);
    if (memory_needed > dst_size) {
      ALOGE("%s: Memory needed to place camera metadata (%zu) > dst size (%zu)", __FUNCTION__,
              memory_needed, dst_size);
      return NULL;
    }

    camera_metadata_t *metadata = (camera_metadata_t*)dst;
    metadata->version = CURRENT_METADATA_VERSION;
    metadata->flags = 0;
    metadata->entry_count = 0;
    metadata->entry_capacity = entry_capacity;
    metadata->entries_start =
            ALIGN_TO(sizeof(camera_metadata_t), ENTRY_ALIGNMENT);
    metadata->data_count = 0;
    metadata->data_capacity = data_capacity;
    metadata->size = memory_needed;
    size_t data_unaligned = (uint8_t*)(get_entries(metadata) +
            metadata->entry_capacity) - (uint8_t*)metadata;
    metadata->data_start = ALIGN_TO(data_unaligned, DATA_ALIGNMENT);
    metadata->vendor_id = CAMERA_METADATA_INVALID_VENDOR_ID;

    assert(validate_camera_metadata_structure(metadata, NULL) == OK);
    return metadata;
}
void free_camera_metadata(camera_metadata_t *metadata) {
    free(metadata);
}

size_t calculate_camera_metadata_size(size_t entry_count,
                                      size_t data_count) {
    size_t memory_needed = sizeof(camera_metadata_t);
    // Start entry list at aligned boundary
    memory_needed = ALIGN_TO(memory_needed, ENTRY_ALIGNMENT);
    memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
    // Start buffer list at aligned boundary
    memory_needed = ALIGN_TO(memory_needed, DATA_ALIGNMENT);
    memory_needed += sizeof(uint8_t[data_count]);
    // Make sure camera metadata can be stacked in continuous memory
    memory_needed = ALIGN_TO(memory_needed, METADATA_PACKET_ALIGNMENT);
    return memory_needed;
}

size_t get_camera_metadata_size(const camera_metadata_t *metadata) {
    if (metadata == NULL) return ERROR;

    return metadata->size;
}

size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
    if (metadata == NULL) return ERROR;

    return calculate_camera_metadata_size(metadata->entry_count,
                                          metadata->data_count);
}

size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
    return metadata->entry_count;
}

size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
    return metadata->entry_capacity;
}

size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
    return metadata->data_count;
}

size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
    return metadata->data_capacity;
}

camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
        const camera_metadata_t *src) {
    size_t memory_needed = get_camera_metadata_compact_size(src);

    if (dst == NULL) return NULL;
    if (dst_size < memory_needed) {
        ALOGE("%s: Memory needed to place camera metadata (%zu) > dst size (%zu)", __FUNCTION__,
                memory_needed, dst_size);
      return NULL;
    }

    camera_metadata_t *metadata =
        place_camera_metadata(dst, dst_size, src->entry_count, src->data_count);

    metadata->flags = src->flags;
    metadata->entry_count = src->entry_count;
    metadata->data_count = src->data_count;
    metadata->vendor_id = src->vendor_id;

    memcpy(get_entries(metadata), get_entries(src),
            sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
    memcpy(get_data(metadata), get_data(src),
            sizeof(uint8_t[metadata->data_count]));

    assert(validate_camera_metadata_structure(metadata, NULL) == OK);
    return metadata;
}

如果对上面几个小节理解了,比如内存分布,结构体定义等,那么这些 API 代码实现也就好理解了。

2.3 vendor tag 操作集

对于OEM厂商可能想对自己定义的 metadata 进行操作。查询其静态信息,验证HAL返回的 metadata 数据结构,并允许供应商定义的元数据标签在面向相机API的应用程序中可见。

/**
 * Vendor tags:
 *
 * This structure contains basic functions for enumerating an immutable set of
 * vendor-defined camera metadata tags, and querying static information about
 * their structure/type.  The intended use of this information is to validate
 * the structure of metadata returned by the camera HAL, and to allow vendor-
 * defined metadata tags to be visible in application facing camera API.
 */
typedef struct vendor_tag_ops vendor_tag_ops_t;
struct vendor_tag_ops {
    /**
     * Get the number of vendor tags supported on this platform. Used to
     * calculate the size of buffer needed for holding the array of all tags
     * returned by get_all_tags().  This must return -1 on error.
     */
    int (*get_tag_count)(const vendor_tag_ops_t *v);

    /**
     * Fill an array with all of the supported vendor tags on this platform.
     * get_tag_count() must return the number of tags supported, and
     * tag_array will be allocated with enough space to hold the number of tags
     * returned by get_tag_count().
     */
    void (*get_all_tags)(const vendor_tag_ops_t *v, uint32_t *tag_array);

    /**
     * Get the vendor section name for a vendor-specified entry tag. This will
     * only be called for vendor-defined tags.
     *
     * The naming convention for the vendor-specific section names should
     * follow a style similar to the Java package style.  For example,
     * CameraZoom Inc. must prefix their sections with "com.camerazoom."
     * This must return NULL if the tag is outside the bounds of
     * vendor-defined sections.
     *
     * There may be different vendor-defined tag sections, for example the
     * phone maker, the chipset maker, and the camera module maker may each
     * have their own "com.vendor."-prefixed section.
     *
     * The memory pointed to by the return value must remain valid for the
     * lifetime of the module, and is owned by the module.
     */
    const char *(*get_section_name)(const vendor_tag_ops_t *v, uint32_t tag);

    /**
     * Get the tag name for a vendor-specified entry tag. This is only called
     * for vendor-defined tags, and must return NULL if it is not a
     * vendor-defined tag.
     *
     * The memory pointed to by the return value must remain valid for the
     * lifetime of the module, and is owned by the module.
     */
    const char *(*get_tag_name)(const vendor_tag_ops_t *v, uint32_t tag);

    /**
     * Get tag type for a vendor-specified entry tag. The type returned must be
     * a valid type defined in camera_metadata.h.  This method is only called
     * for tags >= CAMERA_METADATA_VENDOR_TAG_BOUNDARY, and must return
     * -1 if the tag is outside the bounds of the vendor-defined sections.
     */
    int (*get_tag_type)(const vendor_tag_ops_t *v, uint32_t tag);

    /* Reserved for future use.  These must be initialized to NULL. */
    void* reserved[8];
};

struct vendor_tag_cache_ops {
    /**
     * Get the number of vendor tags supported on this platform. Used to
     * calculate the size of buffer needed for holding the array of all tags
     * returned by get_all_tags().  This must return -1 on error.
     */
    int (*get_tag_count)(metadata_vendor_id_t id);

    /**
     * Fill an array with all of the supported vendor tags on this platform.
     * get_tag_count() must return the number of tags supported, and
     * tag_array will be allocated with enough space to hold the number of tags
     * returned by get_tag_count().
     */
    void (*get_all_tags)(uint32_t *tag_array, metadata_vendor_id_t id);

    /**
     * Get the vendor section name for a vendor-specified entry tag. This will
     * only be called for vendor-defined tags.
     *
     * The naming convention for the vendor-specific section names should
     * follow a style similar to the Java package style.  For example,
     * CameraZoom Inc. must prefix their sections with "com.camerazoom."
     * This must return NULL if the tag is outside the bounds of
     * vendor-defined sections.
     *
     * There may be different vendor-defined tag sections, for example the
     * phone maker, the chipset maker, and the camera module maker may each
     * have their own "com.vendor."-prefixed section.
     *
     * The memory pointed to by the return value must remain valid for the
     * lifetime of the module, and is owned by the module.
     */
    const char *(*get_section_name)(uint32_t tag, metadata_vendor_id_t id);

    /**
     * Get the tag name for a vendor-specified entry tag. This is only called
     * for vendor-defined tags, and must return NULL if it is not a
     * vendor-defined tag.
     *
     * The memory pointed to by the return value must remain valid for the
     * lifetime of the module, and is owned by the module.
     */
    const char *(*get_tag_name)(uint32_t tag, metadata_vendor_id_t id);

    /**
     * Get tag type for a vendor-specified entry tag. The type returned must be
     * a valid type defined in camera_metadata.h.  This method is only called
     * for tags >= CAMERA_METADATA_VENDOR_TAG_BOUNDARY, and must return
     * -1 if the tag is outside the bounds of the vendor-defined sections.
     */
    int (*get_tag_type)(uint32_t tag, metadata_vendor_id_t id);

    /* Reserved for future use.  These must be initialized to NULL. */
    void* reserved[8];
};

用户可以自定义 vendor tag 的操作方法:

// Declared in system/media/private/camera/include/camera_metadata_hidden.h
int set_camera_metadata_vendor_ops(const vendor_tag_ops_t* ops) {
    vendor_tag_ops = ops;
    return OK;
}

// Declared in system/media/private/camera/include/camera_metadata_hidden.h
int set_camera_metadata_vendor_cache_ops(
        const struct vendor_tag_cache_ops *query_cache_ops) {
    vendor_cache_ops = query_cache_ops;
    return OK;
}

3. Camera Metadata 参数下发流程分析

具体代码不讲,代码在更新,写法可能有区别,但流程一样。直接说流程:

  1. 初始化 mMetadata。要设定场景,比如 mDevice->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW, mMetadata) 这种写法。
  2. 更新参数 mMetadata.update()。比如 mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1)。
  3. 下发参数。比如 mDevice->setStreamingRequest(*mMetadata)。
  4. 在 Camera3Device.cpp 中,最终将 request 放入mRequestQueue 中。
    在 Camera3Device::RequestThread::threadLoop() 来对 mRequestQueue 消息进行处理。

  5. 调用 HAL 层的 process_capture_request() 方法,处理 request 请求
    最终通过ioctl(fd, VIDIOC_S_CTRL, &control); 往 V4L2 driver 下发参数。

  6. 在 driver 中,根据具体设备注册 V4L2_ctrl 时的 ops ,调用不同的操作函数,来更新具体的硬件寄存器。

你可能感兴趣的:(车载Camera专家教程,Camera)