• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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