OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / media / libstagefright / ESDS.cpp
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