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