1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/*
2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License.
6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at
7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software
11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and
14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License.
15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */
16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
17bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber#include "include/ESDS.h"
18e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <string.h>
20e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
21e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android {
22e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
23e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberESDS::ESDS(const void *data, size_t size)
24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mData(new uint8_t[size]),
25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mSize(size),
26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mInitCheck(NO_INIT),
27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mDecoderSpecificOffset(0),
28d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber      mDecoderSpecificLength(0),
29d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber      mObjectTypeIndication(0) {
30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    memcpy(mData, data, size);
31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mInitCheck = parse();
33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
35e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberESDS::~ESDS() {
36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    delete[] mData;
37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mData = NULL;
38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t ESDS::InitCheck() const {
41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mInitCheck;
42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
44d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huberstatus_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const {
45d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber    if (mInitCheck != OK) {
46d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber        return mInitCheck;
47d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber    }
48d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber
49d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber    *objectTypeIndication = mObjectTypeIndication;
50d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber
51d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber    return OK;
52d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber}
53d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber
54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const {
55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mInitCheck != OK) {
56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return mInitCheck;
57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *data = &mData[mDecoderSpecificOffset];
60e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *size = mDecoderSpecificLength;
61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t ESDS::skipDescriptorHeader(
66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size_t offset, size_t size,
67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint8_t *tag, size_t *data_offset, size_t *data_size) const {
68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (size == 0) {
69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
72e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *tag = mData[offset++];
73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    --size;
74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *data_size = 0;
76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool more;
77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    do {
78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (size == 0) {
79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_MALFORMED;
80e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint8_t x = mData[offset++];
83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        --size;
84e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
85e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *data_size = (*data_size << 7) | (x & 0x7f);
86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        more = (x & 0x80) != 0;
87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (more);
89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (*data_size > size) {
91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
93e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *data_offset = offset;
95e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
97e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t ESDS::parse() {
100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint8_t tag;
101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t data_offset;
102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t data_size;
103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err =
104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        skipDescriptorHeader(0, mSize, &tag, &data_offset, &data_size);
105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (err != OK) {
107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return err;
108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (tag != kTag_ESDescriptor) {
111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return parseESDescriptor(data_offset, data_size);
115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t ESDS::parseESDescriptor(size_t offset, size_t size) {
118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (size < 3) {
119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    offset += 2;  // skip ES_ID
123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size -= 2;
124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned streamDependenceFlag = mData[offset] & 0x80;
126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned URL_Flag = mData[offset] & 0x40;
127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    unsigned OCRstreamFlag = mData[offset] & 0x20;
128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    ++offset;
130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    --size;
131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (streamDependenceFlag) {
133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        offset += 2;
134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size -= 2;
135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (URL_Flag) {
138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (offset >= size) {
139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_MALFORMED;
140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        unsigned URLlength = mData[offset];
142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        offset += URLlength + 1;
143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size -= URLlength + 1;
144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (OCRstreamFlag) {
147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        offset += 2;
148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size -= 2;
149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (offset >= size) {
152e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
155e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint8_t tag;
156e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t sub_offset, sub_size;
157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err = skipDescriptorHeader(
158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            offset, size, &tag, &sub_offset, &sub_size);
159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
160e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (err != OK) {
161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return err;
162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (tag != kTag_DecoderConfigDescriptor) {
165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    err = parseDecoderConfigDescriptor(sub_offset, sub_size);
169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return err;
171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
173e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) {
174e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (size < 13) {
175e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
176e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
177e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
178d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber    mObjectTypeIndication = mData[offset];
179d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber
180e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    offset += 13;
181e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size -= 13;
182e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
183e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (size == 0) {
184e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mDecoderSpecificOffset = 0;
185e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mDecoderSpecificLength = 0;
186e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return OK;
187e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
188e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
189e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint8_t tag;
190e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t sub_offset, sub_size;
191e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err = skipDescriptorHeader(
192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            offset, size, &tag, &sub_offset, &sub_size);
193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (err != OK) {
195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return err;
196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (tag != kTag_DecoderSpecificInfo) {
199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_MALFORMED;
200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mDecoderSpecificOffset = sub_offset;
203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mDecoderSpecificLength = sub_size;
204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
205e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
210