CameraMetadata.cpp revision cab96a4a7a2900fa991ab77ae45ba8d4be97e054
1e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala/*
2e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
3e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *
4e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * you may not use this file except in compliance with the License.
6e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * You may obtain a copy of the License at
7e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *
8e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala *
10e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * See the License for the specific language governing permissions and
14e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala * limitations under the License.
15e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala */
16e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
17e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#define LOG_TAG "CameraMetadata"
18e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#include <utils/Log.h>
19e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#include <utils/Errors.h>
20f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala
21e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala#include "CameraMetadata.h"
22e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
23e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalanamespace android {
24e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
25e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::CameraMetadata() :
26e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        mBuffer(NULL) {
27e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
28e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
29e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity)
30e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala{
31e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
32e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
33e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
34e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::CameraMetadata(const CameraMetadata &other) {
35e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mBuffer = clone_camera_metadata(other.mBuffer);
36e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
37e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
38e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
39e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return operator=(other.mBuffer);
40f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala}
41e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
42e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
43f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala    if (CC_LIKELY(buffer != mBuffer)) {
44e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
45e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        clear();
46e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        mBuffer = newBuffer;
47e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
48e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return *this;
49e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
50e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
51e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville TalvalaCameraMetadata::~CameraMetadata() {
52e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    clear();
53e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
54e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
55e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalacamera_metadata_t* CameraMetadata::release() {
56e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    camera_metadata_t *released = mBuffer;
57e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mBuffer = NULL;
58e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return released;
59e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
60e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
61e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalavoid CameraMetadata::clear() {
62e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala    if (mBuffer) {
63e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala        free_camera_metadata(mBuffer);
64e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        mBuffer = NULL;
65e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
66e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
67e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
68e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalavoid CameraMetadata::acquire(camera_metadata_t *buffer) {
69e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    clear();
70e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    mBuffer = buffer;
71e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
72e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
73e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalavoid CameraMetadata::acquire(CameraMetadata &other) {
74e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    acquire(other.release());
75e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
76e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
77e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CameraMetadata::append(const CameraMetadata &other) {
78e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return append_camera_metadata(mBuffer, other.mBuffer);
79e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
80e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
81e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalasize_t CameraMetadata::entryCount() const {
82e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return (mBuffer == NULL) ? 0 :
83e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala            get_camera_metadata_entry_count(mBuffer);
84e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
85f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala
86e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CameraMetadata::sort() {
87e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    return sort_camera_metadata(mBuffer);
88e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala}
89e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala
90e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvalastatus_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
91e232fdca2a62dc5e81b550f5be8710e36174e7a6Eino-Ville Talvala    int tagType = get_camera_metadata_tag_type(tag);
92e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    if ( CC_UNLIKELY(tagType == -1)) {
93e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        ALOGE("Update metadata entry: Unknown tag %d", tag);
94f57e7540d4cf799f18fe87d3536c55f1e0064931Eino-Ville Talvala        return INVALID_OPERATION;
95e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
96e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    if ( CC_UNLIKELY(tagType != expectedType) ) {
97e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
98e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala                "got type %s data instead ",
99e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala                get_camera_metadata_tag_name(tag), tag,
100e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala                camera_metadata_type_names[tagType],
101e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala                camera_metadata_type_names[expectedType]);
102e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala        return INVALID_OPERATION;
103e41b318bc4708e1dee9364e73215ff0d51fb76a1Eino-Ville Talvala    }
104    return OK;
105}
106
107status_t CameraMetadata::update(uint32_t tag,
108        const int32_t *data, size_t data_count) {
109    status_t res;
110    if ( (res = checkType(tag, TYPE_INT32)) != OK) {
111        return res;
112    }
113    return update(tag, (const void*)data, data_count);
114}
115
116status_t CameraMetadata::update(uint32_t tag,
117        const uint8_t *data, size_t data_count) {
118    status_t res;
119    if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
120        return res;
121    }
122    return update(tag, (const void*)data, data_count);
123}
124
125status_t CameraMetadata::update(uint32_t tag,
126        const float *data, size_t data_count) {
127    status_t res;
128    if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
129        return res;
130    }
131    return update(tag, (const void*)data, data_count);
132}
133
134status_t CameraMetadata::update(uint32_t tag,
135        const int64_t *data, size_t data_count) {
136    status_t res;
137    if ( (res = checkType(tag, TYPE_INT64)) != OK) {
138        return res;
139    }
140    return update(tag, (const void*)data, data_count);
141}
142
143status_t CameraMetadata::update(uint32_t tag,
144        const double *data, size_t data_count) {
145    status_t res;
146    if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
147        return res;
148    }
149    return update(tag, (const void*)data, data_count);
150}
151
152status_t CameraMetadata::update(uint32_t tag,
153        const camera_metadata_rational_t *data, size_t data_count) {
154    status_t res;
155    if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
156        return res;
157    }
158    return update(tag, (const void*)data, data_count);
159}
160
161status_t CameraMetadata::update(uint32_t tag,
162        const String8 &string) {
163    status_t res;
164    if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
165        return res;
166    }
167    return update(tag, (const void*)string.string(), string.size());
168}
169
170status_t CameraMetadata::update(uint32_t tag, const void *data,
171        size_t data_count) {
172    status_t res;
173    int type = get_camera_metadata_tag_type(tag);
174    if (type == -1) {
175        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
176        return BAD_VALUE;
177    }
178    size_t data_size = calculate_camera_metadata_entry_data_size(type,
179            data_count);
180
181    res = resizeIfNeeded(1, data_size);
182
183    if (res == OK) {
184        camera_metadata_entry_t entry;
185        res = find_camera_metadata_entry(mBuffer, tag, &entry);
186        if (res == NAME_NOT_FOUND) {
187            res = add_camera_metadata_entry(mBuffer,
188                    tag, data, data_count);
189        } else if (res == OK) {
190            res = update_camera_metadata_entry(mBuffer,
191                    entry.index, data, data_count, NULL);
192        }
193    }
194
195    if (res != OK) {
196        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
197                __FUNCTION__, get_camera_metadata_section_name(tag),
198                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
199    }
200    return res;
201}
202
203camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
204    status_t res;
205    camera_metadata_entry entry;
206    res = find_camera_metadata_entry(mBuffer, tag, &entry);
207    if (CC_UNLIKELY( res != OK )) {
208        entry.count = 0;
209        entry.data.u8 = NULL;
210    }
211    return entry;
212}
213
214camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
215    status_t res;
216    camera_metadata_ro_entry entry;
217    res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
218    if (CC_UNLIKELY( res != OK )) {
219        entry.count = 0;
220        entry.data.u8 = NULL;
221    }
222    return entry;
223}
224
225status_t CameraMetadata::erase(uint32_t tag) {
226    camera_metadata_entry_t entry;
227    status_t res;
228    res = find_camera_metadata_entry(mBuffer, tag, &entry);
229    if (res == NAME_NOT_FOUND) {
230        return OK;
231    } else if (res != OK) {
232        ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
233                __FUNCTION__,
234                get_camera_metadata_section_name(tag),
235                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
236        return res;
237    }
238    res = delete_camera_metadata_entry(mBuffer, entry.index);
239    if (res != OK) {
240        ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
241                __FUNCTION__,
242                get_camera_metadata_section_name(tag),
243                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
244    }
245    return res;
246}
247
248void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
249    dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
250}
251
252status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
253    if (mBuffer == NULL) {
254        mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
255        if (mBuffer == NULL) {
256            ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
257            return NO_MEMORY;
258        }
259    } else {
260        size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
261        size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
262        size_t newEntryCount = currentEntryCount +
263                extraEntries;
264        newEntryCount = (newEntryCount > currentEntryCap) ?
265                newEntryCount * 2 : currentEntryCap;
266
267        size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
268        size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
269        size_t newDataCount = currentDataCount +
270                extraData;
271        newDataCount = (newDataCount > currentDataCap) ?
272                newDataCount * 2 : currentDataCap;
273
274        if (newEntryCount > currentEntryCap ||
275                newDataCount > currentDataCap) {
276            camera_metadata_t *oldBuffer = mBuffer;
277            mBuffer = allocate_camera_metadata(newEntryCount,
278                    newDataCount);
279            if (mBuffer == NULL) {
280                ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
281                return NO_MEMORY;
282            }
283            append_camera_metadata(mBuffer, oldBuffer);
284            free_camera_metadata(oldBuffer);
285        }
286    }
287    return OK;
288}
289
290}; // namespace android
291