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 "include/ESDS.h"
     18 
     19 #include <string.h>
     20 
     21 namespace android {
     22 
     23 ESDS::ESDS(const void *data, size_t size)
     24     : mData(new uint8_t[size]),
     25       mSize(size),
     26       mInitCheck(NO_INIT),
     27       mDecoderSpecificOffset(0),
     28       mDecoderSpecificLength(0),
     29       mObjectTypeIndication(0) {
     30     memcpy(mData, data, size);
     31 
     32     mInitCheck = parse();
     33 }
     34 
     35 ESDS::~ESDS() {
     36     delete[] mData;
     37     mData = NULL;
     38 }
     39 
     40 status_t ESDS::InitCheck() const {
     41     return mInitCheck;
     42 }
     43 
     44 status_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const {
     45     if (mInitCheck != OK) {
     46         return mInitCheck;
     47     }
     48 
     49     *objectTypeIndication = mObjectTypeIndication;
     50 
     51     return OK;
     52 }
     53 
     54 status_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const {
     55     if (mInitCheck != OK) {
     56         return mInitCheck;
     57     }
     58 
     59     *data = &mData[mDecoderSpecificOffset];
     60     *size = mDecoderSpecificLength;
     61 
     62     return OK;
     63 }
     64 
     65 status_t ESDS::skipDescriptorHeader(
     66         size_t offset, size_t size,
     67         uint8_t *tag, size_t *data_offset, size_t *data_size) const {
     68     if (size == 0) {
     69         return ERROR_MALFORMED;
     70     }
     71 
     72     *tag = mData[offset++];
     73     --size;
     74 
     75     *data_size = 0;
     76     bool more;
     77     do {
     78         if (size == 0) {
     79             return ERROR_MALFORMED;
     80         }
     81 
     82         uint8_t x = mData[offset++];
     83         --size;
     84 
     85         *data_size = (*data_size << 7) | (x & 0x7f);
     86         more = (x & 0x80) != 0;
     87     }
     88     while (more);
     89 
     90     if (*data_size > size) {
     91         return ERROR_MALFORMED;
     92     }
     93 
     94     *data_offset = offset;
     95 
     96     return OK;
     97 }
     98 
     99 status_t ESDS::parse() {
    100     uint8_t tag;
    101     size_t data_offset;
    102     size_t data_size;
    103     status_t err =
    104         skipDescriptorHeader(0, mSize, &tag, &data_offset, &data_size);
    105 
    106     if (err != OK) {
    107         return err;
    108     }
    109 
    110     if (tag != kTag_ESDescriptor) {
    111         return ERROR_MALFORMED;
    112     }
    113 
    114     return parseESDescriptor(data_offset, data_size);
    115 }
    116 
    117 status_t ESDS::parseESDescriptor(size_t offset, size_t size) {
    118     if (size < 3) {
    119         return ERROR_MALFORMED;
    120     }
    121 
    122     offset += 2;  // skip ES_ID
    123     size -= 2;
    124 
    125     unsigned streamDependenceFlag = mData[offset] & 0x80;
    126     unsigned URL_Flag = mData[offset] & 0x40;
    127     unsigned OCRstreamFlag = mData[offset] & 0x20;
    128 
    129     ++offset;
    130     --size;
    131 
    132     if (streamDependenceFlag) {
    133         offset += 2;
    134         size -= 2;
    135     }
    136 
    137     if (URL_Flag) {
    138         if (offset >= size) {
    139             return ERROR_MALFORMED;
    140         }
    141         unsigned URLlength = mData[offset];
    142         offset += URLlength + 1;
    143         size -= URLlength + 1;
    144     }
    145 
    146     if (OCRstreamFlag) {
    147         offset += 2;
    148         size -= 2;
    149     }
    150 
    151     if (offset >= size) {
    152         return ERROR_MALFORMED;
    153     }
    154 
    155     uint8_t tag;
    156     size_t sub_offset, sub_size;
    157     status_t err = skipDescriptorHeader(
    158             offset, size, &tag, &sub_offset, &sub_size);
    159 
    160     if (err != OK) {
    161         return err;
    162     }
    163 
    164     if (tag != kTag_DecoderConfigDescriptor) {
    165         return ERROR_MALFORMED;
    166     }
    167 
    168     err = parseDecoderConfigDescriptor(sub_offset, sub_size);
    169 
    170     return err;
    171 }
    172 
    173 status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) {
    174     if (size < 13) {
    175         return ERROR_MALFORMED;
    176     }
    177 
    178     mObjectTypeIndication = mData[offset];
    179 
    180     offset += 13;
    181     size -= 13;
    182 
    183     if (size == 0) {
    184         mDecoderSpecificOffset = 0;
    185         mDecoderSpecificLength = 0;
    186         return OK;
    187     }
    188 
    189     uint8_t tag;
    190     size_t sub_offset, sub_size;
    191     status_t err = skipDescriptorHeader(
    192             offset, size, &tag, &sub_offset, &sub_size);
    193 
    194     if (err != OK) {
    195         return err;
    196     }
    197 
    198     if (tag != kTag_DecoderSpecificInfo) {
    199         return ERROR_MALFORMED;
    200     }
    201 
    202     mDecoderSpecificOffset = sub_offset;
    203     mDecoderSpecificLength = sub_size;
    204 
    205     return OK;
    206 }
    207 
    208 }  // namespace android
    209 
    210