/* SPDX-License-Identifier: Apache-2.0 *//* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#define LOG_TAG"camera_metadata"/* * Replace ALOGE() with a fprintf to stderr so that we don't need to * re-implement Android's logging system. The log/log.h header file is no * longer necessary once we removed dependency on ALOGE(). */#define ALOGE(...) fprintf(stderr, LOG_TAG __VA_ARGS__)#include <system/camera_metadata.h>#include <camera_metadata_hidden.h>#include <assert.h>#include <errno.h>#include <inttypes.h>#include <stddef.h>// for offsetof#include <stdio.h>#include <stdlib.h>#define OK 0#define ERROR 1#define NOT_FOUND (-ENOENT)#define SN_EVENT_LOG_ID 0x534e4554#define ALIGN_TO(val, alignment) \ (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))/** * 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)typedefstruct 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;typedefuint32_t metadata_uptrdiff_t;typedefuint32_t metadata_size_t;/** * 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_metadatauint32_t padding;// padding to 8 bytes boundary
metadata_vendor_id_t vendor_id;};/** * 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)typedefunion 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;_Static_assert(sizeof(metadata_size_t) ==4,"Size of metadata_size_t must be 4");_Static_assert(sizeof(metadata_uptrdiff_t) ==4,"Size of metadata_uptrdiff_t must be 4");_Static_assert(sizeof(metadata_vendor_id_t) ==8,"Size of metadata_vendor_id_t must be 8");_Static_assert(sizeof(camera_metadata_data_t) ==8,"Size of camera_metadata_data_t must be 8");_Static_assert(offsetof(camera_metadata_buffer_entry_t, tag) ==0,"Offset of tag must be 0");_Static_assert(offsetof(camera_metadata_buffer_entry_t, count) ==4,"Offset of count must be 4");_Static_assert(offsetof(camera_metadata_buffer_entry_t, data) ==8,"Offset of data must be 8");_Static_assert(offsetof(camera_metadata_buffer_entry_t, type) ==12,"Offset of type must be 12");_Static_assert(sizeof(camera_metadata_buffer_entry_t) ==16,"Size of camera_metadata_buffer_entry_t must be 16");_Static_assert(offsetof(camera_metadata_t, size) ==0,"Offset of size must be 0");_Static_assert(offsetof(camera_metadata_t, version) ==4,"Offset of version must be 4");_Static_assert(offsetof(camera_metadata_t, flags) ==8,"Offset of flags must be 8");_Static_assert(offsetof(camera_metadata_t, entry_count) ==12,"Offset of entry_count must be 12");_Static_assert(offsetof(camera_metadata_t, entry_capacity) ==16,"Offset of entry_capacity must be 16");_Static_assert(offsetof(camera_metadata_t, entries_start) ==20,"Offset of entries_start must be 20");_Static_assert(offsetof(camera_metadata_t, data_count) ==24,"Offset of data_count must be 24");_Static_assert(offsetof(camera_metadata_t, data_capacity) ==28,"Offset of data_capacity must be 28");_Static_assert(offsetof(camera_metadata_t, data_start) ==32,"Offset of data_start must be 32");_Static_assert(offsetof(camera_metadata_t, vendor_id) ==40,"Offset of vendor_id must be 40");_Static_assert(sizeof(camera_metadata_t) ==48,"Size of camera_metadata_t must be 48");/** * The preferred alignment of a packet of camera metadata. In general, * this is the lowest common multiple of the constituents of a metadata * package, i.e, of DATA_ALIGNMENT and ENTRY_ALIGNMENT. */#define MAX_ALIGNMENT(A, B) (((A) > (B)) ? (A) : (B))#define METADATA_PACKET_ALIGNMENT \ MAX_ALIGNMENT(MAX_ALIGNMENT(DATA_ALIGNMENT, METADATA_ALIGNMENT), ENTRY_ALIGNMENT)