• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <media/stagefright/ESDS.h>
18 
19 #include <string.h>
20 
21 namespace android {
22 
ESDS(const void * data,size_t size)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     memcpy(mData, data, size);
30 
31     mInitCheck = parse();
32 }
33 
~ESDS()34 ESDS::~ESDS() {
35     delete[] mData;
36     mData = NULL;
37 }
38 
InitCheck() const39 status_t ESDS::InitCheck() const {
40     return mInitCheck;
41 }
42 
getCodecSpecificInfo(const void ** data,size_t * size) const43 status_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 
skipDescriptorHeader(size_t offset,size_t size,uint8_t * tag,size_t * data_offset,size_t * data_size) const54 status_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 
parse()88 status_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 
parseESDescriptor(size_t offset,size_t size)106 status_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 
parseDecoderConfigDescriptor(size_t offset,size_t size)162 status_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 
197