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