CameraMetadata.cpp revision e2d1e3d0436aec645739c65e6d3131dd814f40a1
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
25namespace android {
26
27CameraMetadata::CameraMetadata() :
28        mBuffer(NULL), mLocked(false) {
29}
30
31CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
32        mLocked(false)
33{
34    mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
35}
36
37CameraMetadata::CameraMetadata(const CameraMetadata &other) :
38        mLocked(false) {
39    mBuffer = clone_camera_metadata(other.mBuffer);
40}
41
42CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
43        mBuffer(NULL), mLocked(false) {
44    acquire(buffer);
45}
46
47CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
48    return operator=(other.mBuffer);
49}
50
51CameraMetadata &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
65CameraMetadata::~CameraMetadata() {
66    mLocked = false;
67    clear();
68}
69
70const 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
89camera_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
99void 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
110void 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
123void CameraMetadata::acquire(CameraMetadata &other) {
124    if (mLocked) {
125        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
126        return;
127    }
128    acquire(other.release());
129}
130
131status_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
139size_t CameraMetadata::entryCount() const {
140    return (mBuffer == NULL) ? 0 :
141            get_camera_metadata_entry_count(mBuffer);
142}
143
144bool CameraMetadata::isEmpty() const {
145    return entryCount() == 0;
146}
147
148status_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
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;
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
186status_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
199status_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
212status_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
225status_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
238status_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
251status_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
264status_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
310bool 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
315camera_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
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;
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
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
411}; // namespace android
412