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
CameraMetadata()27 CameraMetadata::CameraMetadata() :
28 mBuffer(NULL), mLocked(false) {
29 }
30
CameraMetadata(size_t entryCapacity,size_t dataCapacity)31 CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
32 mLocked(false)
33 {
34 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
35 }
36
CameraMetadata(const CameraMetadata & other)37 CameraMetadata::CameraMetadata(const CameraMetadata &other) :
38 mLocked(false) {
39 mBuffer = clone_camera_metadata(other.mBuffer);
40 }
41
CameraMetadata(camera_metadata_t * buffer)42 CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
43 mBuffer(NULL), mLocked(false) {
44 acquire(buffer);
45 }
46
operator =(const CameraMetadata & other)47 CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
48 return operator=(other.mBuffer);
49 }
50
operator =(const camera_metadata_t * buffer)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
~CameraMetadata()65 CameraMetadata::~CameraMetadata() {
66 mLocked = false;
67 clear();
68 }
69
getAndLock()70 const camera_metadata_t* CameraMetadata::getAndLock() {
71 mLocked = true;
72 return mBuffer;
73 }
74
unlock(const camera_metadata_t * buffer)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
release()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
clear()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
acquire(camera_metadata_t * buffer)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
acquire(CameraMetadata & other)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
append(const CameraMetadata & other)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
entryCount() const139 size_t CameraMetadata::entryCount() const {
140 return (mBuffer == NULL) ? 0 :
141 get_camera_metadata_entry_count(mBuffer);
142 }
143
isEmpty() const144 bool CameraMetadata::isEmpty() const {
145 return entryCount() == 0;
146 }
147
sort()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
checkType(uint32_t tag,uint8_t expectedType)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
update(uint32_t tag,const int32_t * data,size_t data_count)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
update(uint32_t tag,const uint8_t * data,size_t data_count)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
update(uint32_t tag,const float * data,size_t data_count)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
update(uint32_t tag,const int64_t * data,size_t data_count)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
update(uint32_t tag,const double * data,size_t data_count)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
update(uint32_t tag,const camera_metadata_rational_t * data,size_t data_count)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
update(uint32_t tag,const String8 & string)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
updateImpl(uint32_t tag,const void * data,size_t data_count)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
exists(uint32_t tag) const310 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
find(uint32_t tag)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
find(uint32_t tag) const331 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
erase(uint32_t tag)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
dump(int fd,int verbosity,int indentation) const369 void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
370 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
371 }
372
resizeIfNeeded(size_t extraEntries,size_t extraData)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