Home | History | Annotate | Download | only in libstagefright
      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::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 
     86 bool 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 
    101 bool 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 
    116 bool 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 
    131 bool 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 
    146 bool 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 
    165 bool 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 
    180 MetaData::typed_data::typed_data()
    181     : mType(0),
    182       mSize(0) {
    183 }
    184 
    185 MetaData::typed_data::~typed_data() {
    186     clear();
    187 }
    188 
    189 MetaData::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 
    196 MetaData::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 
    208 void MetaData::typed_data::clear() {
    209     freeStorage();
    210 
    211     mType = 0;
    212 }
    213 
    214 void 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 
    223 void 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 
    230 void 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 
    240 void 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