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