CameraMetadata.cpp revision f76e027c43f531fc6f9287838b5c332236a4338a
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Camera2-Metadata" 18#include <utils/Log.h> 19#include <utils/Errors.h> 20 21#include <camera/CameraMetadata.h> 22 23namespace android { 24 25CameraMetadata::CameraMetadata() : 26 mBuffer(NULL), mLocked(false) { 27} 28 29CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : 30 mLocked(false) 31{ 32 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); 33} 34 35CameraMetadata::CameraMetadata(const CameraMetadata &other) : 36 mLocked(false) { 37 mBuffer = clone_camera_metadata(other.mBuffer); 38} 39 40CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : 41 mBuffer(NULL), mLocked(false) { 42 acquire(buffer); 43} 44 45CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { 46 return operator=(other.mBuffer); 47} 48 49CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { 50 if (mLocked) { 51 ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__); 52 return *this; 53 } 54 55 if (CC_LIKELY(buffer != mBuffer)) { 56 camera_metadata_t *newBuffer = clone_camera_metadata(buffer); 57 clear(); 58 mBuffer = newBuffer; 59 } 60 return *this; 61} 62 63CameraMetadata::~CameraMetadata() { 64 mLocked = false; 65 clear(); 66} 67 68const camera_metadata_t* CameraMetadata::getAndLock() { 69 mLocked = true; 70 return mBuffer; 71} 72 73status_t CameraMetadata::unlock(const camera_metadata_t *buffer) { 74 if (!mLocked) { 75 ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__); 76 return INVALID_OPERATION; 77 } 78 if (buffer != mBuffer) { 79 ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", 80 __FUNCTION__); 81 return BAD_VALUE; 82 } 83 mLocked = false; 84 return OK; 85} 86 87camera_metadata_t* CameraMetadata::release() { 88 if (mLocked) { 89 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 90 return NULL; 91 } 92 camera_metadata_t *released = mBuffer; 93 mBuffer = NULL; 94 return released; 95} 96 97void CameraMetadata::clear() { 98 if (mLocked) { 99 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 100 return; 101 } 102 if (mBuffer) { 103 free_camera_metadata(mBuffer); 104 mBuffer = NULL; 105 } 106} 107 108void CameraMetadata::acquire(camera_metadata_t *buffer) { 109 if (mLocked) { 110 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 111 return; 112 } 113 clear(); 114 mBuffer = buffer; 115} 116 117void CameraMetadata::acquire(CameraMetadata &other) { 118 if (mLocked) { 119 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 120 return; 121 } 122 acquire(other.release()); 123} 124 125status_t CameraMetadata::append(const CameraMetadata &other) { 126 if (mLocked) { 127 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 128 return INVALID_OPERATION; 129 } 130 return append_camera_metadata(mBuffer, other.mBuffer); 131} 132 133size_t CameraMetadata::entryCount() const { 134 return (mBuffer == NULL) ? 0 : 135 get_camera_metadata_entry_count(mBuffer); 136} 137 138bool CameraMetadata::isEmpty() const { 139 return entryCount() == 0; 140} 141 142status_t CameraMetadata::sort() { 143 if (mLocked) { 144 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 145 return INVALID_OPERATION; 146 } 147 return sort_camera_metadata(mBuffer); 148} 149 150status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { 151 int tagType = get_camera_metadata_tag_type(tag); 152 if ( CC_UNLIKELY(tagType == -1)) { 153 ALOGE("Update metadata entry: Unknown tag %d", tag); 154 return INVALID_OPERATION; 155 } 156 if ( CC_UNLIKELY(tagType != expectedType) ) { 157 ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " 158 "got type %s data instead ", 159 get_camera_metadata_tag_name(tag), tag, 160 camera_metadata_type_names[tagType], 161 camera_metadata_type_names[expectedType]); 162 return INVALID_OPERATION; 163 } 164 return OK; 165} 166 167status_t CameraMetadata::update(uint32_t tag, 168 const int32_t *data, size_t data_count) { 169 status_t res; 170 if (mLocked) { 171 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 172 return INVALID_OPERATION; 173 } 174 if ( (res = checkType(tag, TYPE_INT32)) != OK) { 175 return res; 176 } 177 return updateImpl(tag, (const void*)data, data_count); 178} 179 180status_t CameraMetadata::update(uint32_t tag, 181 const uint8_t *data, size_t data_count) { 182 status_t res; 183 if (mLocked) { 184 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 185 return INVALID_OPERATION; 186 } 187 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 188 return res; 189 } 190 return updateImpl(tag, (const void*)data, data_count); 191} 192 193status_t CameraMetadata::update(uint32_t tag, 194 const float *data, size_t data_count) { 195 status_t res; 196 if (mLocked) { 197 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 198 return INVALID_OPERATION; 199 } 200 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { 201 return res; 202 } 203 return updateImpl(tag, (const void*)data, data_count); 204} 205 206status_t CameraMetadata::update(uint32_t tag, 207 const int64_t *data, size_t data_count) { 208 status_t res; 209 if (mLocked) { 210 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 211 return INVALID_OPERATION; 212 } 213 if ( (res = checkType(tag, TYPE_INT64)) != OK) { 214 return res; 215 } 216 return updateImpl(tag, (const void*)data, data_count); 217} 218 219status_t CameraMetadata::update(uint32_t tag, 220 const double *data, size_t data_count) { 221 status_t res; 222 if (mLocked) { 223 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 224 return INVALID_OPERATION; 225 } 226 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { 227 return res; 228 } 229 return updateImpl(tag, (const void*)data, data_count); 230} 231 232status_t CameraMetadata::update(uint32_t tag, 233 const camera_metadata_rational_t *data, size_t data_count) { 234 status_t res; 235 if (mLocked) { 236 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 237 return INVALID_OPERATION; 238 } 239 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { 240 return res; 241 } 242 return updateImpl(tag, (const void*)data, data_count); 243} 244 245status_t CameraMetadata::update(uint32_t tag, 246 const String8 &string) { 247 status_t res; 248 if (mLocked) { 249 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 250 return INVALID_OPERATION; 251 } 252 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 253 return res; 254 } 255 return updateImpl(tag, (const void*)string.string(), string.size()); 256} 257 258status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, 259 size_t data_count) { 260 status_t res; 261 if (mLocked) { 262 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 263 return INVALID_OPERATION; 264 } 265 int type = get_camera_metadata_tag_type(tag); 266 if (type == -1) { 267 ALOGE("%s: Tag %d not found", __FUNCTION__, tag); 268 return BAD_VALUE; 269 } 270 size_t data_size = calculate_camera_metadata_entry_data_size(type, 271 data_count); 272 273 res = resizeIfNeeded(1, data_size); 274 275 if (res == OK) { 276 camera_metadata_entry_t entry; 277 res = find_camera_metadata_entry(mBuffer, tag, &entry); 278 if (res == NAME_NOT_FOUND) { 279 res = add_camera_metadata_entry(mBuffer, 280 tag, data, data_count); 281 } else if (res == OK) { 282 res = update_camera_metadata_entry(mBuffer, 283 entry.index, data, data_count, NULL); 284 } 285 } 286 287 if (res != OK) { 288 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", 289 __FUNCTION__, get_camera_metadata_section_name(tag), 290 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 291 } 292 return res; 293} 294 295bool CameraMetadata::exists(uint32_t tag) const { 296 camera_metadata_ro_entry entry; 297 return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0; 298} 299 300camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { 301 status_t res; 302 camera_metadata_entry entry; 303 if (mLocked) { 304 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 305 entry.count = 0; 306 return entry; 307 } 308 res = find_camera_metadata_entry(mBuffer, tag, &entry); 309 if (CC_UNLIKELY( res != OK )) { 310 entry.count = 0; 311 entry.data.u8 = NULL; 312 } 313 return entry; 314} 315 316camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { 317 status_t res; 318 camera_metadata_ro_entry entry; 319 res = find_camera_metadata_ro_entry(mBuffer, tag, &entry); 320 if (CC_UNLIKELY( res != OK )) { 321 entry.count = 0; 322 entry.data.u8 = NULL; 323 } 324 return entry; 325} 326 327status_t CameraMetadata::erase(uint32_t tag) { 328 camera_metadata_entry_t entry; 329 status_t res; 330 if (mLocked) { 331 ALOGE("%s: CameraMetadata is locked", __FUNCTION__); 332 return INVALID_OPERATION; 333 } 334 res = find_camera_metadata_entry(mBuffer, tag, &entry); 335 if (res == NAME_NOT_FOUND) { 336 return OK; 337 } else if (res != OK) { 338 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", 339 __FUNCTION__, 340 get_camera_metadata_section_name(tag), 341 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 342 return res; 343 } 344 res = delete_camera_metadata_entry(mBuffer, entry.index); 345 if (res != OK) { 346 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", 347 __FUNCTION__, 348 get_camera_metadata_section_name(tag), 349 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 350 } 351 return res; 352} 353 354void CameraMetadata::dump(int fd, int verbosity, int indentation) const { 355 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation); 356} 357 358status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { 359 if (mBuffer == NULL) { 360 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); 361 if (mBuffer == NULL) { 362 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 363 return NO_MEMORY; 364 } 365 } else { 366 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); 367 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); 368 size_t newEntryCount = currentEntryCount + 369 extraEntries; 370 newEntryCount = (newEntryCount > currentEntryCap) ? 371 newEntryCount * 2 : currentEntryCap; 372 373 size_t currentDataCount = get_camera_metadata_data_count(mBuffer); 374 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); 375 size_t newDataCount = currentDataCount + 376 extraData; 377 newDataCount = (newDataCount > currentDataCap) ? 378 newDataCount * 2 : currentDataCap; 379 380 if (newEntryCount > currentEntryCap || 381 newDataCount > currentDataCap) { 382 camera_metadata_t *oldBuffer = mBuffer; 383 mBuffer = allocate_camera_metadata(newEntryCount, 384 newDataCount); 385 if (mBuffer == NULL) { 386 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 387 return NO_MEMORY; 388 } 389 append_camera_metadata(mBuffer, oldBuffer); 390 free_camera_metadata(oldBuffer); 391 } 392 } 393 return OK; 394} 395 396}; // namespace android 397