CameraMetadata.cpp revision cab96a4a7a2900fa991ab77ae45ba8d4be97e054
1e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala/* 2e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project 3e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * 4e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 5e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * you may not use this file except in compliance with the License. 6e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * You may obtain a copy of the License at 7e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * 8e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 9e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * 10e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 11e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 12e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * See the License for the specific language governing permissions and 14e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * limitations under the License. 15e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala */ 16e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 17e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#define LOG_TAG "CameraMetadata" 18e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#include <utils/Log.h> 19e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#include <utils/Errors.h> 20f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala 21e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#include "CameraMetadata.h" 22e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 23e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalanamespace android { 24e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 25e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::CameraMetadata() : 26e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala mBuffer(NULL) { 27e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 28e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 29e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) 30e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala{ 31e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); 32e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 33e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 34e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::CameraMetadata(const CameraMetadata &other) { 35e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala mBuffer = clone_camera_metadata(other.mBuffer); 36e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 37e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 38e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { 39e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala return operator=(other.mBuffer); 40f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala} 41e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 42e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { 43f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala if (CC_LIKELY(buffer != mBuffer)) { 44e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala camera_metadata_t *newBuffer = clone_camera_metadata(buffer); 45e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala clear(); 46e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala mBuffer = newBuffer; 47e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala } 48e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala return *this; 49e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 50e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 51e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::~CameraMetadata() { 52e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala clear(); 53e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 54e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 55e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalacamera_metadata_t* CameraMetadata::release() { 56e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala camera_metadata_t *released = mBuffer; 57e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala mBuffer = NULL; 58e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala return released; 59e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 60e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 61e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalavoid CameraMetadata::clear() { 62e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala if (mBuffer) { 63e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala free_camera_metadata(mBuffer); 64e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala mBuffer = NULL; 65e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala } 66e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 67e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 68e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalavoid CameraMetadata::acquire(camera_metadata_t *buffer) { 69e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala clear(); 70e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala mBuffer = buffer; 71e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 72e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 73e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalavoid CameraMetadata::acquire(CameraMetadata &other) { 74e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala acquire(other.release()); 75e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 76e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 77e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CameraMetadata::append(const CameraMetadata &other) { 78e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala return append_camera_metadata(mBuffer, other.mBuffer); 79e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 80e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 81e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalasize_t CameraMetadata::entryCount() const { 82e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala return (mBuffer == NULL) ? 0 : 83e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala get_camera_metadata_entry_count(mBuffer); 84e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 85f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala 86e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CameraMetadata::sort() { 87e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala return sort_camera_metadata(mBuffer); 88e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala} 89e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala 90e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { 91e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala int tagType = get_camera_metadata_tag_type(tag); 92e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala if ( CC_UNLIKELY(tagType == -1)) { 93e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala ALOGE("Update metadata entry: Unknown tag %d", tag); 94f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala return INVALID_OPERATION; 95e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala } 96e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala if ( CC_UNLIKELY(tagType != expectedType) ) { 97e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " 98e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala "got type %s data instead ", 99e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala get_camera_metadata_tag_name(tag), tag, 100e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala camera_metadata_type_names[tagType], 101e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala camera_metadata_type_names[expectedType]); 102e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala return INVALID_OPERATION; 103e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala } 104 return OK; 105} 106 107status_t CameraMetadata::update(uint32_t tag, 108 const int32_t *data, size_t data_count) { 109 status_t res; 110 if ( (res = checkType(tag, TYPE_INT32)) != OK) { 111 return res; 112 } 113 return update(tag, (const void*)data, data_count); 114} 115 116status_t CameraMetadata::update(uint32_t tag, 117 const uint8_t *data, size_t data_count) { 118 status_t res; 119 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 120 return res; 121 } 122 return update(tag, (const void*)data, data_count); 123} 124 125status_t CameraMetadata::update(uint32_t tag, 126 const float *data, size_t data_count) { 127 status_t res; 128 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { 129 return res; 130 } 131 return update(tag, (const void*)data, data_count); 132} 133 134status_t CameraMetadata::update(uint32_t tag, 135 const int64_t *data, size_t data_count) { 136 status_t res; 137 if ( (res = checkType(tag, TYPE_INT64)) != OK) { 138 return res; 139 } 140 return update(tag, (const void*)data, data_count); 141} 142 143status_t CameraMetadata::update(uint32_t tag, 144 const double *data, size_t data_count) { 145 status_t res; 146 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { 147 return res; 148 } 149 return update(tag, (const void*)data, data_count); 150} 151 152status_t CameraMetadata::update(uint32_t tag, 153 const camera_metadata_rational_t *data, size_t data_count) { 154 status_t res; 155 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { 156 return res; 157 } 158 return update(tag, (const void*)data, data_count); 159} 160 161status_t CameraMetadata::update(uint32_t tag, 162 const String8 &string) { 163 status_t res; 164 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 165 return res; 166 } 167 return update(tag, (const void*)string.string(), string.size()); 168} 169 170status_t CameraMetadata::update(uint32_t tag, const void *data, 171 size_t data_count) { 172 status_t res; 173 int type = get_camera_metadata_tag_type(tag); 174 if (type == -1) { 175 ALOGE("%s: Tag %d not found", __FUNCTION__, tag); 176 return BAD_VALUE; 177 } 178 size_t data_size = calculate_camera_metadata_entry_data_size(type, 179 data_count); 180 181 res = resizeIfNeeded(1, data_size); 182 183 if (res == OK) { 184 camera_metadata_entry_t entry; 185 res = find_camera_metadata_entry(mBuffer, tag, &entry); 186 if (res == NAME_NOT_FOUND) { 187 res = add_camera_metadata_entry(mBuffer, 188 tag, data, data_count); 189 } else if (res == OK) { 190 res = update_camera_metadata_entry(mBuffer, 191 entry.index, data, data_count, NULL); 192 } 193 } 194 195 if (res != OK) { 196 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", 197 __FUNCTION__, get_camera_metadata_section_name(tag), 198 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 199 } 200 return res; 201} 202 203camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { 204 status_t res; 205 camera_metadata_entry entry; 206 res = find_camera_metadata_entry(mBuffer, tag, &entry); 207 if (CC_UNLIKELY( res != OK )) { 208 entry.count = 0; 209 entry.data.u8 = NULL; 210 } 211 return entry; 212} 213 214camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { 215 status_t res; 216 camera_metadata_ro_entry entry; 217 res = find_camera_metadata_ro_entry(mBuffer, tag, &entry); 218 if (CC_UNLIKELY( res != OK )) { 219 entry.count = 0; 220 entry.data.u8 = NULL; 221 } 222 return entry; 223} 224 225status_t CameraMetadata::erase(uint32_t tag) { 226 camera_metadata_entry_t entry; 227 status_t res; 228 res = find_camera_metadata_entry(mBuffer, tag, &entry); 229 if (res == NAME_NOT_FOUND) { 230 return OK; 231 } else if (res != OK) { 232 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", 233 __FUNCTION__, 234 get_camera_metadata_section_name(tag), 235 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 236 return res; 237 } 238 res = delete_camera_metadata_entry(mBuffer, entry.index); 239 if (res != OK) { 240 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", 241 __FUNCTION__, 242 get_camera_metadata_section_name(tag), 243 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 244 } 245 return res; 246} 247 248void CameraMetadata::dump(int fd, int verbosity, int indentation) const { 249 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation); 250} 251 252status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { 253 if (mBuffer == NULL) { 254 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); 255 if (mBuffer == NULL) { 256 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 257 return NO_MEMORY; 258 } 259 } else { 260 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); 261 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); 262 size_t newEntryCount = currentEntryCount + 263 extraEntries; 264 newEntryCount = (newEntryCount > currentEntryCap) ? 265 newEntryCount * 2 : currentEntryCap; 266 267 size_t currentDataCount = get_camera_metadata_data_count(mBuffer); 268 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); 269 size_t newDataCount = currentDataCount + 270 extraData; 271 newDataCount = (newDataCount > currentDataCap) ? 272 newDataCount * 2 : currentDataCap; 273 274 if (newEntryCount > currentEntryCap || 275 newDataCount > currentDataCap) { 276 camera_metadata_t *oldBuffer = mBuffer; 277 mBuffer = allocate_camera_metadata(newEntryCount, 278 newDataCount); 279 if (mBuffer == NULL) { 280 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 281 return NO_MEMORY; 282 } 283 append_camera_metadata(mBuffer, oldBuffer); 284 free_camera_metadata(oldBuffer); 285 } 286 } 287 return OK; 288} 289 290}; // namespace android 291