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