CameraMetadata.cpp revision bd02dd1bf1f34eb4e100d0d058f1fe5a2790d67e
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) { 27} 28 29CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) 30{ 31 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); 32} 33 34CameraMetadata::CameraMetadata(const CameraMetadata &other) { 35 mBuffer = clone_camera_metadata(other.mBuffer); 36} 37 38CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : mBuffer(NULL) { 39 acquire(buffer); 40} 41 42CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { 43 return operator=(other.mBuffer); 44} 45 46CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { 47 if (CC_LIKELY(buffer != mBuffer)) { 48 camera_metadata_t *newBuffer = clone_camera_metadata(buffer); 49 clear(); 50 mBuffer = newBuffer; 51 } 52 return *this; 53} 54 55CameraMetadata::~CameraMetadata() { 56 clear(); 57} 58 59camera_metadata_t* CameraMetadata::release() { 60 camera_metadata_t *released = mBuffer; 61 mBuffer = NULL; 62 return released; 63} 64 65void CameraMetadata::clear() { 66 if (mBuffer) { 67 free_camera_metadata(mBuffer); 68 mBuffer = NULL; 69 } 70} 71 72void CameraMetadata::acquire(camera_metadata_t *buffer) { 73 clear(); 74 mBuffer = buffer; 75} 76 77void CameraMetadata::acquire(CameraMetadata &other) { 78 acquire(other.release()); 79} 80 81status_t CameraMetadata::append(const CameraMetadata &other) { 82 return append_camera_metadata(mBuffer, other.mBuffer); 83} 84 85size_t CameraMetadata::entryCount() const { 86 return (mBuffer == NULL) ? 0 : 87 get_camera_metadata_entry_count(mBuffer); 88} 89 90bool CameraMetadata::isEmpty() const { 91 return entryCount() == 0; 92} 93 94status_t CameraMetadata::sort() { 95 return sort_camera_metadata(mBuffer); 96} 97 98status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { 99 int tagType = get_camera_metadata_tag_type(tag); 100 if ( CC_UNLIKELY(tagType == -1)) { 101 ALOGE("Update metadata entry: Unknown tag %d", tag); 102 return INVALID_OPERATION; 103 } 104 if ( CC_UNLIKELY(tagType != expectedType) ) { 105 ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " 106 "got type %s data instead ", 107 get_camera_metadata_tag_name(tag), tag, 108 camera_metadata_type_names[tagType], 109 camera_metadata_type_names[expectedType]); 110 return INVALID_OPERATION; 111 } 112 return OK; 113} 114 115status_t CameraMetadata::update(uint32_t tag, 116 const int32_t *data, size_t data_count) { 117 status_t res; 118 if ( (res = checkType(tag, TYPE_INT32)) != OK) { 119 return res; 120 } 121 return update(tag, (const void*)data, data_count); 122} 123 124status_t CameraMetadata::update(uint32_t tag, 125 const uint8_t *data, size_t data_count) { 126 status_t res; 127 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 128 return res; 129 } 130 return update(tag, (const void*)data, data_count); 131} 132 133status_t CameraMetadata::update(uint32_t tag, 134 const float *data, size_t data_count) { 135 status_t res; 136 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { 137 return res; 138 } 139 return update(tag, (const void*)data, data_count); 140} 141 142status_t CameraMetadata::update(uint32_t tag, 143 const int64_t *data, size_t data_count) { 144 status_t res; 145 if ( (res = checkType(tag, TYPE_INT64)) != OK) { 146 return res; 147 } 148 return update(tag, (const void*)data, data_count); 149} 150 151status_t CameraMetadata::update(uint32_t tag, 152 const double *data, size_t data_count) { 153 status_t res; 154 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { 155 return res; 156 } 157 return update(tag, (const void*)data, data_count); 158} 159 160status_t CameraMetadata::update(uint32_t tag, 161 const camera_metadata_rational_t *data, size_t data_count) { 162 status_t res; 163 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { 164 return res; 165 } 166 return update(tag, (const void*)data, data_count); 167} 168 169status_t CameraMetadata::update(uint32_t tag, 170 const String8 &string) { 171 status_t res; 172 if ( (res = checkType(tag, TYPE_BYTE)) != OK) { 173 return res; 174 } 175 return update(tag, (const void*)string.string(), string.size()); 176} 177 178status_t CameraMetadata::update(uint32_t tag, const void *data, 179 size_t data_count) { 180 status_t res; 181 int type = get_camera_metadata_tag_type(tag); 182 if (type == -1) { 183 ALOGE("%s: Tag %d not found", __FUNCTION__, tag); 184 return BAD_VALUE; 185 } 186 size_t data_size = calculate_camera_metadata_entry_data_size(type, 187 data_count); 188 189 res = resizeIfNeeded(1, data_size); 190 191 if (res == OK) { 192 camera_metadata_entry_t entry; 193 res = find_camera_metadata_entry(mBuffer, tag, &entry); 194 if (res == NAME_NOT_FOUND) { 195 res = add_camera_metadata_entry(mBuffer, 196 tag, data, data_count); 197 } else if (res == OK) { 198 res = update_camera_metadata_entry(mBuffer, 199 entry.index, data, data_count, NULL); 200 } 201 } 202 203 if (res != OK) { 204 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", 205 __FUNCTION__, get_camera_metadata_section_name(tag), 206 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 207 } 208 return res; 209} 210 211camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { 212 status_t res; 213 camera_metadata_entry entry; 214 res = find_camera_metadata_entry(mBuffer, tag, &entry); 215 if (CC_UNLIKELY( res != OK )) { 216 entry.count = 0; 217 entry.data.u8 = NULL; 218 } 219 return entry; 220} 221 222camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { 223 status_t res; 224 camera_metadata_ro_entry entry; 225 res = find_camera_metadata_ro_entry(mBuffer, tag, &entry); 226 if (CC_UNLIKELY( res != OK )) { 227 entry.count = 0; 228 entry.data.u8 = NULL; 229 } 230 return entry; 231} 232 233status_t CameraMetadata::erase(uint32_t tag) { 234 camera_metadata_entry_t entry; 235 status_t res; 236 res = find_camera_metadata_entry(mBuffer, tag, &entry); 237 if (res == NAME_NOT_FOUND) { 238 return OK; 239 } else if (res != OK) { 240 ALOGE("%s: Error looking for 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 return res; 245 } 246 res = delete_camera_metadata_entry(mBuffer, entry.index); 247 if (res != OK) { 248 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", 249 __FUNCTION__, 250 get_camera_metadata_section_name(tag), 251 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); 252 } 253 return res; 254} 255 256void CameraMetadata::dump(int fd, int verbosity, int indentation) const { 257 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation); 258} 259 260status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { 261 if (mBuffer == NULL) { 262 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); 263 if (mBuffer == NULL) { 264 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 265 return NO_MEMORY; 266 } 267 } else { 268 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); 269 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); 270 size_t newEntryCount = currentEntryCount + 271 extraEntries; 272 newEntryCount = (newEntryCount > currentEntryCap) ? 273 newEntryCount * 2 : currentEntryCap; 274 275 size_t currentDataCount = get_camera_metadata_data_count(mBuffer); 276 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); 277 size_t newDataCount = currentDataCount + 278 extraData; 279 newDataCount = (newDataCount > currentDataCap) ? 280 newDataCount * 2 : currentDataCap; 281 282 if (newEntryCount > currentEntryCap || 283 newDataCount > currentDataCap) { 284 camera_metadata_t *oldBuffer = mBuffer; 285 mBuffer = allocate_camera_metadata(newEntryCount, 286 newDataCount); 287 if (mBuffer == NULL) { 288 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); 289 return NO_MEMORY; 290 } 291 append_camera_metadata(mBuffer, oldBuffer); 292 free_camera_metadata(oldBuffer); 293 } 294 } 295 return OK; 296} 297 298}; // namespace android 299