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::findCString(uint32_t key, const char **value) { 74 uint32_t type; 75 const void *data; 76 size_t size; 77 if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) { 78 return false; 79 } 80 81 *value = (const char *)data; 82 83 return true; 84} 85 86bool MetaData::findInt32(uint32_t key, int32_t *value) { 87 uint32_t type; 88 const void *data; 89 size_t size; 90 if (!findData(key, &type, &data, &size) || type != TYPE_INT32) { 91 return false; 92 } 93 94 CHECK_EQ(size, sizeof(*value)); 95 96 *value = *(int32_t *)data; 97 98 return true; 99} 100 101bool MetaData::findInt64(uint32_t key, int64_t *value) { 102 uint32_t type; 103 const void *data; 104 size_t size; 105 if (!findData(key, &type, &data, &size) || type != TYPE_INT64) { 106 return false; 107 } 108 109 CHECK_EQ(size, sizeof(*value)); 110 111 *value = *(int64_t *)data; 112 113 return true; 114} 115 116bool MetaData::findFloat(uint32_t key, float *value) { 117 uint32_t type; 118 const void *data; 119 size_t size; 120 if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) { 121 return false; 122 } 123 124 CHECK_EQ(size, sizeof(*value)); 125 126 *value = *(float *)data; 127 128 return true; 129} 130 131bool MetaData::findPointer(uint32_t key, void **value) { 132 uint32_t type; 133 const void *data; 134 size_t size; 135 if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) { 136 return false; 137 } 138 139 CHECK_EQ(size, sizeof(*value)); 140 141 *value = *(void **)data; 142 143 return true; 144} 145 146bool MetaData::setData( 147 uint32_t key, uint32_t type, const void *data, size_t size) { 148 bool overwrote_existing = true; 149 150 ssize_t i = mItems.indexOfKey(key); 151 if (i < 0) { 152 typed_data item; 153 i = mItems.add(key, item); 154 155 overwrote_existing = false; 156 } 157 158 typed_data &item = mItems.editValueAt(i); 159 160 item.setData(type, data, size); 161 162 return overwrote_existing; 163} 164 165bool MetaData::findData(uint32_t key, uint32_t *type, 166 const void **data, size_t *size) const { 167 ssize_t i = mItems.indexOfKey(key); 168 169 if (i < 0) { 170 return false; 171 } 172 173 const typed_data &item = mItems.valueAt(i); 174 175 item.getData(type, data, size); 176 177 return true; 178} 179 180MetaData::typed_data::typed_data() 181 : mType(0), 182 mSize(0) { 183} 184 185MetaData::typed_data::~typed_data() { 186 clear(); 187} 188 189MetaData::typed_data::typed_data(const typed_data &from) 190 : mType(from.mType), 191 mSize(0) { 192 allocateStorage(from.mSize); 193 memcpy(storage(), from.storage(), mSize); 194} 195 196MetaData::typed_data &MetaData::typed_data::operator=( 197 const MetaData::typed_data &from) { 198 if (this != &from) { 199 clear(); 200 mType = from.mType; 201 allocateStorage(from.mSize); 202 memcpy(storage(), from.storage(), mSize); 203 } 204 205 return *this; 206} 207 208void MetaData::typed_data::clear() { 209 freeStorage(); 210 211 mType = 0; 212} 213 214void MetaData::typed_data::setData( 215 uint32_t type, const void *data, size_t size) { 216 clear(); 217 218 mType = type; 219 allocateStorage(size); 220 memcpy(storage(), data, size); 221} 222 223void MetaData::typed_data::getData( 224 uint32_t *type, const void **data, size_t *size) const { 225 *type = mType; 226 *size = mSize; 227 *data = storage(); 228} 229 230void MetaData::typed_data::allocateStorage(size_t size) { 231 mSize = size; 232 233 if (usesReservoir()) { 234 return; 235 } 236 237 u.ext_data = malloc(mSize); 238} 239 240void MetaData::typed_data::freeStorage() { 241 if (!usesReservoir()) { 242 if (u.ext_data) { 243 free(u.ext_data); 244 } 245 } 246 247 mSize = 0; 248} 249 250} // namespace android 251 252