MetaData.cpp revision 4650ff0e86f9e815e3152a806a06c700418d071d
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 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 61bool MetaData::setInt64(uint32_t key, int64_t value) { 62 return setData(key, TYPE_INT64, &value, sizeof(value)); 63} 64 65bool 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 73bool 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 86bool MetaData::findCString(uint32_t key, const char **value) const { 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) const { 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 114bool MetaData::findInt64(uint32_t key, int64_t *value) const { 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 129bool MetaData::findFloat(uint32_t key, float *value) const { 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 144bool MetaData::findPointer(uint32_t key, void **value) const { 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 159bool MetaData::findRect( 160 uint32_t key, 161 int32_t *left, int32_t *top, 162 int32_t *right, int32_t *bottom) const { 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 181bool 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 287