2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <system/camera_metadata.h>
19 #include <camera_metadata_hidden.h>
21 #define LOG_TAG "camera_metadata"
22 #include <cutils/log.h>
30 #define NOT_FOUND -ENOENT
31 #define SN_EVENT_LOG_ID 0x534e4554
33 #define ALIGN_TO(val, alignment) \
34 (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
37 * A single metadata entry, storing an array of values of a given type. If the
38 * array is no larger than 4 bytes in size, it is stored in the data.value[]
39 * array; otherwise, it can found in the parent's data array at index
42 #define ENTRY_ALIGNMENT ((size_t) 4)
43 typedef struct camera_metadata_buffer_entry {
52 } camera_metadata_buffer_entry_t;
54 typedef uint32_t metadata_uptrdiff_t;
55 typedef uint32_t metadata_size_t;
58 * A packet of metadata. This is a list of entries, each of which may point to
59 * its values stored at an offset in data.
61 * It is assumed by the utility functions that the memory layout of the packet
64 * |-----------------------------------------------|
65 * | camera_metadata_t |
67 * |-----------------------------------------------|
68 * | reserved for future expansion |
69 * |-----------------------------------------------|
70 * | camera_metadata_buffer_entry_t #0 |
71 * |-----------------------------------------------|
73 * |-----------------------------------------------|
74 * | camera_metadata_buffer_entry_t #entry_count-1 |
75 * |-----------------------------------------------|
77 * | (entry_capacity-entry_count) entries |
78 * |-----------------------------------------------|
79 * | start of camera_metadata.data |
81 * |-----------------------------------------------|
83 * | (data_capacity-data_count) bytes |
84 * |-----------------------------------------------|
86 * With the total length of the whole packet being camera_metadata.size bytes.
88 * In short, the entries and data are contiguous in memory after the metadata
91 #define METADATA_ALIGNMENT ((size_t) 4)
92 struct camera_metadata {
96 metadata_size_t entry_count;
97 metadata_size_t entry_capacity;
98 metadata_uptrdiff_t entries_start; // Offset from camera_metadata
99 metadata_size_t data_count;
100 metadata_size_t data_capacity;
101 metadata_uptrdiff_t data_start; // Offset from camera_metadata
106 * A datum of metadata. This corresponds to camera_metadata_entry_t::data
107 * with the difference that each element is not a pointer. We need to have a
108 * non-pointer type description in order to figure out the largest alignment
109 * requirement for data (DATA_ALIGNMENT).
111 #define DATA_ALIGNMENT ((size_t) 8)
112 typedef union camera_metadata_data {
118 camera_metadata_rational_t r;
119 } camera_metadata_data_t;
122 * The preferred alignment of a packet of camera metadata. In general,
123 * this is the lowest common multiple of the constituents of a metadata
124 * package, i.e, of DATA_ALIGNMENT and ENTRY_ALIGNMENT.
126 #define MAX_ALIGNMENT(A, B) (((A) > (B)) ? (A) : (B))
127 #define METADATA_PACKET_ALIGNMENT \
128 MAX_ALIGNMENT(MAX_ALIGNMENT(DATA_ALIGNMENT, METADATA_ALIGNMENT), ENTRY_ALIGNMENT);
130 /** Versioning information */
131 #define CURRENT_METADATA_VERSION 1
133 /** Flag definitions */
134 #define FLAG_SORTED 0x00000001
136 /** Tag information */
138 typedef struct tag_info {
139 const char *tag_name;
143 #include "camera_metadata_tag_info.c"
145 const size_t camera_metadata_type_size[NUM_TYPES] = {
146 [TYPE_BYTE] = sizeof(uint8_t),
147 [TYPE_INT32] = sizeof(int32_t),
148 [TYPE_FLOAT] = sizeof(float),
149 [TYPE_INT64] = sizeof(int64_t),
150 [TYPE_DOUBLE] = sizeof(double),
151 [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
154 const char *camera_metadata_type_names[NUM_TYPES] = {
155 [TYPE_BYTE] = "byte",
156 [TYPE_INT32] = "int32",
157 [TYPE_FLOAT] = "float",
158 [TYPE_INT64] = "int64",
159 [TYPE_DOUBLE] = "double",
160 [TYPE_RATIONAL] = "rational"
163 static camera_metadata_buffer_entry_t *get_entries(
164 const camera_metadata_t *metadata) {
165 return (camera_metadata_buffer_entry_t*)
166 ((uint8_t*)metadata + metadata->entries_start);
169 static uint8_t *get_data(const camera_metadata_t *metadata) {
170 return (uint8_t*)metadata + metadata->data_start;
173 size_t get_camera_metadata_alignment() {
174 return METADATA_PACKET_ALIGNMENT;
177 camera_metadata_t *allocate_copy_camera_metadata_checked(
178 const camera_metadata_t *src,
185 if (src_size < sizeof(camera_metadata_t)) {
186 ALOGE("%s: Source size too small!", __FUNCTION__);
187 android_errorWriteLog(0x534e4554, "67782345");
191 void *buffer = calloc(1, src_size);
192 memcpy(buffer, src, src_size);
194 camera_metadata_t *metadata = (camera_metadata_t*) buffer;
195 if (validate_camera_metadata_structure(metadata, &src_size) != OK) {
203 camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
204 size_t data_capacity) {
206 size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
208 void *buffer = calloc(1, memory_needed);
209 return place_camera_metadata(buffer, memory_needed,
214 camera_metadata_t *place_camera_metadata(void *dst,
216 size_t entry_capacity,
217 size_t data_capacity) {
218 if (dst == NULL) return NULL;
220 size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
222 if (memory_needed > dst_size) return NULL;
224 camera_metadata_t *metadata = (camera_metadata_t*)dst;
225 metadata->version = CURRENT_METADATA_VERSION;
227 metadata->entry_count = 0;
228 metadata->entry_capacity = entry_capacity;
229 metadata->entries_start =
230 ALIGN_TO(sizeof(camera_metadata_t), ENTRY_ALIGNMENT);
231 metadata->data_count = 0;
232 metadata->data_capacity = data_capacity;
233 metadata->size = memory_needed;
234 size_t data_unaligned = (uint8_t*)(get_entries(metadata) +
235 metadata->entry_capacity) - (uint8_t*)metadata;
236 metadata->data_start = ALIGN_TO(data_unaligned, DATA_ALIGNMENT);
238 assert(validate_camera_metadata_structure(metadata, NULL) == OK);
241 void free_camera_metadata(camera_metadata_t *metadata) {
245 size_t calculate_camera_metadata_size(size_t entry_count,
247 size_t memory_needed = sizeof(camera_metadata_t);
248 // Start entry list at aligned boundary
249 memory_needed = ALIGN_TO(memory_needed, ENTRY_ALIGNMENT);
250 memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
251 // Start buffer list at aligned boundary
252 memory_needed = ALIGN_TO(memory_needed, DATA_ALIGNMENT);
253 memory_needed += sizeof(uint8_t[data_count]);
254 return memory_needed;
257 size_t get_camera_metadata_size(const camera_metadata_t *metadata) {
258 if (metadata == NULL) return ERROR;
260 return metadata->size;
263 size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
264 if (metadata == NULL) return ERROR;
266 return calculate_camera_metadata_size(metadata->entry_count,
267 metadata->data_count);
270 size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
271 return metadata->entry_count;
274 size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
275 return metadata->entry_capacity;
278 size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
279 return metadata->data_count;
282 size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
283 return metadata->data_capacity;
286 camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
287 const camera_metadata_t *src) {
288 size_t memory_needed = get_camera_metadata_compact_size(src);
290 if (dst == NULL) return NULL;
291 if (dst_size < memory_needed) return NULL;
293 camera_metadata_t *metadata =
294 place_camera_metadata(dst, dst_size, src->entry_count, src->data_count);
296 metadata->flags = src->flags;
297 metadata->entry_count = src->entry_count;
298 metadata->data_count = src->data_count;
300 memcpy(get_entries(metadata), get_entries(src),
301 sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
302 memcpy(get_data(metadata), get_data(src),
303 sizeof(uint8_t[metadata->data_count]));
305 assert(validate_camera_metadata_structure(metadata, NULL) == OK);
309 // This method should be used when the camera metadata cannot be trusted. For example, when it's
311 static int validate_and_calculate_camera_metadata_entry_data_size(size_t *data_size, uint8_t type,
313 if (type >= NUM_TYPES) return ERROR;
315 // Check for overflow
316 if (data_count != 0 &&
317 camera_metadata_type_size[type] > (SIZE_MAX - DATA_ALIGNMENT + 1) / data_count) {
318 android_errorWriteLog(SN_EVENT_LOG_ID, "30741779");
322 size_t data_bytes = data_count * camera_metadata_type_size[type];
325 *data_size = data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
331 size_t calculate_camera_metadata_entry_data_size(uint8_t type,
333 if (type >= NUM_TYPES) return 0;
335 size_t data_bytes = data_count *
336 camera_metadata_type_size[type];
338 return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
341 int validate_camera_metadata_structure(const camera_metadata_t *metadata,
342 const size_t *expected_size) {
344 if (metadata == NULL) {
345 ALOGE("%s: metadata is null!", __FUNCTION__);
349 // Check that the metadata pointer is well-aligned first.
351 static const struct {
356 .name = "camera_metadata",
357 .alignment = METADATA_ALIGNMENT
360 .name = "camera_metadata_buffer_entry",
361 .alignment = ENTRY_ALIGNMENT
364 .name = "camera_metadata_data",
365 .alignment = DATA_ALIGNMENT
369 for (size_t i = 0; i < sizeof(alignments)/sizeof(alignments[0]); ++i) {
370 uintptr_t aligned_ptr = ALIGN_TO(metadata, alignments[i].alignment);
372 if ((uintptr_t)metadata != aligned_ptr) {
373 ALOGE("%s: Metadata pointer is not aligned (actual %p, "
374 "expected %p) to type %s",
375 __FUNCTION__, metadata,
376 (void*)aligned_ptr, alignments[i].name);
383 * Check that the metadata contents are correct
386 if (expected_size != NULL && metadata->size > *expected_size) {
387 ALOGE("%s: Metadata size (%" PRIu32 ") should be <= expected size (%zu)",
388 __FUNCTION__, metadata->size, *expected_size);
392 if (metadata->entry_count > metadata->entry_capacity) {
393 ALOGE("%s: Entry count (%" PRIu32 ") should be <= entry capacity "
395 __FUNCTION__, metadata->entry_count, metadata->entry_capacity);
399 if (metadata->data_count > metadata->data_capacity) {
400 ALOGE("%s: Data count (%" PRIu32 ") should be <= data capacity "
402 __FUNCTION__, metadata->data_count, metadata->data_capacity);
403 android_errorWriteLog(SN_EVENT_LOG_ID, "30591838");
407 const metadata_uptrdiff_t entries_end =
408 metadata->entries_start + metadata->entry_capacity;
409 if (entries_end < metadata->entries_start || // overflow check
410 entries_end > metadata->data_start) {
412 ALOGE("%s: Entry start + capacity (%" PRIu32 ") should be <= data start "
415 (metadata->entries_start + metadata->entry_capacity),
416 metadata->data_start);
420 const metadata_uptrdiff_t data_end =
421 metadata->data_start + metadata->data_capacity;
422 if (data_end < metadata->data_start || // overflow check
423 data_end > metadata->size) {
425 ALOGE("%s: Data start + capacity (%" PRIu32 ") should be <= total size "
428 (metadata->data_start + metadata->data_capacity),
433 // Validate each entry
434 const metadata_size_t entry_count = metadata->entry_count;
435 camera_metadata_buffer_entry_t *entries = get_entries(metadata);
437 for (size_t i = 0; i < entry_count; ++i) {
439 if ((uintptr_t)&entries[i] != ALIGN_TO(&entries[i], ENTRY_ALIGNMENT)) {
440 ALOGE("%s: Entry index %zu had bad alignment (address %p),"
441 " expected alignment %zu",
442 __FUNCTION__, i, &entries[i], ENTRY_ALIGNMENT);
446 camera_metadata_buffer_entry_t entry = entries[i];
448 if (entry.type >= NUM_TYPES) {
449 ALOGE("%s: Entry index %zu had a bad type %d",
450 __FUNCTION__, i, entry.type);
454 // TODO: fix vendor_tag_ops across processes so we don't need to special
455 // case vendor-specific tags
456 uint32_t tag_section = entry.tag >> 16;
457 int tag_type = get_camera_metadata_tag_type(entry.tag);
458 if (tag_type != (int)entry.type && tag_section < VENDOR_SECTION) {
459 ALOGE("%s: Entry index %zu had tag type %d, but the type was %d",
460 __FUNCTION__, i, tag_type, entry.type);
465 if (validate_and_calculate_camera_metadata_entry_data_size(&data_size, entry.type,
466 entry.count) != OK) {
467 ALOGE("%s: Entry data size is invalid. type: %u count: %u", __FUNCTION__, entry.type,
472 if (data_size != 0) {
473 camera_metadata_data_t *data =
474 (camera_metadata_data_t*) (get_data(metadata) +
477 if ((uintptr_t)data != ALIGN_TO(data, DATA_ALIGNMENT)) {
478 ALOGE("%s: Entry index %zu had bad data alignment (address %p),"
479 " expected align %zu, (tag name %s, data size %zu)",
480 __FUNCTION__, i, data, DATA_ALIGNMENT,
481 get_camera_metadata_tag_name(entry.tag) ?: "unknown",
486 size_t data_entry_end = entry.data.offset + data_size;
487 if (data_entry_end < entry.data.offset || // overflow check
488 data_entry_end > metadata->data_capacity) {
490 ALOGE("%s: Entry index %zu data ends (%zu) beyond the capacity "
491 "%" PRIu32, __FUNCTION__, i, data_entry_end,
492 metadata->data_capacity);
496 } else if (entry.count == 0) {
497 if (entry.data.offset != 0) {
498 ALOGE("%s: Entry index %zu had 0 items, but offset was non-0 "
499 "(%" PRIu32 "), tag name: %s", __FUNCTION__, i, entry.data.offset,
500 get_camera_metadata_tag_name(entry.tag) ?: "unknown");
503 } // else data stored inline, so we look at value which can be anything.
509 int append_camera_metadata(camera_metadata_t *dst,
510 const camera_metadata_t *src) {
511 if (dst == NULL || src == NULL ) return ERROR;
513 // Check for overflow
514 if (src->entry_count + dst->entry_count < src->entry_count) return ERROR;
515 if (src->data_count + dst->data_count < src->data_count) return ERROR;
517 if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
518 if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
520 memcpy(get_entries(dst) + dst->entry_count, get_entries(src),
521 sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
522 memcpy(get_data(dst) + dst->data_count, get_data(src),
523 sizeof(uint8_t[src->data_count]));
524 if (dst->data_count != 0) {
525 camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
526 for (size_t i = 0; i < src->entry_count; i++, entry++) {
527 if ( calculate_camera_metadata_entry_data_size(entry->type,
528 entry->count) > 0 ) {
529 entry->data.offset += dst->data_count;
533 if (dst->entry_count == 0) {
534 // Appending onto empty buffer, keep sorted state
535 dst->flags |= src->flags & FLAG_SORTED;
536 } else if (src->entry_count != 0) {
537 // Both src, dst are nonempty, cannot assume sort remains
538 dst->flags &= ~FLAG_SORTED;
540 // Src is empty, keep dst sorted state
542 dst->entry_count += src->entry_count;
543 dst->data_count += src->data_count;
545 assert(validate_camera_metadata_structure(dst, NULL) == OK);
549 camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
551 if (src == NULL) return NULL;
552 camera_metadata_t *clone = allocate_camera_metadata(
553 get_camera_metadata_entry_count(src),
554 get_camera_metadata_data_count(src));
556 res = append_camera_metadata(clone, src);
558 free_camera_metadata(clone);
562 assert(validate_camera_metadata_structure(clone, NULL) == OK);
566 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
572 if (dst == NULL) return ERROR;
573 if (dst->entry_count == dst->entry_capacity) return ERROR;
574 if (data == NULL) return ERROR;
577 calculate_camera_metadata_entry_data_size(type, data_count);
578 if (data_bytes + dst->data_count > dst->data_capacity) return ERROR;
580 size_t data_payload_bytes =
581 data_count * camera_metadata_type_size[type];
582 camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
583 memset(entry, 0, sizeof(camera_metadata_buffer_entry_t));
586 entry->count = data_count;
588 if (data_bytes == 0) {
589 memcpy(entry->data.value, data,
592 entry->data.offset = dst->data_count;
593 memcpy(get_data(dst) + entry->data.offset, data,
595 dst->data_count += data_bytes;
598 dst->flags &= ~FLAG_SORTED;
599 assert(validate_camera_metadata_structure(dst, NULL) == OK);
603 int add_camera_metadata_entry(camera_metadata_t *dst,
608 int type = get_camera_metadata_tag_type(tag);
610 ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
614 return add_camera_metadata_entry_raw(dst,
621 static int compare_entry_tags(const void *p1, const void *p2) {
622 uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
623 uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
624 return tag1 < tag2 ? -1 :
629 int sort_camera_metadata(camera_metadata_t *dst) {
630 if (dst == NULL) return ERROR;
631 if (dst->flags & FLAG_SORTED) return OK;
633 qsort(get_entries(dst), dst->entry_count,
634 sizeof(camera_metadata_buffer_entry_t),
636 dst->flags |= FLAG_SORTED;
638 assert(validate_camera_metadata_structure(dst, NULL) == OK);
642 int get_camera_metadata_entry(camera_metadata_t *src,
644 camera_metadata_entry_t *entry) {
645 if (src == NULL || entry == NULL) return ERROR;
646 if (index >= src->entry_count) return ERROR;
648 camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index;
650 entry->index = index;
651 entry->tag = buffer_entry->tag;
652 entry->type = buffer_entry->type;
653 entry->count = buffer_entry->count;
654 if (buffer_entry->count *
655 camera_metadata_type_size[buffer_entry->type] > 4) {
656 entry->data.u8 = get_data(src) + buffer_entry->data.offset;
658 entry->data.u8 = buffer_entry->data.value;
663 int get_camera_metadata_ro_entry(const camera_metadata_t *src,
665 camera_metadata_ro_entry_t *entry) {
666 return get_camera_metadata_entry((camera_metadata_t*)src, index,
667 (camera_metadata_entry_t*)entry);
670 int find_camera_metadata_entry(camera_metadata_t *src,
672 camera_metadata_entry_t *entry) {
673 if (src == NULL) return ERROR;
676 if (src->flags & FLAG_SORTED) {
677 // Sorted entries, do a binary search
678 camera_metadata_buffer_entry_t *search_entry = NULL;
679 camera_metadata_buffer_entry_t key;
681 search_entry = bsearch(&key,
684 sizeof(camera_metadata_buffer_entry_t),
686 if (search_entry == NULL) return NOT_FOUND;
687 index = search_entry - get_entries(src);
689 // Not sorted, linear search
690 camera_metadata_buffer_entry_t *search_entry = get_entries(src);
691 for (index = 0; index < src->entry_count; index++, search_entry++) {
692 if (search_entry->tag == tag) {
696 if (index == src->entry_count) return NOT_FOUND;
699 return get_camera_metadata_entry(src, index,
703 int find_camera_metadata_ro_entry(const camera_metadata_t *src,
705 camera_metadata_ro_entry_t *entry) {
706 return find_camera_metadata_entry((camera_metadata_t*)src, tag,
707 (camera_metadata_entry_t*)entry);
711 int delete_camera_metadata_entry(camera_metadata_t *dst,
713 if (dst == NULL) return ERROR;
714 if (index >= dst->entry_count) return ERROR;
716 camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
717 size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
720 if (data_bytes > 0) {
721 // Shift data buffer to overwrite deleted data
722 uint8_t *start = get_data(dst) + entry->data.offset;
723 uint8_t *end = start + data_bytes;
724 size_t length = dst->data_count - entry->data.offset - data_bytes;
725 memmove(start, end, length);
727 // Update all entry indices to account for shift
728 camera_metadata_buffer_entry_t *e = get_entries(dst);
730 for (i = 0; i < dst->entry_count; i++) {
731 if (calculate_camera_metadata_entry_data_size(
732 e->type, e->count) > 0 &&
733 e->data.offset > entry->data.offset) {
734 e->data.offset -= data_bytes;
738 dst->data_count -= data_bytes;
741 memmove(entry, entry + 1,
742 sizeof(camera_metadata_buffer_entry_t) *
743 (dst->entry_count - index - 1) );
744 dst->entry_count -= 1;
746 assert(validate_camera_metadata_structure(dst, NULL) == OK);
750 int update_camera_metadata_entry(camera_metadata_t *dst,
754 camera_metadata_entry_t *updated_entry) {
755 if (dst == NULL) return ERROR;
756 if (index >= dst->entry_count) return ERROR;
758 camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
761 calculate_camera_metadata_entry_data_size(entry->type,
763 size_t data_payload_bytes =
764 data_count * camera_metadata_type_size[entry->type];
767 calculate_camera_metadata_entry_data_size(entry->type,
769 if (data_bytes != entry_bytes) {
770 // May need to shift/add to data array
771 if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
775 if (entry_bytes != 0) {
777 uint8_t *start = get_data(dst) + entry->data.offset;
778 uint8_t *end = start + entry_bytes;
779 size_t length = dst->data_count - entry->data.offset - entry_bytes;
780 memmove(start, end, length);
781 dst->data_count -= entry_bytes;
783 // Update all entry indices to account for shift
784 camera_metadata_buffer_entry_t *e = get_entries(dst);
786 for (i = 0; i < dst->entry_count; i++) {
787 if (calculate_camera_metadata_entry_data_size(
788 e->type, e->count) > 0 &&
789 e->data.offset > entry->data.offset) {
790 e->data.offset -= entry_bytes;
796 if (data_bytes != 0) {
798 entry->data.offset = dst->data_count;
800 memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
801 dst->data_count += data_bytes;
803 } else if (data_bytes != 0) {
804 // data size unchanged, reuse same data location
805 memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
808 if (data_bytes == 0) {
809 // Data fits into entry
810 memcpy(entry->data.value, data,
814 entry->count = data_count;
816 if (updated_entry != NULL) {
817 get_camera_metadata_entry(dst,
822 assert(validate_camera_metadata_structure(dst, NULL) == OK);
826 static const vendor_tag_ops_t *vendor_tag_ops = NULL;
828 const char *get_camera_metadata_section_name(uint32_t tag) {
829 uint32_t tag_section = tag >> 16;
830 if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
831 return vendor_tag_ops->get_section_name(
835 if (tag_section >= ANDROID_SECTION_COUNT) {
838 return camera_metadata_section_names[tag_section];
841 const char *get_camera_metadata_tag_name(uint32_t tag) {
842 uint32_t tag_section = tag >> 16;
843 if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
844 return vendor_tag_ops->get_tag_name(
848 if (tag_section >= ANDROID_SECTION_COUNT ||
849 tag >= camera_metadata_section_bounds[tag_section][1] ) {
852 uint32_t tag_index = tag & 0xFFFF;
853 return tag_info[tag_section][tag_index].tag_name;
856 int get_camera_metadata_tag_type(uint32_t tag) {
857 uint32_t tag_section = tag >> 16;
858 if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
859 return vendor_tag_ops->get_tag_type(
863 if (tag_section >= ANDROID_SECTION_COUNT ||
864 tag >= camera_metadata_section_bounds[tag_section][1] ) {
867 uint32_t tag_index = tag & 0xFFFF;
868 return tag_info[tag_section][tag_index].tag_type;
871 int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t* ops) {
873 ALOGE("%s: This function has been deprecated", __FUNCTION__);
877 // Declared in system/media/private/camera/include/camera_metadata_hidden.h
878 int set_camera_metadata_vendor_ops(const vendor_tag_ops_t* ops) {
879 vendor_tag_ops = ops;
883 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type,
887 void dump_camera_metadata(const camera_metadata_t *metadata,
890 dump_indented_camera_metadata(metadata, fd, verbosity, 0);
893 void dump_indented_camera_metadata(const camera_metadata_t *metadata,
897 if (metadata == NULL) {
898 dprintf(fd, "%*sDumping camera metadata array: Not allocated\n",
904 "%*sDumping camera metadata array: %" PRIu32 " / %" PRIu32 " entries, "
905 "%" PRIu32 " / %" PRIu32 " bytes of extra data.\n", indentation, "",
906 metadata->entry_count, metadata->entry_capacity,
907 metadata->data_count, metadata->data_capacity);
908 dprintf(fd, "%*sVersion: %d, Flags: %08x\n",
910 metadata->version, metadata->flags);
911 camera_metadata_buffer_entry_t *entry = get_entries(metadata);
912 for (i=0; i < metadata->entry_count; i++, entry++) {
914 const char *tag_name, *tag_section;
915 tag_section = get_camera_metadata_section_name(entry->tag);
916 if (tag_section == NULL) {
917 tag_section = "unknownSection";
919 tag_name = get_camera_metadata_tag_name(entry->tag);
920 if (tag_name == NULL) {
921 tag_name = "unknownTag";
923 const char *type_name;
924 if (entry->type >= NUM_TYPES) {
925 type_name = "unknown";
927 type_name = camera_metadata_type_names[entry->type];
929 dprintf(fd, "%*s%s.%s (%05x): %s[%" PRIu32 "]\n",
937 if (verbosity < 1) continue;
939 if (entry->type >= NUM_TYPES) continue;
941 size_t type_size = camera_metadata_type_size[entry->type];
943 if ( type_size * entry->count > 4 ) {
944 if (entry->data.offset >= metadata->data_count) {
945 ALOGE("%s: Malformed entry data offset: %" PRIu32 " (max %" PRIu32 ")",
948 metadata->data_count);
951 data_ptr = get_data(metadata) + entry->data.offset;
953 data_ptr = entry->data.value;
955 int count = entry->count;
956 if (verbosity < 2 && count > 16) count = 16;
958 print_data(fd, data_ptr, entry->tag, entry->type, count, indentation);
962 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag,
963 int type, int count, int indentation) {
964 static int values_per_line[NUM_TYPES] = {
972 size_t type_size = camera_metadata_type_size[type];
973 char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE];
976 int lines = count / values_per_line[type];
977 if (count % values_per_line[type] != 0) lines++;
981 for (j = 0; j < lines; j++) {
982 dprintf(fd, "%*s[", indentation + 4, "");
984 k < values_per_line[type] && count > 0;
985 k++, count--, index += type_size) {
989 value = *(data_ptr + index);
990 if (camera_metadata_enum_snprint(tag,
993 sizeof(value_string_tmp))
995 dprintf(fd, "%s ", value_string_tmp);
998 *(data_ptr + index));
1003 *(int32_t*)(data_ptr + index);
1004 if (camera_metadata_enum_snprint(tag,
1007 sizeof(value_string_tmp))
1009 dprintf(fd, "%s ", value_string_tmp);
1011 dprintf(fd, "%" PRId32 " ",
1012 *(int32_t*)(data_ptr + index));
1016 dprintf(fd, "%0.8f ",
1017 *(float*)(data_ptr + index));
1020 dprintf(fd, "%" PRId64 " ",
1021 *(int64_t*)(data_ptr + index));
1024 dprintf(fd, "%0.8f ",
1025 *(double*)(data_ptr + index));
1027 case TYPE_RATIONAL: {
1028 int32_t numerator = *(int32_t*)(data_ptr + index);
1029 int32_t denominator = *(int32_t*)(data_ptr + index + 4);
1030 dprintf(fd, "(%d / %d) ",
1031 numerator, denominator);
1035 dprintf(fd, "??? ");