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::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