blob: 28d338ca57967fadb2c1c0e0fa1091355c43932d [file] [log] [blame]
Andreas Hubere46b7be2009-07-14 16:56:47 -07001/*
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
Andreas Huberbd7b43b2009-10-13 10:22:55 -070017#include "include/ESDS.h"
Andreas Hubere46b7be2009-07-14 16:56:47 -070018
19#include <string.h>
20
21namespace android {
22
23ESDS::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 memcpy(mData, data, size);
30
31 mInitCheck = parse();
32}
33
34ESDS::~ESDS() {
35 delete[] mData;
36 mData = NULL;
37}
38
39status_t ESDS::InitCheck() const {
40 return mInitCheck;
41}
42
43status_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const {
44 if (mInitCheck != OK) {
45 return mInitCheck;
46 }
47
48 *data = &mData[mDecoderSpecificOffset];
49 *size = mDecoderSpecificLength;
50
51 return OK;
52}
53
54status_t ESDS::skipDescriptorHeader(
55 size_t offset, size_t size,
56 uint8_t *tag, size_t *data_offset, size_t *data_size) const {
57 if (size == 0) {
58 return ERROR_MALFORMED;
59 }
60
61 *tag = mData[offset++];
62 --size;
63
64 *data_size = 0;
65 bool more;
66 do {
67 if (size == 0) {
68 return ERROR_MALFORMED;
69 }
70
71 uint8_t x = mData[offset++];
72 --size;
73
74 *data_size = (*data_size << 7) | (x & 0x7f);
75 more = (x & 0x80) != 0;
76 }
77 while (more);
78
79 if (*data_size > size) {
80 return ERROR_MALFORMED;
81 }
82
83 *data_offset = offset;
84
85 return OK;
86}
87
88status_t ESDS::parse() {
89 uint8_t tag;
90 size_t data_offset;
91 size_t data_size;
92 status_t err =
93 skipDescriptorHeader(0, mSize, &tag, &data_offset, &data_size);
94
95 if (err != OK) {
96 return err;
97 }
98
99 if (tag != kTag_ESDescriptor) {
100 return ERROR_MALFORMED;
101 }
102
103 return parseESDescriptor(data_offset, data_size);
104}
105
106status_t ESDS::parseESDescriptor(size_t offset, size_t size) {
107 if (size < 3) {
108 return ERROR_MALFORMED;
109 }
110
111 offset += 2; // skip ES_ID
112 size -= 2;
113
114 unsigned streamDependenceFlag = mData[offset] & 0x80;
115 unsigned URL_Flag = mData[offset] & 0x40;
116 unsigned OCRstreamFlag = mData[offset] & 0x20;
117
118 ++offset;
119 --size;
120
121 if (streamDependenceFlag) {
122 offset += 2;
123 size -= 2;
124 }
125
126 if (URL_Flag) {
127 if (offset >= size) {
128 return ERROR_MALFORMED;
129 }
130 unsigned URLlength = mData[offset];
131 offset += URLlength + 1;
132 size -= URLlength + 1;
133 }
134
135 if (OCRstreamFlag) {
136 offset += 2;
137 size -= 2;
138 }
139
140 if (offset >= size) {
141 return ERROR_MALFORMED;
142 }
143
144 uint8_t tag;
145 size_t sub_offset, sub_size;
146 status_t err = skipDescriptorHeader(
147 offset, size, &tag, &sub_offset, &sub_size);
148
149 if (err != OK) {
150 return err;
151 }
152
153 if (tag != kTag_DecoderConfigDescriptor) {
154 return ERROR_MALFORMED;
155 }
156
157 err = parseDecoderConfigDescriptor(sub_offset, sub_size);
158
159 return err;
160}
161
162status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) {
163 if (size < 13) {
164 return ERROR_MALFORMED;
165 }
166
167 offset += 13;
168 size -= 13;
169
170 if (size == 0) {
171 mDecoderSpecificOffset = 0;
172 mDecoderSpecificLength = 0;
173 return OK;
174 }
175
176 uint8_t tag;
177 size_t sub_offset, sub_size;
178 status_t err = skipDescriptorHeader(
179 offset, size, &tag, &sub_offset, &sub_size);
180
181 if (err != OK) {
182 return err;
183 }
184
185 if (tag != kTag_DecoderSpecificInfo) {
186 return ERROR_MALFORMED;
187 }
188
189 mDecoderSpecificOffset = sub_offset;
190 mDecoderSpecificLength = sub_size;
191
192 return OK;
193}
194
195} // namespace android
196