1 /*
2 * Copyright (C) 2009 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 <stdlib.h>
18 #include <string.h>
19
20 #include <media/stagefright/MediaDebug.h>
21 #include <media/stagefright/MetaData.h>
22
23 namespace android {
24
MetaData()25 MetaData::MetaData() {
26 }
27
MetaData(const MetaData & from)28 MetaData::MetaData(const MetaData &from)
29 : RefBase(),
30 mItems(from.mItems) {
31 }
32
~MetaData()33 MetaData::~MetaData() {
34 clear();
35 }
36
clear()37 void MetaData::clear() {
38 mItems.clear();
39 }
40
remove(uint32_t key)41 bool MetaData::remove(uint32_t key) {
42 ssize_t i = mItems.indexOfKey(key);
43
44 if (i < 0) {
45 return false;
46 }
47
48 mItems.removeItemsAt(i);
49
50 return true;
51 }
52
setCString(uint32_t key,const char * value)53 bool MetaData::setCString(uint32_t key, const char *value) {
54 return setData(key, TYPE_C_STRING, value, strlen(value) + 1);
55 }
56
setInt32(uint32_t key,int32_t value)57 bool MetaData::setInt32(uint32_t key, int32_t value) {
58 return setData(key, TYPE_INT32, &value, sizeof(value));
59 }
60
setFloat(uint32_t key,float value)61 bool MetaData::setFloat(uint32_t key, float value) {
62 return setData(key, TYPE_FLOAT, &value, sizeof(value));
63 }
64
setPointer(uint32_t key,void * value)65 bool MetaData::setPointer(uint32_t key, void *value) {
66 return setData(key, TYPE_POINTER, &value, sizeof(value));
67 }
68
findCString(uint32_t key,const char ** value)69 bool MetaData::findCString(uint32_t key, const char **value) {
70 uint32_t type;
71 const void *data;
72 size_t size;
73 if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) {
74 return false;
75 }
76
77 *value = (const char *)data;
78
79 return true;
80 }
81
findInt32(uint32_t key,int32_t * value)82 bool MetaData::findInt32(uint32_t key, int32_t *value) {
83 uint32_t type;
84 const void *data;
85 size_t size;
86 if (!findData(key, &type, &data, &size) || type != TYPE_INT32) {
87 return false;
88 }
89
90 CHECK_EQ(size, sizeof(*value));
91
92 *value = *(int32_t *)data;
93
94 return true;
95 }
96
findFloat(uint32_t key,float * value)97 bool MetaData::findFloat(uint32_t key, float *value) {
98 uint32_t type;
99 const void *data;
100 size_t size;
101 if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) {
102 return false;
103 }
104
105 CHECK_EQ(size, sizeof(*value));
106
107 *value = *(float *)data;
108
109 return true;
110 }
111
findPointer(uint32_t key,void ** value)112 bool MetaData::findPointer(uint32_t key, void **value) {
113 uint32_t type;
114 const void *data;
115 size_t size;
116 if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) {
117 return false;
118 }
119
120 CHECK_EQ(size, sizeof(*value));
121
122 *value = *(void **)data;
123
124 return true;
125 }
126
setData(uint32_t key,uint32_t type,const void * data,size_t size)127 bool MetaData::setData(
128 uint32_t key, uint32_t type, const void *data, size_t size) {
129 bool overwrote_existing = true;
130
131 ssize_t i = mItems.indexOfKey(key);
132 if (i < 0) {
133 typed_data item;
134 i = mItems.add(key, item);
135
136 overwrote_existing = false;
137 }
138
139 typed_data &item = mItems.editValueAt(i);
140
141 item.setData(type, data, size);
142
143 return overwrote_existing;
144 }
145
findData(uint32_t key,uint32_t * type,const void ** data,size_t * size) const146 bool MetaData::findData(uint32_t key, uint32_t *type,
147 const void **data, size_t *size) const {
148 ssize_t i = mItems.indexOfKey(key);
149
150 if (i < 0) {
151 return false;
152 }
153
154 const typed_data &item = mItems.valueAt(i);
155
156 item.getData(type, data, size);
157
158 return true;
159 }
160
typed_data()161 MetaData::typed_data::typed_data()
162 : mType(0),
163 mSize(0) {
164 }
165
~typed_data()166 MetaData::typed_data::~typed_data() {
167 clear();
168 }
169
typed_data(const typed_data & from)170 MetaData::typed_data::typed_data(const typed_data &from)
171 : mType(from.mType),
172 mSize(0) {
173 allocateStorage(from.mSize);
174 memcpy(storage(), from.storage(), mSize);
175 }
176
operator =(const MetaData::typed_data & from)177 MetaData::typed_data &MetaData::typed_data::operator=(
178 const MetaData::typed_data &from) {
179 if (this != &from) {
180 clear();
181 mType = from.mType;
182 allocateStorage(from.mSize);
183 memcpy(storage(), from.storage(), mSize);
184 }
185
186 return *this;
187 }
188
clear()189 void MetaData::typed_data::clear() {
190 freeStorage();
191
192 mType = 0;
193 }
194
setData(uint32_t type,const void * data,size_t size)195 void MetaData::typed_data::setData(
196 uint32_t type, const void *data, size_t size) {
197 clear();
198
199 mType = type;
200 allocateStorage(size);
201 memcpy(storage(), data, size);
202 }
203
getData(uint32_t * type,const void ** data,size_t * size) const204 void MetaData::typed_data::getData(
205 uint32_t *type, const void **data, size_t *size) const {
206 *type = mType;
207 *size = mSize;
208 *data = storage();
209 }
210
allocateStorage(size_t size)211 void MetaData::typed_data::allocateStorage(size_t size) {
212 mSize = size;
213
214 if (usesReservoir()) {
215 return;
216 }
217
218 u.ext_data = malloc(mSize);
219 }
220
freeStorage()221 void MetaData::typed_data::freeStorage() {
222 if (!usesReservoir()) {
223 if (u.ext_data) {
224 free(u.ext_data);
225 }
226 }
227
228 mSize = 0;
229 }
230
231 } // namespace android
232
233