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 25 MetaData::MetaData() { 26 } 27 28 MetaData::MetaData(const MetaData &from) 29 : RefBase(), 30 mItems(from.mItems) { 31 } 32 33 MetaData::~MetaData() { 34 clear(); 35 } 36 37 void MetaData::clear() { 38 mItems.clear(); 39 } 40 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 53 bool MetaData::setCString(uint32_t key, const char *value) { 54 return setData(key, TYPE_C_STRING, value, strlen(value) + 1); 55 } 56 57 bool MetaData::setInt32(uint32_t key, int32_t value) { 58 return setData(key, TYPE_INT32, &value, sizeof(value)); 59 } 60 61 bool MetaData::setInt64(uint32_t key, int64_t value) { 62 return setData(key, TYPE_INT64, &value, sizeof(value)); 63 } 64 65 bool MetaData::setFloat(uint32_t key, float value) { 66 return setData(key, TYPE_FLOAT, &value, sizeof(value)); 67 } 68 69 bool MetaData::setPointer(uint32_t key, void *value) { 70 return setData(key, TYPE_POINTER, &value, sizeof(value)); 71 } 72 73 bool 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 86 bool 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 99 bool 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 107 CHECK_EQ(size, sizeof(*value)); 108 109 *value = *(int32_t *)data; 110 111 return true; 112 } 113 114 bool 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 129 bool 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 137 CHECK_EQ(size, sizeof(*value)); 138 139 *value = *(float *)data; 140 141 return true; 142 } 143 144 bool 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 152 CHECK_EQ(size, sizeof(*value)); 153 154 *value = *(void **)data; 155 156 return true; 157 } 158 159 bool 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 181 bool 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 200 bool 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 215 MetaData::typed_data::typed_data() 216 : mType(0), 217 mSize(0) { 218 } 219 220 MetaData::typed_data::~typed_data() { 221 clear(); 222 } 223 224 MetaData::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 231 MetaData::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 243 void MetaData::typed_data::clear() { 244 freeStorage(); 245 246 mType = 0; 247 } 248 249 void 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 258 void 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 265 void 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 275 void 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 287