• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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