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 "ESDS" 19 #include <utils/Log.h> 20 21 #include <media/stagefright/Utils.h> 22 23 #include "include/ESDS.h" 24 25 #include <string.h> 26 27 namespace android { 28 29 ESDS::ESDS(const void *data, size_t size) 30 : mData(new uint8_t[size]), 31 mSize(size), 32 mInitCheck(NO_INIT), 33 mDecoderSpecificOffset(0), 34 mDecoderSpecificLength(0), 35 mObjectTypeIndication(0) { 36 memcpy(mData, data, size); 37 38 mInitCheck = parse(); 39 } 40 41 ESDS::~ESDS() { 42 delete[] mData; 43 mData = NULL; 44 } 45 46 status_t ESDS::InitCheck() const { 47 return mInitCheck; 48 } 49 50 status_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const { 51 if (mInitCheck != OK) { 52 return mInitCheck; 53 } 54 55 *objectTypeIndication = mObjectTypeIndication; 56 57 return OK; 58 } 59 60 status_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const { 61 if (mInitCheck != OK) { 62 return mInitCheck; 63 } 64 65 *data = &mData[mDecoderSpecificOffset]; 66 *size = mDecoderSpecificLength; 67 68 return OK; 69 } 70 71 status_t ESDS::skipDescriptorHeader( 72 size_t offset, size_t size, 73 uint8_t *tag, size_t *data_offset, size_t *data_size) const { 74 if (size == 0) { 75 return ERROR_MALFORMED; 76 } 77 78 *tag = mData[offset++]; 79 --size; 80 81 *data_size = 0; 82 bool more; 83 do { 84 if (size == 0) { 85 return ERROR_MALFORMED; 86 } 87 88 uint8_t x = mData[offset++]; 89 --size; 90 91 *data_size = (*data_size << 7) | (x & 0x7f); 92 more = (x & 0x80) != 0; 93 } 94 while (more); 95 96 ALOGV("tag=0x%02x data_size=%zu", *tag, *data_size); 97 98 if (*data_size > size) { 99 return ERROR_MALFORMED; 100 } 101 102 *data_offset = offset; 103 104 return OK; 105 } 106 107 status_t ESDS::parse() { 108 uint8_t tag; 109 size_t data_offset; 110 size_t data_size; 111 status_t err = 112 skipDescriptorHeader(0, mSize, &tag, &data_offset, &data_size); 113 114 if (err != OK) { 115 return err; 116 } 117 118 if (tag != kTag_ESDescriptor) { 119 return ERROR_MALFORMED; 120 } 121 122 return parseESDescriptor(data_offset, data_size); 123 } 124 125 status_t ESDS::parseESDescriptor(size_t offset, size_t size) { 126 if (size < 3) { 127 return ERROR_MALFORMED; 128 } 129 130 offset += 2; // skip ES_ID 131 size -= 2; 132 133 unsigned streamDependenceFlag = mData[offset] & 0x80; 134 unsigned URL_Flag = mData[offset] & 0x40; 135 unsigned OCRstreamFlag = mData[offset] & 0x20; 136 137 ++offset; 138 --size; 139 140 if (streamDependenceFlag) { 141 if (size < 2) 142 return ERROR_MALFORMED; 143 offset += 2; 144 size -= 2; 145 } 146 147 if (URL_Flag) { 148 if (offset >= size) { 149 return ERROR_MALFORMED; 150 } 151 unsigned URLlength = mData[offset]; 152 if (URLlength >= size) 153 return ERROR_MALFORMED; 154 offset += URLlength + 1; 155 size -= URLlength + 1; 156 } 157 158 if (OCRstreamFlag) { 159 if (size < 2) 160 return ERROR_MALFORMED; 161 offset += 2; 162 size -= 2; 163 164 if ((offset >= size || mData[offset] != kTag_DecoderConfigDescriptor) 165 && offset - 2 < size 166 && mData[offset - 2] == kTag_DecoderConfigDescriptor) { 167 // Content found "in the wild" had OCRstreamFlag set but was 168 // missing OCR_ES_Id, the decoder config descriptor immediately 169 // followed instead. 170 offset -= 2; 171 size += 2; 172 173 ALOGW("Found malformed 'esds' atom, ignoring missing OCR_ES_Id."); 174 } 175 } 176 177 if (offset >= size) { 178 return ERROR_MALFORMED; 179 } 180 181 uint8_t tag; 182 size_t sub_offset, sub_size; 183 status_t err = skipDescriptorHeader( 184 offset, size, &tag, &sub_offset, &sub_size); 185 186 if (err != OK) { 187 return err; 188 } 189 190 if (tag != kTag_DecoderConfigDescriptor) { 191 return ERROR_MALFORMED; 192 } 193 194 err = parseDecoderConfigDescriptor(sub_offset, sub_size); 195 196 return err; 197 } 198 199 status_t ESDS::getBitRate(uint32_t *brateMax, uint32_t *brateAvg) const { 200 if (mInitCheck != OK) { 201 return mInitCheck; 202 } 203 204 *brateMax = mBitRateMax; 205 *brateAvg = mBitRateAvg; 206 207 return OK; 208 }; 209 210 status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) { 211 if (size < 13) { 212 return ERROR_MALFORMED; 213 } 214 215 mObjectTypeIndication = mData[offset]; 216 mBitRateMax = U32_AT(mData + offset + 5); 217 mBitRateAvg = U32_AT(mData + offset + 9); 218 219 offset += 13; 220 size -= 13; 221 222 if (size == 0) { 223 mDecoderSpecificOffset = 0; 224 mDecoderSpecificLength = 0; 225 return OK; 226 } 227 228 uint8_t tag; 229 size_t sub_offset, sub_size; 230 status_t err = skipDescriptorHeader( 231 offset, size, &tag, &sub_offset, &sub_size); 232 233 if (err != OK) { 234 return err; 235 } 236 237 if (tag != kTag_DecoderSpecificInfo) { 238 return ERROR_MALFORMED; 239 } 240 241 mDecoderSpecificOffset = sub_offset; 242 mDecoderSpecificLength = sub_size; 243 244 return OK; 245 } 246 247 } // namespace android 248 249