blob: a8f9eff10ecb02184af177e5f057b6752c6e18ca [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
Igor Murashkine2d1e3d2013-04-30 18:18:06 -070017// #define LOG_NDEBUG 0
18
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070019#define LOG_TAG "Camera2-Metadata"
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070020#include <utils/Log.h>
21#include <utils/Errors.h>
22
Igor Murashkin7efa5202013-02-13 15:53:56 -080023#include <camera/CameraMetadata.h>
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070024
25namespace android {
26
27CameraMetadata::CameraMetadata() :
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080028 mBuffer(NULL), mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070029}
30
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080031CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
32 mLocked(false)
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070033{
34 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
35}
36
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080037CameraMetadata::CameraMetadata(const CameraMetadata &other) :
38 mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070039 mBuffer = clone_camera_metadata(other.mBuffer);
40}
41
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080042CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
43 mBuffer(NULL), mLocked(false) {
Igor Murashkin7efa5202013-02-13 15:53:56 -080044 acquire(buffer);
45}
46
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070047CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
48 return operator=(other.mBuffer);
49}
50
51CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080052 if (mLocked) {
53 ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
54 return *this;
55 }
56
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070057 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
65CameraMetadata::~CameraMetadata() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080066 mLocked = false;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070067 clear();
68}
69
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080070const camera_metadata_t* CameraMetadata::getAndLock() {
71 mLocked = true;
72 return mBuffer;
73}
74
75status_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
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070089camera_metadata_t* CameraMetadata::release() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080090 if (mLocked) {
91 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
92 return NULL;
93 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070094 camera_metadata_t *released = mBuffer;
95 mBuffer = NULL;
96 return released;
97}
98
99void CameraMetadata::clear() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800100 if (mLocked) {
101 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
102 return;
103 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700104 if (mBuffer) {
105 free_camera_metadata(mBuffer);
106 mBuffer = NULL;
107 }
108}
109
110void CameraMetadata::acquire(camera_metadata_t *buffer) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800111 if (mLocked) {
112 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
113 return;
114 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700115 clear();
116 mBuffer = buffer;
Igor Murashkine2d1e3d2013-04-30 18:18:06 -0700117
118 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
119 "%s: Failed to validate metadata structure %p",
120 __FUNCTION__, buffer);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700121}
122
123void CameraMetadata::acquire(CameraMetadata &other) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800124 if (mLocked) {
125 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
126 return;
127 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700128 acquire(other.release());
129}
130
131status_t CameraMetadata::append(const CameraMetadata &other) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800132 if (mLocked) {
133 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
134 return INVALID_OPERATION;
135 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700136 return append_camera_metadata(mBuffer, other.mBuffer);
137}
138
139size_t CameraMetadata::entryCount() const {
140 return (mBuffer == NULL) ? 0 :
141 get_camera_metadata_entry_count(mBuffer);
142}
143
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700144bool CameraMetadata::isEmpty() const {
145 return entryCount() == 0;
146}
147
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700148status_t CameraMetadata::sort() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800149 if (mLocked) {
150 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
151 return INVALID_OPERATION;
152 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700153 return sort_camera_metadata(mBuffer);
154}
155
156status_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
173status_t CameraMetadata::update(uint32_t tag,
174 const int32_t *data, size_t data_count) {
175 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800176 if (mLocked) {
177 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
178 return INVALID_OPERATION;
179 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700180 if ( (res = checkType(tag, TYPE_INT32)) != OK) {
181 return res;
182 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800183 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700184}
185
186status_t CameraMetadata::update(uint32_t tag,
187 const uint8_t *data, size_t data_count) {
188 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800189 if (mLocked) {
190 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
191 return INVALID_OPERATION;
192 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700193 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
194 return res;
195 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800196 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700197}
198
199status_t CameraMetadata::update(uint32_t tag,
200 const float *data, size_t data_count) {
201 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800202 if (mLocked) {
203 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
204 return INVALID_OPERATION;
205 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700206 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
207 return res;
208 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800209 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700210}
211
212status_t CameraMetadata::update(uint32_t tag,
213 const int64_t *data, size_t data_count) {
214 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800215 if (mLocked) {
216 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
217 return INVALID_OPERATION;
218 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700219 if ( (res = checkType(tag, TYPE_INT64)) != OK) {
220 return res;
221 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800222 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700223}
224
225status_t CameraMetadata::update(uint32_t tag,
226 const double *data, size_t data_count) {
227 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800228 if (mLocked) {
229 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
230 return INVALID_OPERATION;
231 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700232 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
233 return res;
234 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800235 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700236}
237
238status_t CameraMetadata::update(uint32_t tag,
239 const camera_metadata_rational_t *data, size_t data_count) {
240 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800241 if (mLocked) {
242 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
243 return INVALID_OPERATION;
244 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700245 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
246 return res;
247 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800248 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700249}
250
251status_t CameraMetadata::update(uint32_t tag,
252 const String8 &string) {
253 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800254 if (mLocked) {
255 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
256 return INVALID_OPERATION;
257 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700258 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
259 return res;
260 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800261 return updateImpl(tag, (const void*)string.string(), string.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700262}
263
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800264status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700265 size_t data_count) {
266 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800267 if (mLocked) {
268 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
269 return INVALID_OPERATION;
270 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700271 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 }
Igor Murashkine2d1e3d2013-04-30 18:18:06 -0700298
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
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700307 return res;
308}
309
Igor Murashkinfc42642a2013-02-13 18:23:39 -0800310bool 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
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700315camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
316 status_t res;
317 camera_metadata_entry entry;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800318 if (mLocked) {
319 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
320 entry.count = 0;
321 return entry;
322 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700323 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
331camera_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
342status_t CameraMetadata::erase(uint32_t tag) {
343 camera_metadata_entry_t entry;
344 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800345 if (mLocked) {
346 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
347 return INVALID_OPERATION;
348 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700349 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
369void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
370 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
371}
372
373status_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
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700411}; // namespace android