OSDN Git Service

Improvements to the camera metadata structure
[android-x86/system-media.git] / camera / src / camera_metadata.c
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 #include <system/camera_metadata.h>
18 #include <cutils/log.h>
19 #define _GNU_SOURCE // for fdprintf
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <errno.h>
23
24 #define OK         0
25 #define ERROR      1
26 #define NOT_FOUND -ENOENT
27 /**
28  * A single metadata entry, storing an array of values of a given type. If the
29  * array is no larger than 4 bytes in size, it is stored in the data.value[]
30  * array; otherwise, it can found in the parent's data array at index
31  * data.offset.
32  */
33 typedef struct camera_metadata_entry {
34     uint32_t tag;
35     size_t   count;
36     union {
37         size_t  offset;
38         uint8_t value[4];
39     } data;
40     uint8_t  type;
41     uint8_t  reserved[3];
42 } __attribute__((packed)) camera_metadata_entry_t;
43
44 /**
45  * A packet of metadata. This is a list of entries, each of which may point to
46  * its values stored at an offset in data.
47  *
48  * It is assumed by the utility functions that the memory layout of the packet
49  * is as follows:
50  *
51  *   |----------------------------------------|
52  *   | camera_metadata_t                      |
53  *   |                                        |
54  *   |----------------------------------------|
55  *   | reserved for future expansion          |
56  *   |----------------------------------------|
57  *   | camera_metadata_entry_t #0             |
58  *   |----------------------------------------|
59  *   | ....                                   |
60  *   |----------------------------------------|
61  *   | camera_metadata_entry_t #entry_count-1 |
62  *   |----------------------------------------|
63  *   | free space for                         |
64  *   | (entry_capacity-entry_count) entries   |
65  *   |----------------------------------------|
66  *   | start of camera_metadata.data          |
67  *   |                                        |
68  *   |----------------------------------------|
69  *   | free space for                         |
70  *   | (data_capacity-data_count) bytes       |
71  *   |----------------------------------------|
72  *
73  * With the total length of the whole packet being camera_metadata.size bytes.
74  *
75  * In short, the entries and data are contiguous in memory after the metadata
76  * header.
77  */
78 struct camera_metadata {
79     size_t                   size;
80     uint32_t                 version;
81     uint32_t                 flags;
82     size_t                   entry_count;
83     size_t                   entry_capacity;
84     camera_metadata_entry_t *entries;
85     size_t                   data_count;
86     size_t                   data_capacity;
87     uint8_t                 *data;
88     uint8_t                  reserved[0];
89 };
90
91 /** Versioning information */
92 #define CURRENT_METADATA_VERSION 1
93
94 /** Flag definitions */
95 #define FLAG_SORTED 0x00000001
96
97 /** Tag information */
98
99 typedef struct tag_info {
100     const char *tag_name;
101     uint8_t     tag_type;
102 } tag_info_t;
103
104 #include "camera_metadata_tag_info.c"
105
106 size_t camera_metadata_type_size[NUM_TYPES] = {
107     [TYPE_BYTE]     = sizeof(uint8_t),
108     [TYPE_INT32]    = sizeof(int32_t),
109     [TYPE_FLOAT]    = sizeof(float),
110     [TYPE_INT64]    = sizeof(int64_t),
111     [TYPE_DOUBLE]   = sizeof(double),
112     [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
113 };
114
115 char *camera_metadata_type_names[NUM_TYPES] = {
116     [TYPE_BYTE]     = "byte",
117     [TYPE_INT32]    = "int32",
118     [TYPE_FLOAT]    = "float",
119     [TYPE_INT64]    = "int64",
120     [TYPE_RATIONAL] = "rational"
121 };
122
123 camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
124                                             size_t data_capacity) {
125     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
126                                                           data_capacity);
127     void *buffer = malloc(memory_needed);
128     return place_camera_metadata(buffer, memory_needed,
129                                  entry_capacity,
130                                  data_capacity);
131 }
132
133 camera_metadata_t *place_camera_metadata(void *dst,
134                                          size_t dst_size,
135                                          size_t entry_capacity,
136                                          size_t data_capacity) {
137     if (dst == NULL) return NULL;
138     if (entry_capacity == 0) return NULL;
139
140     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
141                                                           data_capacity);
142     if (memory_needed > dst_size) return NULL;
143
144     camera_metadata_t *metadata = (camera_metadata_t*)dst;
145     metadata->version = CURRENT_METADATA_VERSION;
146     metadata->flags = 0;
147     metadata->entry_count = 0;
148     metadata->entry_capacity = entry_capacity;
149     metadata->entries = (camera_metadata_entry_t*)(metadata + 1);
150     metadata->data_count = 0;
151     metadata->data_capacity = data_capacity;
152     metadata->size = memory_needed;
153     if (metadata->data_capacity != 0) {
154         metadata->data =
155                 (uint8_t*)(metadata->entries + metadata->entry_capacity);
156     } else {
157         metadata->data = NULL;
158     }
159
160     return metadata;
161 }
162 void free_camera_metadata(camera_metadata_t *metadata) {
163     free(metadata);
164 }
165
166 size_t calculate_camera_metadata_size(size_t entry_count,
167                                       size_t data_count) {
168     size_t memory_needed = sizeof(camera_metadata_t);
169     memory_needed += sizeof(camera_metadata_entry_t[entry_count]);
170     memory_needed += sizeof(uint8_t[data_count]);
171     return memory_needed;
172 }
173
174 size_t get_camera_metadata_size(const camera_metadata_t *metadata) {
175     if (metadata == NULL) return ERROR;
176
177     return metadata->size;
178 }
179
180 size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
181     if (metadata == NULL) return ERROR;
182
183     ptrdiff_t reserved_size = metadata->size -
184             calculate_camera_metadata_size(metadata->entry_capacity,
185                                            metadata->data_capacity);
186
187     return calculate_camera_metadata_size(metadata->entry_count,
188                                           metadata->data_count) + reserved_size;
189 }
190
191 size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
192     return metadata->entry_count;
193 }
194
195 size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
196     return metadata->entry_capacity;
197 }
198
199 size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
200     return metadata->data_count;
201 }
202
203 size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
204     return metadata->data_capacity;
205 }
206
207 camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
208         const camera_metadata_t *src) {
209     size_t memory_needed = get_camera_metadata_compact_size(src);
210
211     if (dst == NULL) return NULL;
212     if (dst_size < memory_needed) return NULL;
213
214     // If copying a newer version of the structure, there may be additional
215     // header fields we don't know about but need to copy
216     ptrdiff_t reserved_size = src->size -
217             calculate_camera_metadata_size(src->entry_capacity,
218                                            src->data_capacity);
219
220     camera_metadata_t *metadata = (camera_metadata_t*)dst;
221     metadata->version = CURRENT_METADATA_VERSION;
222     metadata->flags = src->flags;
223     metadata->entry_count = src->entry_count;
224     metadata->entry_capacity = src->entry_count;
225     metadata->entries = (camera_metadata_entry_t*)
226              ((uint8_t *)(metadata + 1) + reserved_size);
227     metadata->data_count = src->data_count;
228     metadata->data_capacity = src->data_count;
229     metadata->data = (uint8_t *)(metadata->entries + metadata->entry_capacity);
230     metadata->size = memory_needed;
231
232     if (reserved_size > 0) {
233         memcpy(metadata->reserved, src->reserved, reserved_size);
234     }
235     memcpy(metadata->entries, src->entries,
236             sizeof(camera_metadata_entry_t[metadata->entry_count]));
237     memcpy(metadata->data, src->data,
238             sizeof(uint8_t[metadata->data_count]));
239
240     return metadata;
241 }
242
243 int append_camera_metadata(camera_metadata_t *dst,
244         const camera_metadata_t *src) {
245     if (dst == NULL || src == NULL ) return ERROR;
246
247     if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
248     if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
249
250     memcpy(dst->entries + dst->entry_count, src->entries,
251             sizeof(camera_metadata_entry_t[src->entry_count]));
252     memcpy(dst->data + dst->data_count, src->data,
253             sizeof(uint8_t[src->data_count]));
254     if (dst->data_count != 0) {
255         unsigned int i;
256         for (i = dst->entry_count;
257              i < dst->entry_count + src->entry_count;
258              i++) {
259             camera_metadata_entry_t *entry = dst->entries + i;
260             if ( camera_metadata_type_size[entry->type] * entry->count > 4 ) {
261                 entry->data.offset += dst->data_count;
262             }
263         }
264     }
265     dst->entry_count += src->entry_count;
266     dst->data_count += src->data_count;
267     dst->flags &= ~FLAG_SORTED;
268
269     return OK;
270 }
271
272 size_t calculate_camera_metadata_entry_data_size(uint8_t type,
273         size_t data_count) {
274     if (type >= NUM_TYPES) return 0;
275     size_t data_bytes = data_count *
276             camera_metadata_type_size[type];
277     return data_bytes <= 4 ? 0 : data_bytes;
278 }
279
280 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
281         uint32_t tag,
282         uint8_t  type,
283         const void *data,
284         size_t data_count) {
285
286     if (dst == NULL) return ERROR;
287     if (dst->entry_count == dst->entry_capacity) return ERROR;
288     if (data == NULL) return ERROR;
289
290     size_t data_bytes =
291             calculate_camera_metadata_entry_data_size(type, data_count);
292
293     camera_metadata_entry_t *entry = dst->entries + dst->entry_count;
294     entry->tag = tag;
295     entry->type = type;
296     entry->count = data_count;
297
298     if (data_bytes == 0) {
299         memcpy(entry->data.value, data,
300                 data_count * camera_metadata_type_size[type] );
301     } else {
302         entry->data.offset = dst->data_count;
303         memcpy(dst->data + entry->data.offset, data, data_bytes);
304         dst->data_count += data_bytes;
305     }
306     dst->entry_count++;
307     dst->flags &= ~FLAG_SORTED;
308     return OK;
309 }
310
311 int add_camera_metadata_entry(camera_metadata_t *dst,
312         uint32_t tag,
313         const void *data,
314         size_t data_count) {
315
316     int type = get_camera_metadata_tag_type(tag);
317     if (type == -1) {
318         ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
319         return ERROR;
320     }
321
322     return add_camera_metadata_entry_raw(dst,
323             tag,
324             type,
325             data,
326             data_count);
327 }
328
329 static int compare_entry_tags(const void *p1, const void *p2) {
330     uint32_t tag1 = ((camera_metadata_entry_t*)p1)->tag;
331     uint32_t tag2 = ((camera_metadata_entry_t*)p2)->tag;
332     return  tag1 < tag2 ? -1 :
333             tag1 == tag2 ? 0 :
334             1;
335 }
336
337 int sort_camera_metadata(camera_metadata_t *dst) {
338     if (dst == NULL) return ERROR;
339     if (dst->flags & FLAG_SORTED) return OK;
340
341     qsort(dst->entries, dst->entry_count,
342             sizeof(camera_metadata_entry_t),
343             compare_entry_tags);
344     dst->flags |= FLAG_SORTED;
345
346     return OK;
347 }
348
349 int get_camera_metadata_entry(camera_metadata_t *src,
350         uint32_t index,
351         uint32_t *tag,
352         uint8_t *type,
353         void **data,
354         size_t *data_count) {
355     if (src == NULL ) return ERROR;
356     if (index >= src->entry_count) return ERROR;
357
358     camera_metadata_entry_t *entry = src->entries + index;
359
360     if (tag != NULL) *tag = entry->tag;
361     if (type != NULL) *type = entry->type;
362     if (data_count != NULL) *data_count = entry->count;
363     if (data != NULL) {
364         if (entry->count * camera_metadata_type_size[entry->type] > 4) {
365             *data = src->data + entry->data.offset;
366         } else {
367             *data = entry->data.value;
368         }
369     }
370     return OK;
371 }
372
373 int find_camera_metadata_entry(camera_metadata_t *src,
374         uint32_t tag,
375         uint8_t *type,
376         void **data,
377         size_t *data_count) {
378     if (src == NULL) return ERROR;
379
380     camera_metadata_entry_t *entry = NULL;
381     if (src->flags & FLAG_SORTED) {
382         // Sorted entries, do a binary search
383         camera_metadata_entry_t key;
384         key.tag = tag;
385         entry = bsearch(&key,
386                 src->entries,
387                 src->entry_count,
388                 sizeof(camera_metadata_entry_t),
389                 compare_entry_tags);
390     } else {
391         // Not sorted, linear search
392         unsigned int i;
393         for (i = 0; i < src->entry_count; i++) {
394             if (src->entries[i].tag == tag) {
395                 entry = src->entries + i;
396                 break;
397             }
398         }
399     }
400     if (entry == NULL) return NOT_FOUND;
401
402     if (type != NULL) *type = entry->type;
403     if (data_count != NULL) *data_count = entry->count;
404     if (data != NULL) {
405         if (entry->count * camera_metadata_type_size[entry->type] > 4) {
406             *data = src->data + entry->data.offset;
407         } else {
408             *data = entry->data.value;
409         }
410     }
411     return OK;
412 }
413
414 static const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
415
416 const char *get_camera_metadata_section_name(uint32_t tag) {
417     uint32_t tag_section = tag >> 16;
418     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
419         return vendor_tag_ops->get_camera_vendor_section_name(
420             vendor_tag_ops,
421             tag);
422     }
423     if (tag_section >= ANDROID_SECTION_COUNT) {
424         return NULL;
425     }
426     return camera_metadata_section_names[tag_section];
427 }
428
429 const char *get_camera_metadata_tag_name(uint32_t tag) {
430     uint32_t tag_section = tag >> 16;
431     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
432         return vendor_tag_ops->get_camera_vendor_tag_name(
433             vendor_tag_ops,
434             tag);
435     }
436     if (tag_section >= ANDROID_SECTION_COUNT ||
437         tag >= camera_metadata_section_bounds[tag_section][1] ) {
438         return NULL;
439     }
440     uint32_t tag_index = tag & 0xFFFF;
441     return tag_info[tag_section][tag_index].tag_name;
442 }
443
444 int get_camera_metadata_tag_type(uint32_t tag) {
445     uint32_t tag_section = tag >> 16;
446     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
447         return vendor_tag_ops->get_camera_vendor_tag_type(
448             vendor_tag_ops,
449             tag);
450     }
451     if (tag_section >= ANDROID_SECTION_COUNT ||
452             tag >= camera_metadata_section_bounds[tag_section][1] ) {
453         return -1;
454     }
455     uint32_t tag_index = tag & 0xFFFF;
456     return tag_info[tag_section][tag_index].tag_type;
457 }
458
459 int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
460     vendor_tag_ops = query_ops;
461     return OK;
462 }
463
464 static void print_data(int fd, const uint8_t *data_ptr, int type, int count);
465
466 void dump_camera_metadata(const camera_metadata_t *metadata,
467         int fd,
468         int verbosity) {
469     if (metadata == NULL) {
470         ALOGE("%s: Metadata is null.", __FUNCTION__);
471         return;
472     }
473     unsigned int i;
474     fdprintf(fd,
475             "Dumping camera metadata array. %d entries, "
476             "%d bytes of extra data.\n",
477             metadata->entry_count, metadata->data_count);
478     fdprintf(fd, "  (%d entries and %d bytes data reserved)\n",
479             metadata->entry_capacity, metadata->data_capacity);
480     fdprintf(fd, "  Version: %d, Flags: %08x\n",
481             metadata->version, metadata->flags);
482     for (i=0; i < metadata->entry_count; i++) {
483         camera_metadata_entry_t *entry = metadata->entries + i;
484
485         const char *tag_name, *tag_section;
486         tag_section = get_camera_metadata_section_name(entry->tag);
487         if (tag_section == NULL) {
488             tag_section = "unknownSection";
489         }
490         tag_name = get_camera_metadata_tag_name(entry->tag);
491         if (tag_name == NULL) {
492             tag_name = "unknownTag";
493         }
494         const char *type_name;
495         if (entry->type >= NUM_TYPES) {
496             type_name = "unknown";
497         } else {
498             type_name = camera_metadata_type_names[entry->type];
499         }
500         fdprintf(fd, "Tag: %s.%s (%05x): %s[%d]\n",
501              tag_section,
502              tag_name,
503              entry->tag,
504              type_name,
505              entry->count);
506
507         if (verbosity < 1) continue;
508
509         if (entry->type >= NUM_TYPES) continue;
510
511         size_t type_size = camera_metadata_type_size[entry->type];
512         uint8_t *data_ptr;
513         if ( type_size * entry->count > 4 ) {
514             if (entry->data.offset >= metadata->data_count) {
515                 ALOGE("%s: Malformed entry data offset: %d (max %d)",
516                         __FUNCTION__,
517                         entry->data.offset,
518                         metadata->data_count);
519                 continue;
520             }
521             data_ptr = metadata->data + entry->data.offset;
522         } else {
523             data_ptr = entry->data.value;
524         }
525         int count = entry->count;
526         if (verbosity < 2 && count > 16) count = 16;
527
528         print_data(fd, data_ptr, entry->type, count);
529     }
530 }
531
532 static void print_data(int fd, const uint8_t *data_ptr, int type, int count) {
533     static int values_per_line[NUM_TYPES] = {
534         [TYPE_BYTE]     = 16,
535         [TYPE_INT32]    = 4,
536         [TYPE_FLOAT]    = 8,
537         [TYPE_INT64]    = 2,
538         [TYPE_DOUBLE]   = 4,
539         [TYPE_RATIONAL] = 2,
540     };
541     size_t type_size = camera_metadata_type_size[type];
542
543     int lines = count / values_per_line[type];
544     if (count % values_per_line[type] != 0) lines++;
545
546     int index = 0;
547     int j, k;
548     for (j = 0; j < lines; j++) {
549         fdprintf(fd, " [");
550         for (k = 0;
551              k < values_per_line[type] && count > 0;
552              k++, count--, index += type_size) {
553
554             switch (type) {
555                 case TYPE_BYTE:
556                     fdprintf(fd, "%hhu ",
557                             *(data_ptr + index));
558                     break;
559                 case TYPE_INT32:
560                     fdprintf(fd, "%d ",
561                             *(int32_t*)(data_ptr + index));
562                     break;
563                 case TYPE_FLOAT:
564                     fdprintf(fd, "%0.2f ",
565                             *(float*)(data_ptr + index));
566                     break;
567                 case TYPE_INT64:
568                     fdprintf(fd, "%lld ",
569                             *(int64_t*)(data_ptr + index));
570                     break;
571                 case TYPE_DOUBLE:
572                     fdprintf(fd, "%0.2f ",
573                             *(float*)(data_ptr + index));
574                     break;
575                 case TYPE_RATIONAL: {
576                     int32_t numerator = *(int32_t*)(data_ptr + index);
577                     int32_t denominator = *(int32_t*)(data_ptr + index + 4);
578                     fdprintf(fd, "(%d / %d) ",
579                             numerator, denominator);
580                     break;
581                 }
582                 default:
583                     fdprintf(fd, "??? ");
584             }
585         }
586         fdprintf(fd, "]\n");
587     }
588 }