1d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala/* 2d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project 3d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * 4d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 5d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * you may not use this file except in compliance with the License. 6d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * You may obtain a copy of the License at 7d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * 8d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 9d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * 10d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 11d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 12d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * See the License for the specific language governing permissions and 14d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * limitations under the License. 15d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala */ 168e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes 17773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn#include <inttypes.h> 18d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala#include <system/camera_metadata.h> 199c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk#include <camera_metadata_hidden.h> 20d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 21d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin#define LOG_TAG "camera_metadata" 22d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala#include <cutils/log.h> 23151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray#include <assert.h> 2494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#include <stdio.h> 2594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#include <stdlib.h> 2694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#include <errno.h> 2794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 2894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define OK 0 2994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define ERROR 1 3094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define NOT_FOUND -ENOENT 313154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala 323154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala#define ALIGN_TO(val, alignment) \ 33d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1)) 34d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 35d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala/** 36d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * A single metadata entry, storing an array of values of a given type. If the 37d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * array is no larger than 4 bytes in size, it is stored in the data.value[] 38d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * array; otherwise, it can found in the parent's data array at index 39d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * data.offset. 40d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala */ 4121532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath#define ENTRY_ALIGNMENT ((size_t) 4) 42f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalatypedef struct camera_metadata_buffer_entry { 43d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag; 4421532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath uint32_t count; 45d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala union { 4621532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath uint32_t offset; 4721532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath uint8_t value[4]; 48d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } data; 49d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint8_t type; 50d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint8_t reserved[3]; 513154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala} camera_metadata_buffer_entry_t; 52d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 5321532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamathtypedef uint32_t metadata_uptrdiff_t; 5421532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamathtypedef uint32_t metadata_size_t; 5521532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath 56d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala/** 57d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * A packet of metadata. This is a list of entries, each of which may point to 58d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * its values stored at an offset in data. 59d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * 60d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * It is assumed by the utility functions that the memory layout of the packet 61d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * is as follows: 62d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * 63f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 64f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | camera_metadata_t | 65f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | | 66f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 67f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | reserved for future expansion | 68f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 69f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | camera_metadata_buffer_entry_t #0 | 70f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 71f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | .... | 72f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 73f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | camera_metadata_buffer_entry_t #entry_count-1 | 74f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 75f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | free space for | 76f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | (entry_capacity-entry_count) entries | 77f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 78f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | start of camera_metadata.data | 79f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | | 80f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 81f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | free space for | 82f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * | (data_capacity-data_count) bytes | 83f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala * |-----------------------------------------------| 84d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * 85d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * With the total length of the whole packet being camera_metadata.size bytes. 86d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * 87d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * In short, the entries and data are contiguous in memory after the metadata 88d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * header. 89d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala */ 9021532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath#define METADATA_ALIGNMENT ((size_t) 4) 91d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalastruct camera_metadata { 9221532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata_size_t size; 9394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala uint32_t version; 9494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala uint32_t flags; 9521532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata_size_t entry_count; 9621532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata_size_t entry_capacity; 9721532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata_uptrdiff_t entries_start; // Offset from camera_metadata 9821532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata_size_t data_count; 9921532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata_size_t data_capacity; 10021532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata_uptrdiff_t data_start; // Offset from camera_metadata 10121532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath uint8_t reserved[]; 102d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}; 103d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 104555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin/** 105555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin * A datum of metadata. This corresponds to camera_metadata_entry_t::data 106555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin * with the difference that each element is not a pointer. We need to have a 107555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin * non-pointer type description in order to figure out the largest alignment 108555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin * requirement for data (DATA_ALIGNMENT). 109555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin */ 11021532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath#define DATA_ALIGNMENT ((size_t) 8) 111555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkintypedef union camera_metadata_data { 112555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin uint8_t u8; 113555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin int32_t i32; 114555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin float f; 115555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin int64_t i64; 116555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin double d; 117555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin camera_metadata_rational_t r; 118555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin} camera_metadata_data_t; 119555aac882ed63e70019c78ccc58032a5be0f58ecIgor Murashkin 12021532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath/** 12121532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath * The preferred alignment of a packet of camera metadata. In general, 12221532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath * this is the lowest common multiple of the constituents of a metadata 12321532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath * package, i.e, of DATA_ALIGNMENT and ENTRY_ALIGNMENT. 12421532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath */ 12521532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath#define MAX_ALIGNMENT(A, B) (((A) > (B)) ? (A) : (B)) 12621532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath#define METADATA_PACKET_ALIGNMENT \ 12721532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath MAX_ALIGNMENT(MAX_ALIGNMENT(DATA_ALIGNMENT, METADATA_ALIGNMENT), ENTRY_ALIGNMENT); 12821532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath 12994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Versioning information */ 13094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define CURRENT_METADATA_VERSION 1 13194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 13294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Flag definitions */ 13394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define FLAG_SORTED 0x00000001 13494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 13594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Tag information */ 13694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 137d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalatypedef struct tag_info { 138d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala const char *tag_name; 139d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint8_t tag_type; 140d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} tag_info_t; 141d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 142d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala#include "camera_metadata_tag_info.c" 143d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 144fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvalaconst size_t camera_metadata_type_size[NUM_TYPES] = { 145d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_BYTE] = sizeof(uint8_t), 146d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_INT32] = sizeof(int32_t), 147d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_FLOAT] = sizeof(float), 148d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_INT64] = sizeof(int64_t), 149d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_DOUBLE] = sizeof(double), 150d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t) 151d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}; 152d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 153fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvalaconst char *camera_metadata_type_names[NUM_TYPES] = { 154d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_BYTE] = "byte", 155d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_INT32] = "int32", 156d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_FLOAT] = "float", 157d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_INT64] = "int64", 158f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala [TYPE_DOUBLE] = "double", 159d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_RATIONAL] = "rational" 160d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}; 161d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 162b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvalastatic camera_metadata_buffer_entry_t *get_entries( 163b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala const camera_metadata_t *metadata) { 164b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala return (camera_metadata_buffer_entry_t*) 165b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala ((uint8_t*)metadata + metadata->entries_start); 166b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala} 167b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala 168b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvalastatic uint8_t *get_data(const camera_metadata_t *metadata) { 169b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala return (uint8_t*)metadata + metadata->data_start; 170b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala} 171b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala 1721450f7f45376976100d63d3b7f8a39c4dfd47553Zhijun Hesize_t get_camera_metadata_alignment() { 17321532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath return METADATA_PACKET_ALIGNMENT; 1741450f7f45376976100d63d3b7f8a39c4dfd47553Zhijun He} 1751450f7f45376976100d63d3b7f8a39c4dfd47553Zhijun He 176d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkincamera_metadata_t *allocate_copy_camera_metadata_checked( 177d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin const camera_metadata_t *src, 178d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin size_t src_size) { 179d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 180d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (src == NULL) { 181d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return NULL; 182d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 183d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 184d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin void *buffer = malloc(src_size); 185d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin memcpy(buffer, src, src_size); 186d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 187d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin camera_metadata_t *metadata = (camera_metadata_t*) buffer; 188d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (validate_camera_metadata_structure(metadata, &src_size) != OK) { 189d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin free(buffer); 190d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return NULL; 191d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 192d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 193d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return metadata; 194d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin} 195d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 196d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t *allocate_camera_metadata(size_t entry_capacity, 197d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_capacity) { 1982f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala 199d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t memory_needed = calculate_camera_metadata_size(entry_capacity, 200d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala data_capacity); 201d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala void *buffer = malloc(memory_needed); 202d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return place_camera_metadata(buffer, memory_needed, 203d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry_capacity, 204d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala data_capacity); 205d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 206d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 207d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t *place_camera_metadata(void *dst, 208d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t dst_size, 209d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t entry_capacity, 210d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_capacity) { 211d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst == NULL) return NULL; 212d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 213d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t memory_needed = calculate_camera_metadata_size(entry_capacity, 214d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala data_capacity); 215d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (memory_needed > dst_size) return NULL; 216d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 217d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala camera_metadata_t *metadata = (camera_metadata_t*)dst; 21894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala metadata->version = CURRENT_METADATA_VERSION; 21994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala metadata->flags = 0; 220d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala metadata->entry_count = 0; 221d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala metadata->entry_capacity = entry_capacity; 222b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala metadata->entries_start = 223b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala ALIGN_TO(sizeof(camera_metadata_t), ENTRY_ALIGNMENT); 224d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala metadata->data_count = 0; 225d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala metadata->data_capacity = data_capacity; 226d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala metadata->size = memory_needed; 227d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin size_t data_unaligned = (uint8_t*)(get_entries(metadata) + 228d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin metadata->entry_capacity) - (uint8_t*)metadata; 229d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin metadata->data_start = ALIGN_TO(data_unaligned, DATA_ALIGNMENT); 230d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 231151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(metadata, NULL) == OK); 232d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return metadata; 233d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 234d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalavoid free_camera_metadata(camera_metadata_t *metadata) { 235d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala free(metadata); 236d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 237d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 238d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_size(size_t entry_count, 239d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_count) { 240d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t memory_needed = sizeof(camera_metadata_t); 2413154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala // Start entry list at aligned boundary 2423154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala memory_needed = ALIGN_TO(memory_needed, ENTRY_ALIGNMENT); 243f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]); 2443154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala // Start buffer list at aligned boundary 2453154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala memory_needed = ALIGN_TO(memory_needed, DATA_ALIGNMENT); 246d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala memory_needed += sizeof(uint8_t[data_count]); 247d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return memory_needed; 248d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 249d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 250d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_size(const camera_metadata_t *metadata) { 251d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (metadata == NULL) return ERROR; 252d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 253d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return metadata->size; 254d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 255d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 256d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) { 257d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (metadata == NULL) return ERROR; 258d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 259d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return calculate_camera_metadata_size(metadata->entry_count, 260b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala metadata->data_count); 261d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 262d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 263d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) { 264d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return metadata->entry_count; 265d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 266d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 267d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) { 268d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return metadata->entry_capacity; 269d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 270d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 271d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_count(const camera_metadata_t *metadata) { 272d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return metadata->data_count; 273d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 274d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 275d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) { 276d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return metadata->data_capacity; 277d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 278d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 279d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size, 280d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala const camera_metadata_t *src) { 281d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t memory_needed = get_camera_metadata_compact_size(src); 282d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 283d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst == NULL) return NULL; 284d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst_size < memory_needed) return NULL; 285d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 286b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_t *metadata = 287b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala place_camera_metadata(dst, dst_size, src->entry_count, src->data_count); 288d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 28994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala metadata->flags = src->flags; 290d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala metadata->entry_count = src->entry_count; 291d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala metadata->data_count = src->data_count; 292d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 293b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala memcpy(get_entries(metadata), get_entries(src), 294f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala sizeof(camera_metadata_buffer_entry_t[metadata->entry_count])); 295b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala memcpy(get_data(metadata), get_data(src), 296d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala sizeof(uint8_t[metadata->data_count])); 297d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 298151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(metadata, NULL) == OK); 299d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return metadata; 300d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 301d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 302d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkinint validate_camera_metadata_structure(const camera_metadata_t *metadata, 303d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin const size_t *expected_size) { 304d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 305d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (metadata == NULL) { 306246a1adacce4854b91adc9635887453ba4f58e51Zhijun He ALOGE("%s: metadata is null!", __FUNCTION__); 307d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 308d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 309d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 310d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin // Check that the metadata pointer is well-aligned first. 311d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin { 31221532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath static const struct { 313d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin const char *name; 314d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin size_t alignment; 315d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } alignments[] = { 316d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin { 317d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin .name = "camera_metadata", 31821532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath .alignment = METADATA_ALIGNMENT 319d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin }, 320d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin { 321d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin .name = "camera_metadata_buffer_entry", 32221532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath .alignment = ENTRY_ALIGNMENT 323d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin }, 324d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin { 325d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin .name = "camera_metadata_data", 32621532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath .alignment = DATA_ALIGNMENT 327d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin }, 328d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin }; 329d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 330d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin for (size_t i = 0; i < sizeof(alignments)/sizeof(alignments[0]); ++i) { 331d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin uintptr_t aligned_ptr = ALIGN_TO(metadata, alignments[i].alignment); 332d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 333d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if ((uintptr_t)metadata != aligned_ptr) { 334d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin ALOGE("%s: Metadata pointer is not aligned (actual %p, " 335d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin "expected %p) to type %s", 336d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, metadata, 337d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin (void*)aligned_ptr, alignments[i].name); 338d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 339d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 340d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 341d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 342d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 343d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin /** 344d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin * Check that the metadata contents are correct 345d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin */ 346d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 347d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (expected_size != NULL && metadata->size > *expected_size) { 34821532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath ALOGE("%s: Metadata size (%" PRIu32 ") should be <= expected size (%zu)", 349d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, metadata->size, *expected_size); 350d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 351d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 352d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 353d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (metadata->entry_count > metadata->entry_capacity) { 35421532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath ALOGE("%s: Entry count (%" PRIu32 ") should be <= entry capacity " 35521532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath "(%" PRIu32 ")", 356d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, metadata->entry_count, metadata->entry_capacity); 357d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 358d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 359d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 36021532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath const metadata_uptrdiff_t entries_end = 36121532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata->entries_start + metadata->entry_capacity; 362d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (entries_end < metadata->entries_start || // overflow check 363d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin entries_end > metadata->data_start) { 364d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 36521532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath ALOGE("%s: Entry start + capacity (%" PRIu32 ") should be <= data start " 36621532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath "(%" PRIu32 ")", 367d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, 368d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin (metadata->entries_start + metadata->entry_capacity), 369d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin metadata->data_start); 370d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 371d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 372d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 37321532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath const metadata_uptrdiff_t data_end = 37421532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath metadata->data_start + metadata->data_capacity; 375d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (data_end < metadata->data_start || // overflow check 376d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin data_end > metadata->size) { 377d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 37821532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath ALOGE("%s: Data start + capacity (%" PRIu32 ") should be <= total size " 37921532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath "(%" PRIu32 ")", 380d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, 381d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin (metadata->data_start + metadata->data_capacity), 382d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin metadata->size); 383d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 384d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 385d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 386d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin // Validate each entry 38721532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath const metadata_size_t entry_count = metadata->entry_count; 388d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin camera_metadata_buffer_entry_t *entries = get_entries(metadata); 389d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 390d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin for (size_t i = 0; i < entry_count; ++i) { 391d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 392d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if ((uintptr_t)&entries[i] != ALIGN_TO(&entries[i], ENTRY_ALIGNMENT)) { 393773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn ALOGE("%s: Entry index %zu had bad alignment (address %p)," 394773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn " expected alignment %zu", 395d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, i, &entries[i], ENTRY_ALIGNMENT); 396d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 397d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 398d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 399d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin camera_metadata_buffer_entry_t entry = entries[i]; 400d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 401d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (entry.type >= NUM_TYPES) { 402773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn ALOGE("%s: Entry index %zu had a bad type %d", 403d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, i, entry.type); 404d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 405d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 406d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 407d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin // TODO: fix vendor_tag_ops across processes so we don't need to special 408d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin // case vendor-specific tags 409d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin uint32_t tag_section = entry.tag >> 16; 410d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin int tag_type = get_camera_metadata_tag_type(entry.tag); 411d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (tag_type != (int)entry.type && tag_section < VENDOR_SECTION) { 412773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn ALOGE("%s: Entry index %zu had tag type %d, but the type was %d", 413d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, i, tag_type, entry.type); 414d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 415d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 416d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 417d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin size_t data_size = 418d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin calculate_camera_metadata_entry_data_size(entry.type, 419d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin entry.count); 420d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 421d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (data_size != 0) { 422d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin camera_metadata_data_t *data = 423d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin (camera_metadata_data_t*) (get_data(metadata) + 424d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin entry.data.offset); 425d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 426d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if ((uintptr_t)data != ALIGN_TO(data, DATA_ALIGNMENT)) { 427773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn ALOGE("%s: Entry index %zu had bad data alignment (address %p)," 428773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn " expected align %zu, (tag name %s, data size %zu)", 429d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin __FUNCTION__, i, data, DATA_ALIGNMENT, 430d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin get_camera_metadata_tag_name(entry.tag) ?: "unknown", 431d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin data_size); 432d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 433d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 434d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 435d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin size_t data_entry_end = entry.data.offset + data_size; 436d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (data_entry_end < entry.data.offset || // overflow check 437d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin data_entry_end > metadata->data_capacity) { 438d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 439773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn ALOGE("%s: Entry index %zu data ends (%zu) beyond the capacity " 44021532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath "%" PRIu32, __FUNCTION__, i, data_entry_end, 441d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin metadata->data_capacity); 442d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 443d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 444d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 445d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } else if (entry.count == 0) { 446d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin if (entry.data.offset != 0) { 447773e5c8c23de85c100211911b0a5b2cb9733c58eMark Salyzyn ALOGE("%s: Entry index %zu had 0 items, but offset was non-0 " 44821532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath "(%" PRIu32 "), tag name: %s", __FUNCTION__, i, entry.data.offset, 4493064d31f5401b1727bf4c94b55d230615918ea9bZhijun He get_camera_metadata_tag_name(entry.tag) ?: "unknown"); 450d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return ERROR; 451d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 452d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } // else data stored inline, so we look at value which can be anything. 453d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin } 454d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 455d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin return OK; 456d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin} 457d1cecc16420d1e210b0643530e552e3427b2bab2Igor Murashkin 458d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint append_camera_metadata(camera_metadata_t *dst, 459d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala const camera_metadata_t *src) { 460d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst == NULL || src == NULL ) return ERROR; 461d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 462d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR; 463d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst->data_capacity < src->data_count + dst->data_count) return ERROR; 464d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 465b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala memcpy(get_entries(dst) + dst->entry_count, get_entries(src), 466f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala sizeof(camera_metadata_buffer_entry_t[src->entry_count])); 467b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala memcpy(get_data(dst) + dst->data_count, get_data(src), 468d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala sizeof(uint8_t[src->data_count])); 469d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst->data_count != 0) { 470b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count; 471b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala for (size_t i = 0; i < src->entry_count; i++, entry++) { 472b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala if ( calculate_camera_metadata_entry_data_size(entry->type, 473b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala entry->count) > 0 ) { 474d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry->data.offset += dst->data_count; 475d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 476d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 477d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 478f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (dst->entry_count == 0) { 479f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Appending onto empty buffer, keep sorted state 480f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala dst->flags |= src->flags & FLAG_SORTED; 481f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } else if (src->entry_count != 0) { 482f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Both src, dst are nonempty, cannot assume sort remains 483f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala dst->flags &= ~FLAG_SORTED; 484f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } else { 485f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Src is empty, keep dst sorted state 486f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 487d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala dst->entry_count += src->entry_count; 488d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala dst->data_count += src->data_count; 489d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 490151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(dst, NULL) == OK); 491d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return OK; 492d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 493d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 4942f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvalacamera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) { 495fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala int res; 4962f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala if (src == NULL) return NULL; 497fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala camera_metadata_t *clone = allocate_camera_metadata( 498fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala get_camera_metadata_entry_count(src), 499fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala get_camera_metadata_data_count(src)); 500fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala if (clone != NULL) { 501fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala res = append_camera_metadata(clone, src); 502fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala if (res != OK) { 503fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala free_camera_metadata(clone); 504fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala clone = NULL; 505fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala } 506fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala } 507151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(clone, NULL) == OK); 508fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala return clone; 509fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala} 510fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala 511d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_entry_data_size(uint8_t type, 512d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_count) { 513d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (type >= NUM_TYPES) return 0; 514d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_bytes = data_count * 515d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala camera_metadata_type_size[type]; 5163154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); 517d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 518d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 51994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int add_camera_metadata_entry_raw(camera_metadata_t *dst, 520d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag, 521d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint8_t type, 522d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala const void *data, 523d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_count) { 524d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 525d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst == NULL) return ERROR; 526d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (dst->entry_count == dst->entry_capacity) return ERROR; 5279e28b9f7b2f62d2c1870218f951f7345a13bed2fDavid Schalig if (data_count && data == NULL) return ERROR; 528d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 529d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_bytes = 530d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala calculate_camera_metadata_entry_data_size(type, data_count); 5313154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala if (data_bytes + dst->data_count > dst->data_capacity) return ERROR; 532d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 5333154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala size_t data_payload_bytes = 5343154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala data_count * camera_metadata_type_size[type]; 535b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count; 5363064d31f5401b1727bf4c94b55d230615918ea9bZhijun He memset(entry, 0, sizeof(camera_metadata_buffer_entry_t)); 537d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry->tag = tag; 538d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry->type = type; 539d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry->count = data_count; 540d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 541d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (data_bytes == 0) { 542d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala memcpy(entry->data.value, data, 5433154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala data_payload_bytes); 544d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } else { 545d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry->data.offset = dst->data_count; 546b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala memcpy(get_data(dst) + entry->data.offset, data, 5473154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala data_payload_bytes); 548d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala dst->data_count += data_bytes; 549d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 550d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala dst->entry_count++; 55194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala dst->flags &= ~FLAG_SORTED; 552151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(dst, NULL) == OK); 553d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return OK; 554d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 555d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 556d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint add_camera_metadata_entry(camera_metadata_t *dst, 557d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag, 558d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala const void *data, 559d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t data_count) { 560d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 561d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala int type = get_camera_metadata_tag_type(tag); 562d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (type == -1) { 56394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag); 564d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return ERROR; 565d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 566d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 567d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return add_camera_metadata_entry_raw(dst, 568d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag, 569d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala type, 570d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala data, 571d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala data_count); 572d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 573d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 57494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int compare_entry_tags(const void *p1, const void *p2) { 575f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag; 576f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag; 57794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala return tag1 < tag2 ? -1 : 57894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala tag1 == tag2 ? 0 : 57994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 1; 58094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala} 58194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 58294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint sort_camera_metadata(camera_metadata_t *dst) { 58394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala if (dst == NULL) return ERROR; 58494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala if (dst->flags & FLAG_SORTED) return OK; 58594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 586b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala qsort(get_entries(dst), dst->entry_count, 587f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala sizeof(camera_metadata_buffer_entry_t), 58894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala compare_entry_tags); 58994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala dst->flags |= FLAG_SORTED; 59094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 591151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(dst, NULL) == OK); 59294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala return OK; 59394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala} 59494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 595d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_entry(camera_metadata_t *src, 596f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t index, 597f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala camera_metadata_entry_t *entry) { 598f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (src == NULL || entry == NULL) return ERROR; 599d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (index >= src->entry_count) return ERROR; 600d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 601b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index; 602d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 603f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->index = index; 604f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->tag = buffer_entry->tag; 605f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->type = buffer_entry->type; 606f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->count = buffer_entry->count; 607f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (buffer_entry->count * 608f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala camera_metadata_type_size[buffer_entry->type] > 4) { 609b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala entry->data.u8 = get_data(src) + buffer_entry->data.offset; 610f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } else { 611f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->data.u8 = buffer_entry->data.value; 61294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala } 61394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala return OK; 61494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala} 61594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 61671fe0f87dd5339a93ab2f376ca50568d45de617cAlex Rayint get_camera_metadata_ro_entry(const camera_metadata_t *src, 61771fe0f87dd5339a93ab2f376ca50568d45de617cAlex Ray size_t index, 61871fe0f87dd5339a93ab2f376ca50568d45de617cAlex Ray camera_metadata_ro_entry_t *entry) { 61971fe0f87dd5339a93ab2f376ca50568d45de617cAlex Ray return get_camera_metadata_entry((camera_metadata_t*)src, index, 62071fe0f87dd5339a93ab2f376ca50568d45de617cAlex Ray (camera_metadata_entry_t*)entry); 62171fe0f87dd5339a93ab2f376ca50568d45de617cAlex Ray} 62271fe0f87dd5339a93ab2f376ca50568d45de617cAlex Ray 62394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint find_camera_metadata_entry(camera_metadata_t *src, 62494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala uint32_t tag, 625f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala camera_metadata_entry_t *entry) { 62694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala if (src == NULL) return ERROR; 62794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala 628f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala uint32_t index; 62994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala if (src->flags & FLAG_SORTED) { 63094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala // Sorted entries, do a binary search 631f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala camera_metadata_buffer_entry_t *search_entry = NULL; 632f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala camera_metadata_buffer_entry_t key; 63394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala key.tag = tag; 634f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala search_entry = bsearch(&key, 635b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala get_entries(src), 63694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala src->entry_count, 637f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala sizeof(camera_metadata_buffer_entry_t), 63894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala compare_entry_tags); 639f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (search_entry == NULL) return NOT_FOUND; 640b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala index = search_entry - get_entries(src); 641d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } else { 64294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala // Not sorted, linear search 643b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *search_entry = get_entries(src); 644b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala for (index = 0; index < src->entry_count; index++, search_entry++) { 645b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala if (search_entry->tag == tag) { 64694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala break; 64794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala } 64894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala } 649f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (index == src->entry_count) return NOT_FOUND; 65094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala } 651f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 652f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala return get_camera_metadata_entry(src, index, 653f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry); 654f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala} 655f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 6562f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvalaint find_camera_metadata_ro_entry(const camera_metadata_t *src, 6572f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala uint32_t tag, 6582f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala camera_metadata_ro_entry_t *entry) { 6592f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala return find_camera_metadata_entry((camera_metadata_t*)src, tag, 6602f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala (camera_metadata_entry_t*)entry); 6612f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala} 6622f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala 6632f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala 664f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint delete_camera_metadata_entry(camera_metadata_t *dst, 665f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t index) { 666f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (dst == NULL) return ERROR; 667f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (index >= dst->entry_count) return ERROR; 668f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 669b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *entry = get_entries(dst) + index; 670f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type, 671f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->count); 672f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 673f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (data_bytes > 0) { 674f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Shift data buffer to overwrite deleted data 675b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala uint8_t *start = get_data(dst) + entry->data.offset; 676f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala uint8_t *end = start + data_bytes; 677f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t length = dst->data_count - entry->data.offset - data_bytes; 678f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala memmove(start, end, length); 679f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 680f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Update all entry indices to account for shift 681b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *e = get_entries(dst); 682f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t i; 683f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala for (i = 0; i < dst->entry_count; i++) { 684f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (calculate_camera_metadata_entry_data_size( 685f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala e->type, e->count) > 0 && 686f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala e->data.offset > entry->data.offset) { 687f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala e->data.offset -= data_bytes; 688f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 689f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala ++e; 69094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala } 691f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala dst->data_count -= data_bytes; 692d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 693f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Shift entry array 694f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala memmove(entry, entry + 1, 695f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala sizeof(camera_metadata_buffer_entry_t) * 696f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala (dst->entry_count - index - 1) ); 697f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala dst->entry_count -= 1; 698f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 699151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(dst, NULL) == OK); 700f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala return OK; 701f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala} 702f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 703f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint update_camera_metadata_entry(camera_metadata_t *dst, 704f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t index, 705f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala const void *data, 706f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t data_count, 707f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala camera_metadata_entry_t *updated_entry) { 708f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (dst == NULL) return ERROR; 709f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (index >= dst->entry_count) return ERROR; 710f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 711b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *entry = get_entries(dst) + index; 712f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 713f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t data_bytes = 714f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala calculate_camera_metadata_entry_data_size(entry->type, 715f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala data_count); 7163154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala size_t data_payload_bytes = 7173154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala data_count * camera_metadata_type_size[entry->type]; 7183154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala 719f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t entry_bytes = 720f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala calculate_camera_metadata_entry_data_size(entry->type, 721f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->count); 722f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (data_bytes != entry_bytes) { 723f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // May need to shift/add to data array 724f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) { 725f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // No room 726f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala return ERROR; 727f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 728f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (entry_bytes != 0) { 729f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Remove old data 730b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala uint8_t *start = get_data(dst) + entry->data.offset; 731f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala uint8_t *end = start + entry_bytes; 732f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t length = dst->data_count - entry->data.offset - entry_bytes; 733f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala memmove(start, end, length); 734f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala dst->data_count -= entry_bytes; 735f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 736f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Update all entry indices to account for shift 737b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *e = get_entries(dst); 738f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala size_t i; 739f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala for (i = 0; i < dst->entry_count; i++) { 740f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (calculate_camera_metadata_entry_data_size( 741f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala e->type, e->count) > 0 && 742f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala e->data.offset > entry->data.offset) { 743f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala e->data.offset -= entry_bytes; 744f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 745f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala ++e; 746f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 747f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 748f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 749f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (data_bytes != 0) { 750f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Append new data 751f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->data.offset = dst->data_count; 752f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 753b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes); 754f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala dst->data_count += data_bytes; 755f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 756f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } else if (data_bytes != 0) { 757f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // data size unchanged, reuse same data location 758b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes); 759f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 760f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 761f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (data_bytes == 0) { 762f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala // Data fits into entry 763f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala memcpy(entry->data.value, data, 7643154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala data_payload_bytes); 765f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 766f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 767f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala entry->count = data_count; 768f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 769f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala if (updated_entry != NULL) { 770f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala get_camera_metadata_entry(dst, 771f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala index, 772f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala updated_entry); 773f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala } 774f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala 775151389f386c45ff23ca5e2df4c3aaeb1fde3c496Alex Ray assert(validate_camera_metadata_structure(dst, NULL) == OK); 776d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return OK; 777d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 778d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 7799c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunkstatic const vendor_tag_ops_t *vendor_tag_ops = NULL; 780d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 781d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_section_name(uint32_t tag) { 782d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag_section = tag >> 16; 783d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) { 7849c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk return vendor_tag_ops->get_section_name( 78594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala vendor_tag_ops, 78694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala tag); 787d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 788d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_section >= ANDROID_SECTION_COUNT) { 789d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return NULL; 790d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 791d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return camera_metadata_section_names[tag_section]; 792d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 793d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 794d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_tag_name(uint32_t tag) { 795d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag_section = tag >> 16; 796d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) { 7979c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk return vendor_tag_ops->get_tag_name( 79894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala vendor_tag_ops, 79994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala tag); 800d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 801d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_section >= ANDROID_SECTION_COUNT || 802d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag >= camera_metadata_section_bounds[tag_section][1] ) { 803d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return NULL; 804d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 805d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag_index = tag & 0xFFFF; 806d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return tag_info[tag_section][tag_index].tag_name; 807d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 808d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 809d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_tag_type(uint32_t tag) { 810d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag_section = tag >> 16; 811d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) { 8129c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk return vendor_tag_ops->get_tag_type( 81394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala vendor_tag_ops, 81494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala tag); 815d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 816d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_section >= ANDROID_SECTION_COUNT || 817d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag >= camera_metadata_section_bounds[tag_section][1] ) { 818d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return -1; 819d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 820d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint32_t tag_index = tag & 0xFFFF; 821d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return tag_info[tag_section][tag_index].tag_type; 822d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 823d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 8249c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunkint set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t* ops) { 8259c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk // **DEPRECATED** 826aa7948f4cba3db04dd42586f5d06711f443e0c56Eino-Ville Talvala (void) ops; 8279c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk ALOGE("%s: This function has been deprecated", __FUNCTION__); 8289c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk return ERROR; 8299c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk} 8309c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk 8319c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk// Declared in system/media/private/camera/include/camera_metadata_hidden.h 8329c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunkint set_camera_metadata_vendor_ops(const vendor_tag_ops_t* ops) { 8339c13e191ea2d9622d00621d6acb009a9a759dc92Ruben Brunk vendor_tag_ops = ops; 834d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return OK; 835d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 836d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 837375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkinstatic void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type, 838375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin int count, 8391d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala int indentation); 840d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 84194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalavoid dump_camera_metadata(const camera_metadata_t *metadata, 84294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala int fd, 84394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala int verbosity) { 8441d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala dump_indented_camera_metadata(metadata, fd, verbosity, 0); 8451d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala} 8461d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala 8471d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvalavoid dump_indented_camera_metadata(const camera_metadata_t *metadata, 8481d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala int fd, 8491d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala int verbosity, 8501d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala int indentation) { 851d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (metadata == NULL) { 8528e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%*sDumping camera metadata array: Not allocated\n", 8532f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala indentation, ""); 854d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala return; 855d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 856d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala unsigned int i; 8578e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, 85821532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath "%*sDumping camera metadata array: %" PRIu32 " / %" PRIu32 " entries, " 85921532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath "%" PRIu32 " / %" PRIu32 " bytes of extra data.\n", indentation, "", 8601d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala metadata->entry_count, metadata->entry_capacity, 8611d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala metadata->data_count, metadata->data_capacity); 8628e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%*sVersion: %d, Flags: %08x\n", 8631d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala indentation + 2, "", 86494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala metadata->version, metadata->flags); 865b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala camera_metadata_buffer_entry_t *entry = get_entries(metadata); 866b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala for (i=0; i < metadata->entry_count; i++, entry++) { 867d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 868d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala const char *tag_name, *tag_section; 869d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag_section = get_camera_metadata_section_name(entry->tag); 870d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_section == NULL) { 871d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag_section = "unknownSection"; 872d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 873d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag_name = get_camera_metadata_tag_name(entry->tag); 874d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (tag_name == NULL) { 875d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag_name = "unknownTag"; 876d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 877d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala const char *type_name; 878d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (entry->type >= NUM_TYPES) { 879d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala type_name = "unknown"; 880d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } else { 881d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala type_name = camera_metadata_type_names[entry->type]; 882d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 88321532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath dprintf(fd, "%*s%s.%s (%05x): %s[%" PRIu32 "]\n", 8841d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala indentation + 2, "", 885d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag_section, 886d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala tag_name, 887d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry->tag, 888d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala type_name, 889d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala entry->count); 890d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 891d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (verbosity < 1) continue; 892d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 893d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (entry->type >= NUM_TYPES) continue; 894d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 895d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t type_size = camera_metadata_type_size[entry->type]; 896d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala uint8_t *data_ptr; 897d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if ( type_size * entry->count > 4 ) { 898d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (entry->data.offset >= metadata->data_count) { 89921532655a531cf1168f10b8b974e2cef3061dd91Narayan Kamath ALOGE("%s: Malformed entry data offset: %" PRIu32 " (max %" PRIu32 ")", 90094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala __FUNCTION__, 90194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala entry->data.offset, 90294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala metadata->data_count); 903d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala continue; 904d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 905b10d56ad43a91924d3666127963e5fdce725389cEino-Ville Talvala data_ptr = get_data(metadata) + entry->data.offset; 906d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } else { 907d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala data_ptr = entry->data.value; 908d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 909d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala int count = entry->count; 910d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (verbosity < 2 && count > 16) count = 16; 911d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 912375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin print_data(fd, data_ptr, entry->tag, entry->type, count, indentation); 913d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 914d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 915d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 916375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkinstatic void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, 9171d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala int type, int count, int indentation) { 918d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala static int values_per_line[NUM_TYPES] = { 919d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_BYTE] = 16, 920d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_INT32] = 4, 921d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_FLOAT] = 8, 922d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_INT64] = 2, 923d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_DOUBLE] = 4, 924d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala [TYPE_RATIONAL] = 2, 925d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala }; 926d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala size_t type_size = camera_metadata_type_size[type]; 927375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE]; 928375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin uint32_t value; 929d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 930d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala int lines = count / values_per_line[type]; 931d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala if (count % values_per_line[type] != 0) lines++; 932d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 933d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala int index = 0; 934d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala int j, k; 935d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala for (j = 0; j < lines; j++) { 9368e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%*s[", indentation + 4, ""); 937d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala for (k = 0; 938d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala k < values_per_line[type] && count > 0; 939d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala k++, count--, index += type_size) { 940d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala 941d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala switch (type) { 942d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala case TYPE_BYTE: 943375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin value = *(data_ptr + index); 944375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin if (camera_metadata_enum_snprint(tag, 945375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin value, 946375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin value_string_tmp, 947375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin sizeof(value_string_tmp)) 948375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin == OK) { 9498e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%s ", value_string_tmp); 950375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin } else { 9518e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%hhu ", 952375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin *(data_ptr + index)); 953375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin } 954d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala break; 955d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala case TYPE_INT32: 956375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin value = 957375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin *(int32_t*)(data_ptr + index); 958375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin if (camera_metadata_enum_snprint(tag, 959375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin value, 960375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin value_string_tmp, 961375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin sizeof(value_string_tmp)) 962375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin == OK) { 9638e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%s ", value_string_tmp); 964375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin } else { 9658e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%" PRId32 " ", 966375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin *(int32_t*)(data_ptr + index)); 967375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin } 968d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala break; 969d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala case TYPE_FLOAT: 970d1c3357af4bebf3d867761d826351ce7669fefc7Elliott Hughes dprintf(fd, "%0.8f ", 971d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *(float*)(data_ptr + index)); 972d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala break; 973d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala case TYPE_INT64: 9748e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "%" PRId64 " ", 975d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *(int64_t*)(data_ptr + index)); 976d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala break; 977d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala case TYPE_DOUBLE: 978d1c3357af4bebf3d867761d826351ce7669fefc7Elliott Hughes dprintf(fd, "%0.8f ", 9793154036acd2cc809388d08ff856198a8512f05f0Eino-Ville Talvala *(double*)(data_ptr + index)); 980d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala break; 981d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala case TYPE_RATIONAL: { 982d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala int32_t numerator = *(int32_t*)(data_ptr + index); 983d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala int32_t denominator = *(int32_t*)(data_ptr + index + 4); 9848e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "(%d / %d) ", 985d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala numerator, denominator); 986d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala break; 987d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 988d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala default: 9898e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "??? "); 990d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 991d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 9928e86c9c609a65563aa1b2f17423e69eabc6268c3Elliott Hughes dprintf(fd, "]\n"); 993d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala } 994d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} 995