ESDS.cpp revision 3856b090cd04ba5dd4a59a12430ed724d5995909
1a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk/* 2a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * Copyright (C) 2009 The Android Open Source Project 3a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * 4a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License"); 5a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * you may not use this file except in compliance with the License. 6a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * You may obtain a copy of the License at 7a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * 8a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * http://www.apache.org/licenses/LICENSE-2.0 9a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * 10a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software 11a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS, 12a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * See the License for the specific language governing permissions and 14a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * limitations under the License. 15a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk */ 16a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 17a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk//#define LOG_NDEBUG 0 18a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#define LOG_TAG "ESDS" 19a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include <utils/Log.h> 202382aba4a55c6ae74789c478eead8fbd96593321Jason Sams 21a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include "include/ESDS.h" 22a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 23a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include <string.h> 24a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 25a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouknamespace android { 26a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 27a94952436aeb251f587c1bccdf94c7f75285dfe2Alex SakhartchoukESDS::ESDS(const void *data, size_t size) 28a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk : mData(new uint8_t[size]), 29a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk mSize(size), 30a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk mInitCheck(NO_INIT), 31a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk mDecoderSpecificOffset(0), 32a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk mDecoderSpecificLength(0), 33a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk mObjectTypeIndication(0) { 34a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk memcpy(mData, data, size); 35a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 36a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk mInitCheck = parse(); 37a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk} 38a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 39a94952436aeb251f587c1bccdf94c7f75285dfe2Alex SakhartchoukESDS::~ESDS() { 40a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk delete[] mData; 41a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk mData = NULL; 42a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk} 43a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 44a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatus_t ESDS::InitCheck() const { 45a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return mInitCheck; 46a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk} 47a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 48a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatus_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const { 49a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (mInitCheck != OK) { 50a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return mInitCheck; 51a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 52a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 53a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *objectTypeIndication = mObjectTypeIndication; 54a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 55a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return OK; 56a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk} 57a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 58a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatus_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const { 59a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (mInitCheck != OK) { 60a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return mInitCheck; 61a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 62a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 63a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *data = &mData[mDecoderSpecificOffset]; 64a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *size = mDecoderSpecificLength; 65a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 66a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return OK; 67a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk} 68a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 69a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatus_t ESDS::skipDescriptorHeader( 70a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk size_t offset, size_t size, 71a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk uint8_t *tag, size_t *data_offset, size_t *data_size) const { 72a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (size == 0) { 73a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return ERROR_MALFORMED; 74a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 75a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 76a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *tag = mData[offset++]; 77a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk --size; 78a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 79a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *data_size = 0; 80a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk bool more; 81a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk do { 82a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (size == 0) { 83a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return ERROR_MALFORMED; 84a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 85a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 86a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk uint8_t x = mData[offset++]; 87a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk --size; 88a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 89a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *data_size = (*data_size << 7) | (x & 0x7f); 90a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk more = (x & 0x80) != 0; 91a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 92a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk while (more); 93a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 94a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk ALOGV("tag=0x%02x data_size=%d", *tag, *data_size); 95a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 96a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (*data_size > size) { 97a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return ERROR_MALFORMED; 98a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 99a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 100a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *data_offset = offset; 101a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 102a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return OK; 103a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk} 104a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 105a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatus_t ESDS::parse() { 106a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk uint8_t tag; 107a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk size_t data_offset; 108a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk size_t data_size; 109a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk status_t err = 110a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk skipDescriptorHeader(0, mSize, &tag, &data_offset, &data_size); 111a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 112a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (err != OK) { 113a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return err; 114a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 115a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 116a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (tag != kTag_ESDescriptor) { 117a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return ERROR_MALFORMED; 118a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 119a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 120a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return parseESDescriptor(data_offset, data_size); 121a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk} 122a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 123a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatus_t ESDS::parseESDescriptor(size_t offset, size_t size) { 124a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (size < 3) { 125a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk return ERROR_MALFORMED; 126a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk } 127a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 1282382aba4a55c6ae74789c478eead8fbd96593321Jason Sams offset += 2; // skip ES_ID 129a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk size -= 2; 1302382aba4a55c6ae74789c478eead8fbd96593321Jason Sams 131a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk unsigned streamDependenceFlag = mData[offset] & 0x80; 132a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk unsigned URL_Flag = mData[offset] & 0x40; 133a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk unsigned OCRstreamFlag = mData[offset] & 0x20; 134a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 135a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk ++offset; 136a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk --size; 137a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 1382382aba4a55c6ae74789c478eead8fbd96593321Jason Sams if (streamDependenceFlag) { 139a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk offset += 2; 140a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk size -= 2; 1412382aba4a55c6ae74789c478eead8fbd96593321Jason Sams } 1422382aba4a55c6ae74789c478eead8fbd96593321Jason Sams 143a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk if (URL_Flag) { 144a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk 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 191status_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