blob: 884f3b423012935a4594565527b613ee0f343a6c [file] [log] [blame]
Andreas Hubere46b7be2009-07-14 16:56:47 -07001/*
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
Andreas Hubere46b7be2009-07-14 16:56:47 -070017#include <stdlib.h>
18#include <string.h>
19
Andreas Huberb5ceb9e2009-08-26 14:48:20 -070020#include <media/stagefright/MediaDebug.h>
Andreas Hubere46b7be2009-07-14 16:56:47 -070021#include <media/stagefright/MetaData.h>
22
23namespace android {
24
25MetaData::MetaData() {
26}
27
28MetaData::MetaData(const MetaData &from)
29 : RefBase(),
30 mItems(from.mItems) {
31}
32
33MetaData::~MetaData() {
34 clear();
35}
36
37void MetaData::clear() {
38 mItems.clear();
39}
40
41bool 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
53bool MetaData::setCString(uint32_t key, const char *value) {
54 return setData(key, TYPE_C_STRING, value, strlen(value) + 1);
55}
56
57bool MetaData::setInt32(uint32_t key, int32_t value) {
58 return setData(key, TYPE_INT32, &value, sizeof(value));
59}
60
Andreas Huberfa8de752009-10-08 10:07:49 -070061bool MetaData::setInt64(uint32_t key, int64_t value) {
62 return setData(key, TYPE_INT64, &value, sizeof(value));
63}
64
Andreas Hubere46b7be2009-07-14 16:56:47 -070065bool MetaData::setFloat(uint32_t key, float value) {
66 return setData(key, TYPE_FLOAT, &value, sizeof(value));
67}
68
69bool MetaData::setPointer(uint32_t key, void *value) {
70 return setData(key, TYPE_POINTER, &value, sizeof(value));
71}
72
Andreas Huber1bb0ffd2010-11-22 13:06:35 -080073bool MetaData::setRect(
74 uint32_t key,
75 int32_t left, int32_t top,
76 int32_t right, int32_t bottom) {
77 Rect r;
78 r.mLeft = left;
79 r.mTop = top;
80 r.mRight = right;
81 r.mBottom = bottom;
82
83 return setData(key, TYPE_RECT, &r, sizeof(r));
84}
85
Andreas Hubere46b7be2009-07-14 16:56:47 -070086bool MetaData::findCString(uint32_t key, const char **value) {
87 uint32_t type;
88 const void *data;
89 size_t size;
90 if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) {
91 return false;
92 }
93
94 *value = (const char *)data;
95
96 return true;
97}
98
99bool MetaData::findInt32(uint32_t key, int32_t *value) {
100 uint32_t type;
101 const void *data;
102 size_t size;
103 if (!findData(key, &type, &data, &size) || type != TYPE_INT32) {
104 return false;
105 }
106
Andreas Huberb5ceb9e2009-08-26 14:48:20 -0700107 CHECK_EQ(size, sizeof(*value));
Andreas Hubere46b7be2009-07-14 16:56:47 -0700108
109 *value = *(int32_t *)data;
110
111 return true;
112}
113
Andreas Huberfa8de752009-10-08 10:07:49 -0700114bool MetaData::findInt64(uint32_t key, int64_t *value) {
115 uint32_t type;
116 const void *data;
117 size_t size;
118 if (!findData(key, &type, &data, &size) || type != TYPE_INT64) {
119 return false;
120 }
121
122 CHECK_EQ(size, sizeof(*value));
123
124 *value = *(int64_t *)data;
125
126 return true;
127}
128
Andreas Hubere46b7be2009-07-14 16:56:47 -0700129bool MetaData::findFloat(uint32_t key, float *value) {
130 uint32_t type;
131 const void *data;
132 size_t size;
133 if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) {
134 return false;
135 }
136
Andreas Huberb5ceb9e2009-08-26 14:48:20 -0700137 CHECK_EQ(size, sizeof(*value));
Andreas Hubere46b7be2009-07-14 16:56:47 -0700138
139 *value = *(float *)data;
140
141 return true;
142}
143
144bool MetaData::findPointer(uint32_t key, void **value) {
145 uint32_t type;
146 const void *data;
147 size_t size;
148 if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) {
149 return false;
150 }
151
Andreas Huberb5ceb9e2009-08-26 14:48:20 -0700152 CHECK_EQ(size, sizeof(*value));
Andreas Hubere46b7be2009-07-14 16:56:47 -0700153
154 *value = *(void **)data;
155
156 return true;
157}
158
Andreas Huber1bb0ffd2010-11-22 13:06:35 -0800159bool MetaData::findRect(
160 uint32_t key,
161 int32_t *left, int32_t *top,
162 int32_t *right, int32_t *bottom) {
163 uint32_t type;
164 const void *data;
165 size_t size;
166 if (!findData(key, &type, &data, &size) || type != TYPE_RECT) {
167 return false;
168 }
169
170 CHECK_EQ(size, sizeof(Rect));
171
172 const Rect *r = (const Rect *)data;
173 *left = r->mLeft;
174 *top = r->mTop;
175 *right = r->mRight;
176 *bottom = r->mBottom;
177
178 return true;
179}
180
Andreas Hubere46b7be2009-07-14 16:56:47 -0700181bool MetaData::setData(
182 uint32_t key, uint32_t type, const void *data, size_t size) {
183 bool overwrote_existing = true;
184
185 ssize_t i = mItems.indexOfKey(key);
186 if (i < 0) {
187 typed_data item;
188 i = mItems.add(key, item);
189
190 overwrote_existing = false;
191 }
192
193 typed_data &item = mItems.editValueAt(i);
194
195 item.setData(type, data, size);
196
197 return overwrote_existing;
198}
199
200bool MetaData::findData(uint32_t key, uint32_t *type,
201 const void **data, size_t *size) const {
202 ssize_t i = mItems.indexOfKey(key);
203
204 if (i < 0) {
205 return false;
206 }
207
208 const typed_data &item = mItems.valueAt(i);
209
210 item.getData(type, data, size);
211
212 return true;
213}
214
215MetaData::typed_data::typed_data()
216 : mType(0),
217 mSize(0) {
218}
219
220MetaData::typed_data::~typed_data() {
221 clear();
222}
223
224MetaData::typed_data::typed_data(const typed_data &from)
225 : mType(from.mType),
226 mSize(0) {
227 allocateStorage(from.mSize);
228 memcpy(storage(), from.storage(), mSize);
229}
230
231MetaData::typed_data &MetaData::typed_data::operator=(
232 const MetaData::typed_data &from) {
233 if (this != &from) {
234 clear();
235 mType = from.mType;
236 allocateStorage(from.mSize);
237 memcpy(storage(), from.storage(), mSize);
238 }
239
240 return *this;
241}
242
243void MetaData::typed_data::clear() {
244 freeStorage();
245
246 mType = 0;
247}
248
249void MetaData::typed_data::setData(
250 uint32_t type, const void *data, size_t size) {
251 clear();
252
253 mType = type;
254 allocateStorage(size);
255 memcpy(storage(), data, size);
256}
257
258void MetaData::typed_data::getData(
259 uint32_t *type, const void **data, size_t *size) const {
260 *type = mType;
261 *size = mSize;
262 *data = storage();
263}
264
265void MetaData::typed_data::allocateStorage(size_t size) {
266 mSize = size;
267
268 if (usesReservoir()) {
269 return;
270 }
271
272 u.ext_data = malloc(mSize);
273}
274
275void MetaData::typed_data::freeStorage() {
276 if (!usesReservoir()) {
277 if (u.ext_data) {
278 free(u.ext_data);
279 }
280 }
281
282 mSize = 0;
283}
284
285} // namespace android
286