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