1 /*
2 * Copyright (C) 2013 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 //#define LOG_NDEBUG 0
17 #define LOG_TAG "Metadata"
18
19 #include <errno.h>
20
21 #include <system/camera_metadata.h>
22
23 #include <log/log.h>
24
25 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
26 #include <utils/Trace.h>
27
28 #include "Metadata.h"
29
30 namespace default_camera_hal {
31
Metadata()32 Metadata::Metadata():
33 mData(NULL)
34 {
35 }
36
~Metadata()37 Metadata::~Metadata()
38 {
39 replace(NULL);
40 }
41
replace(camera_metadata_t * m)42 void Metadata::replace(camera_metadata_t *m)
43 {
44 if (m == mData) {
45 ALOGE("%s: Replacing metadata with itself?!", __func__);
46 return;
47 }
48 if (mData)
49 free_camera_metadata(mData);
50 mData = m;
51 }
52
init(const camera_metadata_t * metadata)53 int Metadata::init(const camera_metadata_t *metadata)
54 {
55 camera_metadata_t* tmp;
56
57 if (validate_camera_metadata_structure(metadata, NULL))
58 return -EINVAL;
59
60 tmp = clone_camera_metadata(metadata);
61 if (tmp == NULL)
62 return -EINVAL;
63
64 replace(tmp);
65 return 0;
66 }
67
addUInt8(uint32_t tag,int count,const uint8_t * data)68 int Metadata::addUInt8(uint32_t tag, int count, const uint8_t *data)
69 {
70 if (!validate(tag, TYPE_BYTE, count)) return -EINVAL;
71 return add(tag, count, data);
72 }
73
add1UInt8(uint32_t tag,const uint8_t data)74 int Metadata::add1UInt8(uint32_t tag, const uint8_t data)
75 {
76 return addUInt8(tag, 1, &data);
77 }
78
addInt32(uint32_t tag,int count,const int32_t * data)79 int Metadata::addInt32(uint32_t tag, int count, const int32_t *data)
80 {
81 if (!validate(tag, TYPE_INT32, count)) return -EINVAL;
82 return add(tag, count, data);
83 }
84
addFloat(uint32_t tag,int count,const float * data)85 int Metadata::addFloat(uint32_t tag, int count, const float *data)
86 {
87 if (!validate(tag, TYPE_FLOAT, count)) return -EINVAL;
88 return add(tag, count, data);
89 }
90
addInt64(uint32_t tag,int count,const int64_t * data)91 int Metadata::addInt64(uint32_t tag, int count, const int64_t *data)
92 {
93 if (!validate(tag, TYPE_INT64, count)) return -EINVAL;
94 return add(tag, count, data);
95 }
96
addDouble(uint32_t tag,int count,const double * data)97 int Metadata::addDouble(uint32_t tag, int count, const double *data)
98 {
99 if (!validate(tag, TYPE_DOUBLE, count)) return -EINVAL;
100 return add(tag, count, data);
101 }
102
addRational(uint32_t tag,int count,const camera_metadata_rational_t * data)103 int Metadata::addRational(uint32_t tag, int count,
104 const camera_metadata_rational_t *data)
105 {
106 if (!validate(tag, TYPE_RATIONAL, count)) return -EINVAL;
107 return add(tag, count, data);
108 }
109
validate(uint32_t tag,int tag_type,int count)110 bool Metadata::validate(uint32_t tag, int tag_type, int count)
111 {
112 if (get_camera_metadata_tag_type(tag) < 0) {
113 ALOGE("%s: Invalid metadata entry tag: %d", __func__, tag);
114 return false;
115 }
116 if (tag_type < 0 || tag_type >= NUM_TYPES) {
117 ALOGE("%s: Invalid metadata entry tag type: %d", __func__, tag_type);
118 return false;
119 }
120 if (tag_type != get_camera_metadata_tag_type(tag)) {
121 ALOGE("%s: Tag %d called with incorrect type: %s(%d)", __func__, tag,
122 camera_metadata_type_names[tag_type], tag_type);
123 return false;
124 }
125 if (count < 1) {
126 ALOGE("%s: Invalid metadata entry count: %d", __func__, count);
127 return false;
128 }
129 return true;
130 }
131
add(uint32_t tag,int count,const void * tag_data)132 int Metadata::add(uint32_t tag, int count, const void *tag_data)
133 {
134 int res;
135 size_t entry_capacity = 0;
136 size_t data_capacity = 0;
137 camera_metadata_t* tmp;
138 int tag_type = get_camera_metadata_tag_type(tag);
139 size_t size = calculate_camera_metadata_entry_data_size(tag_type, count);
140
141 if (NULL == mData) {
142 entry_capacity = 1;
143 data_capacity = size;
144 } else {
145 entry_capacity = get_camera_metadata_entry_count(mData) + 1;
146 data_capacity = get_camera_metadata_data_count(mData) + size;
147 }
148
149 // Opportunistically attempt to add if metadata exists and has room for it
150 if (mData && !add_camera_metadata_entry(mData, tag, tag_data, count))
151 return 0;
152 // Double new dimensions to minimize future reallocations
153 tmp = allocate_camera_metadata(entry_capacity * 2, data_capacity * 2);
154 if (tmp == NULL) {
155 ALOGE("%s: Failed to allocate new metadata with %zu entries, %zu data",
156 __func__, entry_capacity, data_capacity);
157 return -ENOMEM;
158 }
159 // Append the current metadata to the new (empty) metadata, if any
160 if (NULL != mData) {
161 res = append_camera_metadata(tmp, mData);
162 if (res) {
163 ALOGE("%s: Failed to append old metadata %p to new %p",
164 __func__, mData, tmp);
165 return res;
166 }
167 }
168 // Add the remaining new item to tmp and replace mData
169 res = add_camera_metadata_entry(tmp, tag, tag_data, count);
170 if (res) {
171 ALOGE("%s: Failed to add new entry (%d, %p, %d) to metadata %p",
172 __func__, tag, tag_data, count, tmp);
173 return res;
174 }
175 replace(tmp);
176
177 return 0;
178 }
179
get()180 camera_metadata_t* Metadata::get()
181 {
182 return mData;
183 }
184
185 } // namespace default_camera_hal
186