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