blob: 6c3e233a79912f2e4ee55a6c9b40d706068ab068 [file] [log] [blame]
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001/*
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
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070017#define LOG_TAG "Camera2-Metadata"
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070018#include <utils/Log.h>
19#include <utils/Errors.h>
20
Igor Murashkinbd02dd12013-02-13 15:53:56 -080021#include <camera/CameraMetadata.h>
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070022
23namespace android {
24
25CameraMetadata::CameraMetadata() :
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080026 mBuffer(NULL), mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070027}
28
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080029CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
30 mLocked(false)
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070031{
32 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
33}
34
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080035CameraMetadata::CameraMetadata(const CameraMetadata &other) :
36 mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070037 mBuffer = clone_camera_metadata(other.mBuffer);
38}
39
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080040CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
41 mBuffer(NULL), mLocked(false) {
Igor Murashkinbd02dd12013-02-13 15:53:56 -080042 acquire(buffer);
43}
44
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070045CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
46 return operator=(other.mBuffer);
47}
48
49CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080050 if (mLocked) {
51 ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
52 return *this;
53 }
54
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070055 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() {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080064 mLocked = false;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070065 clear();
66}
67
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080068const 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
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070087camera_metadata_t* CameraMetadata::release() {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080088 if (mLocked) {
89 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
90 return NULL;
91 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070092 camera_metadata_t *released = mBuffer;
93 mBuffer = NULL;
94 return released;
95}
96
97void CameraMetadata::clear() {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080098 if (mLocked) {
99 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
100 return;
101 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700102 if (mBuffer) {
103 free_camera_metadata(mBuffer);
104 mBuffer = NULL;
105 }
106}
107
108void CameraMetadata::acquire(camera_metadata_t *buffer) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800109 if (mLocked) {
110 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
111 return;
112 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700113 clear();
114 mBuffer = buffer;
115}
116
117void CameraMetadata::acquire(CameraMetadata &other) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800118 if (mLocked) {
119 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
120 return;
121 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700122 acquire(other.release());
123}
124
125status_t CameraMetadata::append(const CameraMetadata &other) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800126 if (mLocked) {
127 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
128 return INVALID_OPERATION;
129 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700130 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
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700138bool CameraMetadata::isEmpty() const {
139 return entryCount() == 0;
140}
141
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700142status_t CameraMetadata::sort() {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800143 if (mLocked) {
144 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
145 return INVALID_OPERATION;
146 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700147 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;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800170 if (mLocked) {
171 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
172 return INVALID_OPERATION;
173 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700174 if ( (res = checkType(tag, TYPE_INT32)) != OK) {
175 return res;
176 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800177 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700178}
179
180status_t CameraMetadata::update(uint32_t tag,
181 const uint8_t *data, size_t data_count) {
182 status_t res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800183 if (mLocked) {
184 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
185 return INVALID_OPERATION;
186 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700187 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
188 return res;
189 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800190 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700191}
192
193status_t CameraMetadata::update(uint32_t tag,
194 const float *data, size_t data_count) {
195 status_t res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800196 if (mLocked) {
197 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
198 return INVALID_OPERATION;
199 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700200 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
201 return res;
202 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800203 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700204}
205
206status_t CameraMetadata::update(uint32_t tag,
207 const int64_t *data, size_t data_count) {
208 status_t res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800209 if (mLocked) {
210 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
211 return INVALID_OPERATION;
212 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700213 if ( (res = checkType(tag, TYPE_INT64)) != OK) {
214 return res;
215 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800216 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700217}
218
219status_t CameraMetadata::update(uint32_t tag,
220 const double *data, size_t data_count) {
221 status_t res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800222 if (mLocked) {
223 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
224 return INVALID_OPERATION;
225 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700226 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
227 return res;
228 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800229 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700230}
231
232status_t CameraMetadata::update(uint32_t tag,
233 const camera_metadata_rational_t *data, size_t data_count) {
234 status_t res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800235 if (mLocked) {
236 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
237 return INVALID_OPERATION;
238 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700239 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
240 return res;
241 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800242 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700243}
244
245status_t CameraMetadata::update(uint32_t tag,
246 const String8 &string) {
247 status_t res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800248 if (mLocked) {
249 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
250 return INVALID_OPERATION;
251 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700252 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
253 return res;
254 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800255 return updateImpl(tag, (const void*)string.string(), string.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700256}
257
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800258status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700259 size_t data_count) {
260 status_t res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800261 if (mLocked) {
262 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
263 return INVALID_OPERATION;
264 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700265 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
Igor Murashkin53779912013-02-13 18:23:39 -0800295bool 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
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700300camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
301 status_t res;
302 camera_metadata_entry entry;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800303 if (mLocked) {
304 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
305 entry.count = 0;
306 return entry;
307 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700308 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;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800330 if (mLocked) {
331 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
332 return INVALID_OPERATION;
333 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700334 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
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700396}; // namespace android