APacketSource.cpp revision 4dba3e90f211eb5f5af19b10c5d3fc8c967b0086
1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/*
2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License.
6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at
7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and
14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License.
15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */
16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
17cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "APacketSource.h"
18cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
19cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h"
20cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2185f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include "avc_utils.h"
2285f12e9b9062402d6110df3f7099707912040edbAndreas Huber
23ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber#include <ctype.h>
24ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber
2562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber#include <media/stagefright/foundation/ABitReader.h>
26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h>
29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h>
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/base64.h>
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaBuffer.h>
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaDefs.h>
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MetaData.h>
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <utils/Vector.h>
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool GetAttribute(const char *s, const char *key, AString *value) {
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    value->clear();
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t keyLen = strlen(key);
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
45ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        while (isspace(*s)) {
46ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            ++s;
47ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
48ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const char *colonPos = strchr(s, ';');
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t len =
52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            (colonPos == NULL) ? strlen(s) : colonPos - s;
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value->setTo(&s[keyLen + 1], len - keyLen - 1);
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return true;
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (colonPos == NULL) {
60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return false;
61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        s = colonPos + 1;
64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic sp<ABuffer> decodeHex(const AString &s) {
68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if ((s.size() % 2) != 0) {
69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return NULL;
70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t outLen = s.size() / 2;
73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> buffer = new ABuffer(outLen);
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t *out = buffer->data();
75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t accum = 0;
77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < s.size(); ++i) {
78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        char c = s.c_str()[i];
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        unsigned value;
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (c >= '0' && c <= '9') {
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - '0';
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (c >= 'a' && c <= 'f') {
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - 'a' + 10;
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (c >= 'A' && c <= 'F') {
85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - 'A' + 10;
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else {
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return NULL;
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        accum = (accum << 4) | value;
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (i & 1) {
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            *out++ = accum;
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            accum = 0;
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return buffer;
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
10285f12e9b9062402d6110df3f7099707912040edbAndreas Huberstatic sp<ABuffer> MakeAVCCodecSpecificData(
10385f12e9b9062402d6110df3f7099707912040edbAndreas Huber        const char *params, int32_t *width, int32_t *height) {
10485f12e9b9062402d6110df3f7099707912040edbAndreas Huber    *width = 0;
10585f12e9b9062402d6110df3f7099707912040edbAndreas Huber    *height = 0;
10685f12e9b9062402d6110df3f7099707912040edbAndreas Huber
107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString val;
10833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    if (!GetAttribute(params, "profile-level-id", &val)) {
10933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        return NULL;
11033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    }
111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> profileLevelID = decodeHex(val);
113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(profileLevelID != NULL);
114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(profileLevelID->size(), 3u);
115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Vector<sp<ABuffer> > paramSets;
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t numSeqParameterSets = 0;
119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalSeqParameterSetSize = 0;
120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t numPicParameterSets = 0;
121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalPicParameterSetSize = 0;
122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
12333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
12433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        return NULL;
12533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    }
12633a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber
127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t start = 0;
128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ssize_t commaPos = val.find(",", start);
130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t end = (commaPos < 0) ? val.size() : commaPos;
131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        AString nalString(val, start, end - start);
133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = decodeBase64(nalString);
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK(nal != NULL);
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_GT(nal->size(), 0u);
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_LE(nal->size(), 65535u);
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint8_t nalType = nal->data()[0] & 0x1f;
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (numSeqParameterSets == 0) {
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 7u);
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (numPicParameterSets > 0) {
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 8u);
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (nalType == 7) {
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++numSeqParameterSets;
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            totalSeqParameterSetSize += nal->size();
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else  {
148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 8u);
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++numPicParameterSets;
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            totalPicParameterSetSize += nal->size();
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        paramSets.push(nal);
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (commaPos < 0) {
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        start = commaPos + 1;
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LT(numSeqParameterSets, 32u);
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LE(numPicParameterSets, 255u);
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t csdSize =
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        1 + 3 + 1 + 1
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        + 2 * numSeqParameterSets + totalSeqParameterSetSize
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        + 1 + 2 * numPicParameterSets + totalPicParameterSetSize;
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> csd = new ABuffer(csdSize);
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t *out = csd->data();
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = 0x01;  // configurationVersion
174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    memcpy(out, profileLevelID->data(), 3);
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    out += 3;
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = 0xe0 | numSeqParameterSets;
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < numSeqParameterSets; ++i) {
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = paramSets.editItemAt(i);
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() >> 8;
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() & 0xff;
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(out, nal->data(), nal->size());
186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        out += nal->size();
18885f12e9b9062402d6110df3f7099707912040edbAndreas Huber
18985f12e9b9062402d6110df3f7099707912040edbAndreas Huber        if (i == 0) {
19085f12e9b9062402d6110df3f7099707912040edbAndreas Huber            FindAVCDimensions(nal, width, height);
19185f12e9b9062402d6110df3f7099707912040edbAndreas Huber            LOG(INFO) << "dimensions " << *width << "x" << *height;
19285f12e9b9062402d6110df3f7099707912040edbAndreas Huber        }
193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = numPicParameterSets;
196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < numPicParameterSets; ++i) {
198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets);
199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() >> 8;
201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() & 0xff;
202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(out, nal->data(), nal->size());
204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        out += nal->size();
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
20885f12e9b9062402d6110df3f7099707912040edbAndreas Huber    // hexdump(csd->data(), csd->size());
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return csd;
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<ABuffer> MakeAACCodecSpecificData(const char *params) {
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString val;
215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(GetAttribute(params, "config", &val));
216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> config = decodeHex(val);
218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(config != NULL);
219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(config->size(), 4u);
220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = config->data();
222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    x = (x >> 1) & 0xffff;
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    static const uint8_t kStaticESDS[] = {
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x03, 22,
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00,     // ES_ID
228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x04, 17,
231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x40,                       // Audio ISO/IEC 14496-3
232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x05, 2,
237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // AudioSpecificInfo follows
238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    };
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff;
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff;
244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
24585f12e9b9062402d6110df3f7099707912040edbAndreas Huber    // hexdump(csd->data(), csd->size());
246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return csd;
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2504dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber// From mpeg4-generic configuration data.
2514dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Hubersp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
2524dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    AString val;
2534dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    unsigned long objectType;
2544dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    if (GetAttribute(params, "objectType", &val)) {
2554dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        const char *s = val.c_str();
2564dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        char *end;
2574dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        objectType = strtoul(s, &end, 10);
2584dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        CHECK(end > s && *end == '\0');
2594dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    } else {
2604dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        objectType = 0x40;  // Audio ISO/IEC 14496-3
2614dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    }
2624dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2634dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    CHECK(GetAttribute(params, "config", &val));
2644dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2654dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    sp<ABuffer> config = decodeHex(val);
2664dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    CHECK(config != NULL);
2674dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2684dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    // Make sure size fits into a single byte and doesn't have to
2694dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    // be encoded.
2704dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    CHECK_LT(20 + config->size(), 128u);
2714dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2724dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    const uint8_t *data = config->data();
2734dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2744dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    static const uint8_t kStaticESDS[] = {
2754dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x03, 22,
2764dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00,     // ES_ID
2774dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
2784dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2794dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x04, 17,
2804dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x40,                       // Audio ISO/IEC 14496-3
2814dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00, 0x00, 0x00,
2824dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00, 0x00, 0x00,
2834dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00, 0x00, 0x00,
2844dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2854dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x05, 2,
2864dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        // AudioSpecificInfo follows
2874dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    };
2884dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2894dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
2904dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    uint8_t *dst = csd->data();
2914dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x03;
2924dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 20 + config->size();
2934dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x00;  // ES_ID
2944dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x00;
2954dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
2964dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x04;
2974dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 15 + config->size();
2984dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = objectType;
2994dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
3004dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x05;
3014dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = config->size();
3024dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    memcpy(dst, config->data(), config->size());
3034dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
3044dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    // hexdump(csd->data(), csd->size());
3054dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
3064dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    return csd;
3074dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber}
3084dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
30962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic size_t GetSizeWidth(size_t x) {
31062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t n = 1;
31162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    while (x > 127) {
31262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        ++n;
31362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        x >>= 7;
31462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
31562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    return n;
31662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
31762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
31862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) {
31962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    while (x > 127) {
32062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        *dst++ = (x & 0x7f) | 0x80;
32162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        x >>= 7;
32262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
32362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = x;
32462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    return dst;
32562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
32662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
32762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic bool ExtractDimensionsFromVOLHeader(
32862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        const sp<ABuffer> &config, int32_t *width, int32_t *height) {
32962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *width = 0;
33062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *height = 0;
33162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
33262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    const uint8_t *ptr = config->data();
33362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t offset = 0;
33462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    bool foundVOL = false;
33562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    while (offset + 3 < config->size()) {
33662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        if (memcmp("\x00\x00\x01", &ptr[offset], 3)
33762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                || (ptr[offset + 3] & 0xf0) != 0x20) {
33862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            ++offset;
33962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            continue;
34062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
34162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
34262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        foundVOL = true;
34362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        break;
34462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
34562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
34662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    if (!foundVOL) {
34762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        return false;
34862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
34962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
35062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    ABitReader br(&ptr[offset + 4], config->size() - offset - 4);
35162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    br.skipBits(1);  // random_accessible_vol
35262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned video_object_type_indication = br.getBits(8);
35362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
35462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK_NE(video_object_type_indication,
35562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber             0x21u /* Fine Granularity Scalable */);
35662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
35762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned video_object_layer_verid;
35862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned video_object_layer_priority;
35962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    if (br.getBits(1)) {
36062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        video_object_layer_verid = br.getBits(4);
36162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        video_object_layer_priority = br.getBits(3);
36262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
36362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned aspect_ratio_info = br.getBits(4);
36462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    if (aspect_ratio_info == 0x0f /* extended PAR */) {
36562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        br.skipBits(8);  // par_width
36662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        br.skipBits(8);  // par_height
36762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
36862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    if (br.getBits(1)) {  // vol_control_parameters
36962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        br.skipBits(2);  // chroma_format
37062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        br.skipBits(1);  // low_delay
37162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        if (br.getBits(1)) {  // vbv_parameters
37262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            TRESPASS();
37362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
37462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
37562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned video_object_layer_shape = br.getBits(2);
37662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */);
37762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
37862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(br.getBits(1));  // marker_bit
37962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned vop_time_increment_resolution = br.getBits(16);
38062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(br.getBits(1));  // marker_bit
38162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
38262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    if (br.getBits(1)) {  // fixed_vop_rate
38362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        // range [0..vop_time_increment_resolution)
38462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
38562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        // vop_time_increment_resolution
38662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        // 2 => 0..1, 1 bit
38762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        // 3 => 0..2, 2 bits
38862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        // 4 => 0..3, 2 bits
38962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        // 5 => 0..4, 3 bits
39062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        // ...
39162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
39262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        CHECK_GT(vop_time_increment_resolution, 0u);
39362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        --vop_time_increment_resolution;
39462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
39562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        unsigned numBits = 0;
39662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        while (vop_time_increment_resolution > 0) {
39762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            ++numBits;
39862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            vop_time_increment_resolution >>= 1;
39962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
40062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
40162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        br.skipBits(numBits);  // fixed_vop_time_increment
40262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
40362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
40462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(br.getBits(1));  // marker_bit
40562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned video_object_layer_width = br.getBits(13);
40662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(br.getBits(1));  // marker_bit
40762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned video_object_layer_height = br.getBits(13);
40862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(br.getBits(1));  // marker_bit
40962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
41062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    unsigned interlaced = br.getBits(1);
41162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
41262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *width = video_object_layer_width;
41362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *height = video_object_layer_height;
41462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
41562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    LOG(INFO) << "VOL dimensions = " << *width << "x" << *height;
41662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
41762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    return true;
41862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
41962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
42062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Hubersp<ABuffer> MakeMPEG4VideoCodecSpecificData(
42162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        const char *params, int32_t *width, int32_t *height) {
42262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *width = 0;
42362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *height = 0;
42462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
42562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    AString val;
42662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(GetAttribute(params, "config", &val));
42762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
42862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    sp<ABuffer> config = decodeHex(val);
42962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(config != NULL);
43062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
43162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    if (!ExtractDimensionsFromVOLHeader(config, width, height)) {
43262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        return NULL;
43362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
43462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
43562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
43662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
43762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
43862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
43962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    sp<ABuffer> csd = new ABuffer(len3);
44062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    uint8_t *dst = csd->data();
44162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x03;
44262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst = EncodeSize(dst, len2 + 3);
44362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x00;  // ES_ID
44462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x00;
44562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
44662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
44762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x04;
44862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst = EncodeSize(dst, len1 + 13);
44962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x01;  // Video ISO/IEC 14496-2 Simple Profile
45062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    for (size_t i = 0; i < 12; ++i) {
45162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        *dst++ = 0x00;
45262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
45362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
45462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x05;
45562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst = EncodeSize(dst, config->size());
45662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    memcpy(dst, config->data(), config->size());
45762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst += config->size();
45862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
45962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    // hexdump(csd->data(), csd->size());
46062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
46162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    return csd;
46262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
46362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
4648d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic bool GetClockRate(const AString &desc, uint32_t *clockRate) {
4658d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    ssize_t slashPos = desc.find("/");
4668d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    if (slashPos < 0) {
4678d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        return false;
4688d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    }
4698d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4708d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    const char *s = desc.c_str() + slashPos + 1;
4718d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4728d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    char *end;
4738d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    unsigned long x = strtoul(s, &end, 10);
4748d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4758d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    if (end == s || (*end != '\0' && *end != '/')) {
4768d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        return false;
4778d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    }
4788d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4798d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    *clockRate = x;
4808d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4818d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    return true;
4828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
4838d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
484cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::APacketSource(
485cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ASessionDescription> &sessionDesc, size_t index)
48639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    : mInitCheck(NO_INIT),
48739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mFormat(new MetaData),
4888d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mEOSResult(OK),
4898d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mRTPTimeBase(0),
4908d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mNormalPlayTimeBaseUs(0),
4918d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mLastNormalPlayTimeUs(0) {
492cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long PT;
493cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString desc;
494cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString params;
495cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sessionDesc->getFormatType(index, &PT, &desc, &params);
496cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
4978d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CHECK(GetClockRate(desc, &mClockRate));
4988d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
499cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int64_t durationUs;
500cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (sessionDesc->getDurationUs(&durationUs)) {
501cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt64(kKeyDuration, durationUs);
502cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
503cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll);
504cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
505cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
50639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mInitCheck = OK;
507cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!strncmp(desc.c_str(), "H264/", 5)) {
508cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
509cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
510cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t width, height;
511ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
51285f12e9b9062402d6110df3f7099707912040edbAndreas Huber            width = -1;
51385f12e9b9062402d6110df3f7099707912040edbAndreas Huber            height = -1;
514ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
515cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
51685f12e9b9062402d6110df3f7099707912040edbAndreas Huber        int32_t encWidth, encHeight;
517cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> codecSpecificData =
51885f12e9b9062402d6110df3f7099707912040edbAndreas Huber            MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight);
519cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
52033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        if (codecSpecificData != NULL) {
52185f12e9b9062402d6110df3f7099707912040edbAndreas Huber            if (width < 0) {
52285f12e9b9062402d6110df3f7099707912040edbAndreas Huber                // If no explicit width/height given in the sdp, use the dimensions
52385f12e9b9062402d6110df3f7099707912040edbAndreas Huber                // extracted from the first sequence parameter set.
52485f12e9b9062402d6110df3f7099707912040edbAndreas Huber                width = encWidth;
52585f12e9b9062402d6110df3f7099707912040edbAndreas Huber                height = encHeight;
52685f12e9b9062402d6110df3f7099707912040edbAndreas Huber            }
52785f12e9b9062402d6110df3f7099707912040edbAndreas Huber
52833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber            mFormat->setData(
52933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber                    kKeyAVCC, 0,
53033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber                    codecSpecificData->data(), codecSpecificData->size());
53185f12e9b9062402d6110df3f7099707912040edbAndreas Huber        } else if (width < 0) {
53285f12e9b9062402d6110df3f7099707912040edbAndreas Huber            mInitCheck = ERROR_UNSUPPORTED;
53385f12e9b9062402d6110df3f7099707912040edbAndreas Huber            return;
53433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        }
53585f12e9b9062402d6110df3f7099707912040edbAndreas Huber
53685f12e9b9062402d6110df3f7099707912040edbAndreas Huber        mFormat->setInt32(kKeyWidth, width);
53785f12e9b9062402d6110df3f7099707912040edbAndreas Huber        mFormat->setInt32(kKeyHeight, height);
53839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "H263-2000/", 10)
53939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            || !strncmp(desc.c_str(), "H263-1998/", 10)) {
54039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
541cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
54239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t width, height;
543ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
544ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
545ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            return;
546ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
54739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
54839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyWidth, width);
54939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyHeight, height);
55039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
551cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
552cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
553cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t sampleRate, numChannels;
554cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ASessionDescription::ParseFormatDesc(
555cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
556cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
557cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
558cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
559cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
560cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> codecSpecificData =
561cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            MakeAACCodecSpecificData(params.c_str());
562cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
563cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setData(
564cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                kKeyESDS, 0,
565cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                codecSpecificData->data(), codecSpecificData->size());
56639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
56739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
56839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
56939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t sampleRate, numChannels;
57039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ASessionDescription::ParseFormatDesc(
57139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
57239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
57339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
57439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
57539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
57639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (sampleRate != 8000 || numChannels != 1) {
57739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
57839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
57939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
58039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
58139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
58239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t sampleRate, numChannels;
58339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ASessionDescription::ParseFormatDesc(
58439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
58539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
58639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
58739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
58839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
58939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (sampleRate != 16000 || numChannels != 1) {
59039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
59139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
59262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
59362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
59462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
59562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        int32_t width, height;
59662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
59762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            width = -1;
59862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            height = -1;
59962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
60062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
60162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        int32_t encWidth, encHeight;
60262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        sp<ABuffer> codecSpecificData =
60362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            MakeMPEG4VideoCodecSpecificData(
60462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                    params.c_str(), &encWidth, &encHeight);
60562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
60662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        if (codecSpecificData != NULL) {
60762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            mFormat->setData(
60862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                    kKeyESDS, 0,
60962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                    codecSpecificData->data(), codecSpecificData->size());
61062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
61162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            if (width < 0) {
61262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                width = encWidth;
61362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                height = encHeight;
61462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            }
61562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        } else if (width < 0) {
61662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
61762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            return;
61862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
61962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
62062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        mFormat->setInt32(kKeyWidth, width);
62162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        mFormat->setInt32(kKeyHeight, height);
6224dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
6234dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        AString val;
6244dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        if (!GetAttribute(params.c_str(), "mode", &val)
6254dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                || (strcasecmp(val.c_str(), "AAC-lbr")
6264dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                    && strcasecmp(val.c_str(), "AAC-hbr"))) {
6274dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
6284dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber            return;
6294dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        }
6304dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
6314dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
6324dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
6334dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        int32_t sampleRate, numChannels;
6344dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        ASessionDescription::ParseFormatDesc(
6354dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
6364dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
6374dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
6384dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
6394dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
6404dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        sp<ABuffer> codecSpecificData =
6414dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber            MakeAACCodecSpecificData2(params.c_str());
6424dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
6434dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setData(
6444dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                kKeyESDS, 0,
6454dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                codecSpecificData->data(), codecSpecificData->size());
646cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
64739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mInitCheck = ERROR_UNSUPPORTED;
648cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
649cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
650cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
651cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::~APacketSource() {
652cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
653cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
65439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t APacketSource::initCheck() const {
65539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return mInitCheck;
65639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
65739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
658cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::start(MetaData *params) {
659cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
660cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
661cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
662cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::stop() {
663cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
664cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
665cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
666cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<MetaData> APacketSource::getFormat() {
667cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mFormat;
668cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
669cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
670cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::read(
671cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        MediaBuffer **out, const ReadOptions *) {
672cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out = NULL;
673cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
674cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
675cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (mEOSResult == OK && mBuffers.empty()) {
676cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mCondition.wait(mLock);
677cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
678cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
679cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!mBuffers.empty()) {
680cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ABuffer> buffer = *mBuffers.begin();
681cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
6828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        updateNormalPlayTime_l(buffer);
6838d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
68439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
68539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
686f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        int64_t timeUs;
687f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
688cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
689cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
69039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
691cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
692cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out = mediaBuffer;
693cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
694cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mBuffers.erase(mBuffers.begin());
695cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return OK;
696cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
697cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
698cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mEOSResult;
699cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
700cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
7018d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::updateNormalPlayTime_l(const sp<ABuffer> &buffer) {
7028d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    uint32_t rtpTime;
7038d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
7048d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
7058d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    mLastNormalPlayTimeUs =
7068d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        (((double)rtpTime - (double)mRTPTimeBase) / mClockRate)
7078d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber            * 1000000ll
7088d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber            + mNormalPlayTimeBaseUs;
7098d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
7108d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
711cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
712cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int32_t damaged;
713cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
7146dc387a8c3f031f9f17d1138295368946563f7a5Andreas Huber        LOG(VERBOSE) << "discarding damaged AU";
715cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return;
716cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
717cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
718cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
719cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mBuffers.push_back(buffer);
720cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mCondition.signal();
721cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
722cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
723cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::signalEOS(status_t result) {
724cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(result != OK);
725cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
726cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
727cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mEOSResult = result;
728cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mCondition.signal();
729cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
730cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
731cce326fe43411855aca2f719e505b051bc4b61b3Andreas Hubervoid APacketSource::flushQueue() {
73239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    Mutex::Autolock autoLock(mLock);
733cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber    mBuffers.clear();
73439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
73539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
7368d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberint64_t APacketSource::getNormalPlayTimeUs() {
7378d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    Mutex::Autolock autoLock(mLock);
7388d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    return mLastNormalPlayTimeUs;
7398d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
7408d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
7418d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::setNormalPlayTimeMapping(
7428d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        uint32_t rtpTime, int64_t normalPlayTimeUs) {
7438d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    Mutex::Autolock autoLock(mLock);
7448d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
7458d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    mRTPTimeBase = rtpTime;
7468d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    mNormalPlayTimeBaseUs = normalPlayTimeUs;
7478d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
7488d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
749cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
750