MetaData.cpp revision feba11fd788c99b0b63e0bce724730817688d82f
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//#define LOG_NDEBUG 0 18#define LOG_TAG "MetaData" 19#include <utils/Log.h> 20 21#include <stdlib.h> 22#include <string.h> 23 24#include <media/stagefright/foundation/ADebug.h> 25#include <media/stagefright/MetaData.h> 26 27namespace android { 28 29MetaData::MetaData() { 30} 31 32MetaData::MetaData(const MetaData &from) 33 : RefBase(), 34 mItems(from.mItems) { 35} 36 37MetaData::~MetaData() { 38 clear(); 39} 40 41void MetaData::clear() { 42 mItems.clear(); 43} 44 45bool MetaData::remove(uint32_t key) { 46 ssize_t i = mItems.indexOfKey(key); 47 48 if (i < 0) { 49 return false; 50 } 51 52 mItems.removeItemsAt(i); 53 54 return true; 55} 56 57bool MetaData::setCString(uint32_t key, const char *value) { 58 return setData(key, TYPE_C_STRING, value, strlen(value) + 1); 59} 60 61bool MetaData::setInt32(uint32_t key, int32_t value) { 62 return setData(key, TYPE_INT32, &value, sizeof(value)); 63} 64 65bool MetaData::setInt64(uint32_t key, int64_t value) { 66 return setData(key, TYPE_INT64, &value, sizeof(value)); 67} 68 69bool MetaData::setFloat(uint32_t key, float value) { 70 return setData(key, TYPE_FLOAT, &value, sizeof(value)); 71} 72 73bool MetaData::setPointer(uint32_t key, void *value) { 74 return setData(key, TYPE_POINTER, &value, sizeof(value)); 75} 76 77bool MetaData::setRect( 78 uint32_t key, 79 int32_t left, int32_t top, 80 int32_t right, int32_t bottom) { 81 Rect r; 82 r.mLeft = left; 83 r.mTop = top; 84 r.mRight = right; 85 r.mBottom = bottom; 86 87 return setData(key, TYPE_RECT, &r, sizeof(r)); 88} 89 90bool MetaData::findCString(uint32_t key, const char **value) { 91 uint32_t type; 92 const void *data; 93 size_t size; 94 if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) { 95 return false; 96 } 97 98 *value = (const char *)data; 99 100 return true; 101} 102 103bool MetaData::findInt32(uint32_t key, int32_t *value) { 104 uint32_t type; 105 const void *data; 106 size_t size; 107 if (!findData(key, &type, &data, &size) || type != TYPE_INT32) { 108 return false; 109 } 110 111 CHECK_EQ(size, sizeof(*value)); 112 113 *value = *(int32_t *)data; 114 115 return true; 116} 117 118bool MetaData::findInt64(uint32_t key, int64_t *value) { 119 uint32_t type; 120 const void *data; 121 size_t size; 122 if (!findData(key, &type, &data, &size) || type != TYPE_INT64) { 123 return false; 124 } 125 126 CHECK_EQ(size, sizeof(*value)); 127 128 *value = *(int64_t *)data; 129 130 return true; 131} 132 133bool MetaData::findFloat(uint32_t key, float *value) { 134 uint32_t type; 135 const void *data; 136 size_t size; 137 if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) { 138 return false; 139 } 140 141 CHECK_EQ(size, sizeof(*value)); 142 143 *value = *(float *)data; 144 145 return true; 146} 147 148bool MetaData::findPointer(uint32_t key, void **value) { 149 uint32_t type; 150 const void *data; 151 size_t size; 152 if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) { 153 return false; 154 } 155 156 CHECK_EQ(size, sizeof(*value)); 157 158 *value = *(void **)data; 159 160 return true; 161} 162 163bool MetaData::findRect( 164 uint32_t key, 165 int32_t *left, int32_t *top, 166 int32_t *right, int32_t *bottom) { 167 uint32_t type; 168 const void *data; 169 size_t size; 170 if (!findData(key, &type, &data, &size) || type != TYPE_RECT) { 171 return false; 172 } 173 174 CHECK_EQ(size, sizeof(Rect)); 175 176 const Rect *r = (const Rect *)data; 177 *left = r->mLeft; 178 *top = r->mTop; 179 *right = r->mRight; 180 *bottom = r->mBottom; 181 182 return true; 183} 184 185bool MetaData::setData( 186 uint32_t key, uint32_t type, const void *data, size_t size) { 187 bool overwrote_existing = true; 188 189 ssize_t i = mItems.indexOfKey(key); 190 if (i < 0) { 191 typed_data item; 192 i = mItems.add(key, item); 193 194 overwrote_existing = false; 195 } 196 197 typed_data &item = mItems.editValueAt(i); 198 199 item.setData(type, data, size); 200 201 return overwrote_existing; 202} 203 204bool MetaData::findData(uint32_t key, uint32_t *type, 205 const void **data, size_t *size) const { 206 ssize_t i = mItems.indexOfKey(key); 207 208 if (i < 0) { 209 return false; 210 } 211 212 const typed_data &item = mItems.valueAt(i); 213 214 item.getData(type, data, size); 215 216 return true; 217} 218 219MetaData::typed_data::typed_data() 220 : mType(0), 221 mSize(0) { 222} 223 224MetaData::typed_data::~typed_data() { 225 clear(); 226} 227 228MetaData::typed_data::typed_data(const typed_data &from) 229 : mType(from.mType), 230 mSize(0) { 231 allocateStorage(from.mSize); 232 memcpy(storage(), from.storage(), mSize); 233} 234 235MetaData::typed_data &MetaData::typed_data::operator=( 236 const MetaData::typed_data &from) { 237 if (this != &from) { 238 clear(); 239 mType = from.mType; 240 allocateStorage(from.mSize); 241 memcpy(storage(), from.storage(), mSize); 242 } 243 244 return *this; 245} 246 247void MetaData::typed_data::clear() { 248 freeStorage(); 249 250 mType = 0; 251} 252 253void MetaData::typed_data::setData( 254 uint32_t type, const void *data, size_t size) { 255 clear(); 256 257 mType = type; 258 allocateStorage(size); 259 memcpy(storage(), data, size); 260} 261 262void MetaData::typed_data::getData( 263 uint32_t *type, const void **data, size_t *size) const { 264 *type = mType; 265 *size = mSize; 266 *data = storage(); 267} 268 269void MetaData::typed_data::allocateStorage(size_t size) { 270 mSize = size; 271 272 if (usesReservoir()) { 273 return; 274 } 275 276 u.ext_data = malloc(mSize); 277} 278 279void MetaData::typed_data::freeStorage() { 280 if (!usesReservoir()) { 281 if (u.ext_data) { 282 free(u.ext_data); 283 } 284 } 285 286 mSize = 0; 287} 288 289String8 MetaData::typed_data::asString() const { 290 String8 out; 291 const void *data = storage(); 292 switch(mType) { 293 case TYPE_NONE: 294 out = String8::format("no type, size %d)", mSize); 295 break; 296 case TYPE_C_STRING: 297 out = String8::format("(char*) %s", (const char *)data); 298 break; 299 case TYPE_INT32: 300 out = String8::format("(int32_t) %d", *(int32_t *)data); 301 break; 302 case TYPE_INT64: 303 out = String8::format("(int64_t) %lld", *(int64_t *)data); 304 break; 305 case TYPE_FLOAT: 306 out = String8::format("(float) %f", *(float *)data); 307 break; 308 case TYPE_POINTER: 309 out = String8::format("(void*) %p", *(void **)data); 310 break; 311 case TYPE_RECT: 312 { 313 const Rect *r = (const Rect *)data; 314 out = String8::format("Rect(%d, %d, %d, %d)", 315 r->mLeft, r->mTop, r->mRight, r->mBottom); 316 break; 317 } 318 319 default: 320 out = String8::format("(unknown type %d, size %d)", mType, mSize); 321 break; 322 } 323 return out; 324} 325 326static void MakeFourCCString(uint32_t x, char *s) { 327 s[0] = x >> 24; 328 s[1] = (x >> 16) & 0xff; 329 s[2] = (x >> 8) & 0xff; 330 s[3] = x & 0xff; 331 s[4] = '\0'; 332} 333 334void MetaData::dumpToLog() const { 335 for (int i = mItems.size(); --i >= 0;) { 336 int32_t key = mItems.keyAt(i); 337 char cc[5]; 338 MakeFourCCString(key, cc); 339 const typed_data &item = mItems.valueAt(i); 340 ALOGI("%s: %s", cc, item.asString().string()); 341 } 342} 343 344} // namespace android 345 346