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