xref: /aosp_15_r20/hardware/libhardware/modules/camera/3_0/Metadata.cpp (revision e01b6f769022e40d0923dee176e8dc7cd1d52984)
1*e01b6f76SAndroid Build Coastguard Worker /*
2*e01b6f76SAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*e01b6f76SAndroid Build Coastguard Worker  *
4*e01b6f76SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e01b6f76SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e01b6f76SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e01b6f76SAndroid Build Coastguard Worker  *
8*e01b6f76SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e01b6f76SAndroid Build Coastguard Worker  *
10*e01b6f76SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e01b6f76SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e01b6f76SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e01b6f76SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e01b6f76SAndroid Build Coastguard Worker  * limitations under the License.
15*e01b6f76SAndroid Build Coastguard Worker  */
16*e01b6f76SAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
17*e01b6f76SAndroid Build Coastguard Worker #define LOG_TAG "Metadata"
18*e01b6f76SAndroid Build Coastguard Worker 
19*e01b6f76SAndroid Build Coastguard Worker #include <errno.h>
20*e01b6f76SAndroid Build Coastguard Worker 
21*e01b6f76SAndroid Build Coastguard Worker #include <system/camera_metadata.h>
22*e01b6f76SAndroid Build Coastguard Worker 
23*e01b6f76SAndroid Build Coastguard Worker #include <log/log.h>
24*e01b6f76SAndroid Build Coastguard Worker 
25*e01b6f76SAndroid Build Coastguard Worker #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
26*e01b6f76SAndroid Build Coastguard Worker #include <utils/Trace.h>
27*e01b6f76SAndroid Build Coastguard Worker 
28*e01b6f76SAndroid Build Coastguard Worker #include "Metadata.h"
29*e01b6f76SAndroid Build Coastguard Worker 
30*e01b6f76SAndroid Build Coastguard Worker namespace default_camera_hal {
31*e01b6f76SAndroid Build Coastguard Worker 
Metadata()32*e01b6f76SAndroid Build Coastguard Worker Metadata::Metadata():
33*e01b6f76SAndroid Build Coastguard Worker     mData(NULL)
34*e01b6f76SAndroid Build Coastguard Worker {
35*e01b6f76SAndroid Build Coastguard Worker }
36*e01b6f76SAndroid Build Coastguard Worker 
~Metadata()37*e01b6f76SAndroid Build Coastguard Worker Metadata::~Metadata()
38*e01b6f76SAndroid Build Coastguard Worker {
39*e01b6f76SAndroid Build Coastguard Worker     replace(NULL);
40*e01b6f76SAndroid Build Coastguard Worker }
41*e01b6f76SAndroid Build Coastguard Worker 
replace(camera_metadata_t * m)42*e01b6f76SAndroid Build Coastguard Worker void Metadata::replace(camera_metadata_t *m)
43*e01b6f76SAndroid Build Coastguard Worker {
44*e01b6f76SAndroid Build Coastguard Worker     if (m == mData) {
45*e01b6f76SAndroid Build Coastguard Worker         ALOGE("%s: Replacing metadata with itself?!", __func__);
46*e01b6f76SAndroid Build Coastguard Worker         return;
47*e01b6f76SAndroid Build Coastguard Worker     }
48*e01b6f76SAndroid Build Coastguard Worker     if (mData)
49*e01b6f76SAndroid Build Coastguard Worker         free_camera_metadata(mData);
50*e01b6f76SAndroid Build Coastguard Worker     mData = m;
51*e01b6f76SAndroid Build Coastguard Worker }
52*e01b6f76SAndroid Build Coastguard Worker 
init(const camera_metadata_t * metadata)53*e01b6f76SAndroid Build Coastguard Worker int Metadata::init(const camera_metadata_t *metadata)
54*e01b6f76SAndroid Build Coastguard Worker {
55*e01b6f76SAndroid Build Coastguard Worker     camera_metadata_t* tmp;
56*e01b6f76SAndroid Build Coastguard Worker 
57*e01b6f76SAndroid Build Coastguard Worker     if (validate_camera_metadata_structure(metadata, NULL))
58*e01b6f76SAndroid Build Coastguard Worker         return -EINVAL;
59*e01b6f76SAndroid Build Coastguard Worker 
60*e01b6f76SAndroid Build Coastguard Worker     tmp = clone_camera_metadata(metadata);
61*e01b6f76SAndroid Build Coastguard Worker     if (tmp == NULL)
62*e01b6f76SAndroid Build Coastguard Worker         return -EINVAL;
63*e01b6f76SAndroid Build Coastguard Worker 
64*e01b6f76SAndroid Build Coastguard Worker     replace(tmp);
65*e01b6f76SAndroid Build Coastguard Worker     return 0;
66*e01b6f76SAndroid Build Coastguard Worker }
67*e01b6f76SAndroid Build Coastguard Worker 
addUInt8(uint32_t tag,int count,const uint8_t * data)68*e01b6f76SAndroid Build Coastguard Worker int Metadata::addUInt8(uint32_t tag, int count, const uint8_t *data)
69*e01b6f76SAndroid Build Coastguard Worker {
70*e01b6f76SAndroid Build Coastguard Worker     if (!validate(tag, TYPE_BYTE, count)) return -EINVAL;
71*e01b6f76SAndroid Build Coastguard Worker     return add(tag, count, data);
72*e01b6f76SAndroid Build Coastguard Worker }
73*e01b6f76SAndroid Build Coastguard Worker 
add1UInt8(uint32_t tag,const uint8_t data)74*e01b6f76SAndroid Build Coastguard Worker int Metadata::add1UInt8(uint32_t tag, const uint8_t data)
75*e01b6f76SAndroid Build Coastguard Worker {
76*e01b6f76SAndroid Build Coastguard Worker     return addUInt8(tag, 1, &data);
77*e01b6f76SAndroid Build Coastguard Worker }
78*e01b6f76SAndroid Build Coastguard Worker 
addInt32(uint32_t tag,int count,const int32_t * data)79*e01b6f76SAndroid Build Coastguard Worker int Metadata::addInt32(uint32_t tag, int count, const int32_t *data)
80*e01b6f76SAndroid Build Coastguard Worker {
81*e01b6f76SAndroid Build Coastguard Worker     if (!validate(tag, TYPE_INT32, count)) return -EINVAL;
82*e01b6f76SAndroid Build Coastguard Worker     return add(tag, count, data);
83*e01b6f76SAndroid Build Coastguard Worker }
84*e01b6f76SAndroid Build Coastguard Worker 
addFloat(uint32_t tag,int count,const float * data)85*e01b6f76SAndroid Build Coastguard Worker int Metadata::addFloat(uint32_t tag, int count, const float *data)
86*e01b6f76SAndroid Build Coastguard Worker {
87*e01b6f76SAndroid Build Coastguard Worker     if (!validate(tag, TYPE_FLOAT, count)) return -EINVAL;
88*e01b6f76SAndroid Build Coastguard Worker     return add(tag, count, data);
89*e01b6f76SAndroid Build Coastguard Worker }
90*e01b6f76SAndroid Build Coastguard Worker 
addInt64(uint32_t tag,int count,const int64_t * data)91*e01b6f76SAndroid Build Coastguard Worker int Metadata::addInt64(uint32_t tag, int count, const int64_t *data)
92*e01b6f76SAndroid Build Coastguard Worker {
93*e01b6f76SAndroid Build Coastguard Worker     if (!validate(tag, TYPE_INT64, count)) return -EINVAL;
94*e01b6f76SAndroid Build Coastguard Worker     return add(tag, count, data);
95*e01b6f76SAndroid Build Coastguard Worker }
96*e01b6f76SAndroid Build Coastguard Worker 
addDouble(uint32_t tag,int count,const double * data)97*e01b6f76SAndroid Build Coastguard Worker int Metadata::addDouble(uint32_t tag, int count, const double *data)
98*e01b6f76SAndroid Build Coastguard Worker {
99*e01b6f76SAndroid Build Coastguard Worker     if (!validate(tag, TYPE_DOUBLE, count)) return -EINVAL;
100*e01b6f76SAndroid Build Coastguard Worker     return add(tag, count, data);
101*e01b6f76SAndroid Build Coastguard Worker }
102*e01b6f76SAndroid Build Coastguard Worker 
addRational(uint32_t tag,int count,const camera_metadata_rational_t * data)103*e01b6f76SAndroid Build Coastguard Worker int Metadata::addRational(uint32_t tag, int count,
104*e01b6f76SAndroid Build Coastguard Worker         const camera_metadata_rational_t *data)
105*e01b6f76SAndroid Build Coastguard Worker {
106*e01b6f76SAndroid Build Coastguard Worker     if (!validate(tag, TYPE_RATIONAL, count)) return -EINVAL;
107*e01b6f76SAndroid Build Coastguard Worker     return add(tag, count, data);
108*e01b6f76SAndroid Build Coastguard Worker }
109*e01b6f76SAndroid Build Coastguard Worker 
validate(uint32_t tag,int tag_type,int count)110*e01b6f76SAndroid Build Coastguard Worker bool Metadata::validate(uint32_t tag, int tag_type, int count)
111*e01b6f76SAndroid Build Coastguard Worker {
112*e01b6f76SAndroid Build Coastguard Worker     if (get_camera_metadata_tag_type(tag) < 0) {
113*e01b6f76SAndroid Build Coastguard Worker         ALOGE("%s: Invalid metadata entry tag: %d", __func__, tag);
114*e01b6f76SAndroid Build Coastguard Worker         return false;
115*e01b6f76SAndroid Build Coastguard Worker     }
116*e01b6f76SAndroid Build Coastguard Worker     if (tag_type < 0 || tag_type >= NUM_TYPES) {
117*e01b6f76SAndroid Build Coastguard Worker         ALOGE("%s: Invalid metadata entry tag type: %d", __func__, tag_type);
118*e01b6f76SAndroid Build Coastguard Worker         return false;
119*e01b6f76SAndroid Build Coastguard Worker     }
120*e01b6f76SAndroid Build Coastguard Worker     if (tag_type != get_camera_metadata_tag_type(tag)) {
121*e01b6f76SAndroid Build Coastguard Worker         ALOGE("%s: Tag %d called with incorrect type: %s(%d)", __func__, tag,
122*e01b6f76SAndroid Build Coastguard Worker                 camera_metadata_type_names[tag_type], tag_type);
123*e01b6f76SAndroid Build Coastguard Worker         return false;
124*e01b6f76SAndroid Build Coastguard Worker     }
125*e01b6f76SAndroid Build Coastguard Worker     if (count < 1) {
126*e01b6f76SAndroid Build Coastguard Worker         ALOGE("%s: Invalid metadata entry count: %d", __func__, count);
127*e01b6f76SAndroid Build Coastguard Worker         return false;
128*e01b6f76SAndroid Build Coastguard Worker     }
129*e01b6f76SAndroid Build Coastguard Worker     return true;
130*e01b6f76SAndroid Build Coastguard Worker }
131*e01b6f76SAndroid Build Coastguard Worker 
add(uint32_t tag,int count,const void * tag_data)132*e01b6f76SAndroid Build Coastguard Worker int Metadata::add(uint32_t tag, int count, const void *tag_data)
133*e01b6f76SAndroid Build Coastguard Worker {
134*e01b6f76SAndroid Build Coastguard Worker     int res;
135*e01b6f76SAndroid Build Coastguard Worker     size_t entry_capacity = 0;
136*e01b6f76SAndroid Build Coastguard Worker     size_t data_capacity = 0;
137*e01b6f76SAndroid Build Coastguard Worker     camera_metadata_t* tmp;
138*e01b6f76SAndroid Build Coastguard Worker     int tag_type = get_camera_metadata_tag_type(tag);
139*e01b6f76SAndroid Build Coastguard Worker     size_t size = calculate_camera_metadata_entry_data_size(tag_type, count);
140*e01b6f76SAndroid Build Coastguard Worker 
141*e01b6f76SAndroid Build Coastguard Worker     if (NULL == mData) {
142*e01b6f76SAndroid Build Coastguard Worker         entry_capacity = 1;
143*e01b6f76SAndroid Build Coastguard Worker         data_capacity = size;
144*e01b6f76SAndroid Build Coastguard Worker     } else {
145*e01b6f76SAndroid Build Coastguard Worker         entry_capacity = get_camera_metadata_entry_count(mData) + 1;
146*e01b6f76SAndroid Build Coastguard Worker         data_capacity = get_camera_metadata_data_count(mData) + size;
147*e01b6f76SAndroid Build Coastguard Worker     }
148*e01b6f76SAndroid Build Coastguard Worker 
149*e01b6f76SAndroid Build Coastguard Worker     // Opportunistically attempt to add if metadata exists and has room for it
150*e01b6f76SAndroid Build Coastguard Worker     if (mData && !add_camera_metadata_entry(mData, tag, tag_data, count))
151*e01b6f76SAndroid Build Coastguard Worker         return 0;
152*e01b6f76SAndroid Build Coastguard Worker     // Double new dimensions to minimize future reallocations
153*e01b6f76SAndroid Build Coastguard Worker     tmp = allocate_camera_metadata(entry_capacity * 2, data_capacity * 2);
154*e01b6f76SAndroid Build Coastguard Worker     if (tmp == NULL) {
155*e01b6f76SAndroid Build Coastguard Worker         ALOGE("%s: Failed to allocate new metadata with %zu entries, %zu data",
156*e01b6f76SAndroid Build Coastguard Worker                 __func__, entry_capacity, data_capacity);
157*e01b6f76SAndroid Build Coastguard Worker         return -ENOMEM;
158*e01b6f76SAndroid Build Coastguard Worker     }
159*e01b6f76SAndroid Build Coastguard Worker     // Append the current metadata to the new (empty) metadata, if any
160*e01b6f76SAndroid Build Coastguard Worker     if (NULL != mData) {
161*e01b6f76SAndroid Build Coastguard Worker       res = append_camera_metadata(tmp, mData);
162*e01b6f76SAndroid Build Coastguard Worker       if (res) {
163*e01b6f76SAndroid Build Coastguard Worker           ALOGE("%s: Failed to append old metadata %p to new %p",
164*e01b6f76SAndroid Build Coastguard Worker                   __func__, mData, tmp);
165*e01b6f76SAndroid Build Coastguard Worker           return res;
166*e01b6f76SAndroid Build Coastguard Worker       }
167*e01b6f76SAndroid Build Coastguard Worker     }
168*e01b6f76SAndroid Build Coastguard Worker     // Add the remaining new item to tmp and replace mData
169*e01b6f76SAndroid Build Coastguard Worker     res = add_camera_metadata_entry(tmp, tag, tag_data, count);
170*e01b6f76SAndroid Build Coastguard Worker     if (res) {
171*e01b6f76SAndroid Build Coastguard Worker         ALOGE("%s: Failed to add new entry (%d, %p, %d) to metadata %p",
172*e01b6f76SAndroid Build Coastguard Worker                 __func__, tag, tag_data, count, tmp);
173*e01b6f76SAndroid Build Coastguard Worker         return res;
174*e01b6f76SAndroid Build Coastguard Worker     }
175*e01b6f76SAndroid Build Coastguard Worker     replace(tmp);
176*e01b6f76SAndroid Build Coastguard Worker 
177*e01b6f76SAndroid Build Coastguard Worker     return 0;
178*e01b6f76SAndroid Build Coastguard Worker }
179*e01b6f76SAndroid Build Coastguard Worker 
get()180*e01b6f76SAndroid Build Coastguard Worker camera_metadata_t* Metadata::get()
181*e01b6f76SAndroid Build Coastguard Worker {
182*e01b6f76SAndroid Build Coastguard Worker     return mData;
183*e01b6f76SAndroid Build Coastguard Worker }
184*e01b6f76SAndroid Build Coastguard Worker 
185*e01b6f76SAndroid Build Coastguard Worker } // namespace default_camera_hal
186