APacketSource.cpp revision 386d609dc513e838c7e7c4c46c604493ccd560be
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
176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0
186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "APacketSource"
196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h>
206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "APacketSource.h"
22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
23fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber#include "ARawAudioAssembler.h"
24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h"
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2685f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include "avc_utils.h"
2785f12e9b9062402d6110df3f7099707912040edbAndreas Huber
28ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber#include <ctype.h>
29ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber
3062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber#include <media/stagefright/foundation/ABitReader.h>
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h>
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h>
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/base64.h>
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/hexdump.h>
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaBuffer.h>
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaDefs.h>
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MetaData.h>
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <utils/Vector.h>
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool GetAttribute(const char *s, const char *key, AString *value) {
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    value->clear();
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t keyLen = strlen(key);
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
50ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        while (isspace(*s)) {
51ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            ++s;
52ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
53ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const char *colonPos = strchr(s, ';');
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t len =
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            (colonPos == NULL) ? strlen(s) : colonPos - s;
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value->setTo(&s[keyLen + 1], len - keyLen - 1);
61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return true;
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (colonPos == NULL) {
65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return false;
66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        s = colonPos + 1;
69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic sp<ABuffer> decodeHex(const AString &s) {
73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if ((s.size() % 2) != 0) {
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return NULL;
75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t outLen = s.size() / 2;
78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> buffer = new ABuffer(outLen);
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t *out = buffer->data();
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t accum = 0;
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < s.size(); ++i) {
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        char c = s.c_str()[i];
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        unsigned value;
85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (c >= '0' && c <= '9') {
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - '0';
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (c >= 'a' && c <= 'f') {
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - 'a' + 10;
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (c >= 'A' && c <= 'F') {
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - 'A' + 10;
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else {
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return NULL;
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        accum = (accum << 4) | value;
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (i & 1) {
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            *out++ = accum;
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            accum = 0;
101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return buffer;
105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
10785f12e9b9062402d6110df3f7099707912040edbAndreas Huberstatic sp<ABuffer> MakeAVCCodecSpecificData(
10885f12e9b9062402d6110df3f7099707912040edbAndreas Huber        const char *params, int32_t *width, int32_t *height) {
10985f12e9b9062402d6110df3f7099707912040edbAndreas Huber    *width = 0;
11085f12e9b9062402d6110df3f7099707912040edbAndreas Huber    *height = 0;
11185f12e9b9062402d6110df3f7099707912040edbAndreas Huber
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString val;
11333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    if (!GetAttribute(params, "profile-level-id", &val)) {
11433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        return NULL;
11533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    }
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> profileLevelID = decodeHex(val);
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(profileLevelID != NULL);
119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(profileLevelID->size(), 3u);
120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Vector<sp<ABuffer> > paramSets;
122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t numSeqParameterSets = 0;
124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalSeqParameterSetSize = 0;
125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t numPicParameterSets = 0;
126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalPicParameterSetSize = 0;
127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
12833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
12933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        return NULL;
13033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    }
13133a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber
132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t start = 0;
133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ssize_t commaPos = val.find(",", start);
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t end = (commaPos < 0) ? val.size() : commaPos;
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        AString nalString(val, start, end - start);
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = decodeBase64(nalString);
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK(nal != NULL);
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_GT(nal->size(), 0u);
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_LE(nal->size(), 65535u);
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint8_t nalType = nal->data()[0] & 0x1f;
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (numSeqParameterSets == 0) {
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 7u);
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (numPicParameterSets > 0) {
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 8u);
148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (nalType == 7) {
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++numSeqParameterSets;
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            totalSeqParameterSetSize += nal->size();
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else  {
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 8u);
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++numPicParameterSets;
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            totalPicParameterSetSize += nal->size();
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        paramSets.push(nal);
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (commaPos < 0) {
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        start = commaPos + 1;
165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LT(numSeqParameterSets, 32u);
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LE(numPicParameterSets, 255u);
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t csdSize =
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        1 + 3 + 1 + 1
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        + 2 * numSeqParameterSets + totalSeqParameterSetSize
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        + 1 + 2 * numPicParameterSets + totalPicParameterSetSize;
174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> csd = new ABuffer(csdSize);
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t *out = csd->data();
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = 0x01;  // configurationVersion
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    memcpy(out, profileLevelID->data(), 3);
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    out += 3;
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = 0xe0 | numSeqParameterSets;
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < numSeqParameterSets; ++i) {
185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = paramSets.editItemAt(i);
186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() >> 8;
188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() & 0xff;
189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(out, nal->data(), nal->size());
191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        out += nal->size();
19385f12e9b9062402d6110df3f7099707912040edbAndreas Huber
19485f12e9b9062402d6110df3f7099707912040edbAndreas Huber        if (i == 0) {
19585f12e9b9062402d6110df3f7099707912040edbAndreas Huber            FindAVCDimensions(nal, width, height);
1966e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber            LOGI("dimensions %dx%d", *width, *height);
19785f12e9b9062402d6110df3f7099707912040edbAndreas Huber        }
198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = numPicParameterSets;
201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < numPicParameterSets; ++i) {
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets);
204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() >> 8;
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() & 0xff;
207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(out, nal->data(), nal->size());
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        out += nal->size();
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
21385f12e9b9062402d6110df3f7099707912040edbAndreas Huber    // hexdump(csd->data(), csd->size());
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return csd;
216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<ABuffer> MakeAACCodecSpecificData(const char *params) {
219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString val;
220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(GetAttribute(params, "config", &val));
221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> config = decodeHex(val);
223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(config != NULL);
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(config->size(), 4u);
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = config->data();
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    x = (x >> 1) & 0xffff;
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    static const uint8_t kStaticESDS[] = {
231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x03, 22,
232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00,     // ES_ID
233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x04, 17,
236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x40,                       // Audio ISO/IEC 14496-3
237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x05, 2,
242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // AudioSpecificInfo follows
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    };
244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff;
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff;
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
25085f12e9b9062402d6110df3f7099707912040edbAndreas Huber    // hexdump(csd->data(), csd->size());
251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return csd;
253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
254cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2554dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber// From mpeg4-generic configuration data.
2564dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Hubersp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
2574dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    AString val;
2584dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    unsigned long objectType;
2594dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    if (GetAttribute(params, "objectType", &val)) {
2604dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        const char *s = val.c_str();
2614dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        char *end;
2624dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        objectType = strtoul(s, &end, 10);
2634dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        CHECK(end > s && *end == '\0');
2644dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    } else {
2654dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        objectType = 0x40;  // Audio ISO/IEC 14496-3
2664dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    }
2674dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2684dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    CHECK(GetAttribute(params, "config", &val));
2694dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2704dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    sp<ABuffer> config = decodeHex(val);
2714dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    CHECK(config != NULL);
2724dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2734dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    // Make sure size fits into a single byte and doesn't have to
2744dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    // be encoded.
2754dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    CHECK_LT(20 + config->size(), 128u);
2764dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2774dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    const uint8_t *data = config->data();
2784dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2794dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    static const uint8_t kStaticESDS[] = {
2804dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x03, 22,
2814dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00,     // ES_ID
2824dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
2834dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2844dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x04, 17,
2854dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x40,                       // Audio ISO/IEC 14496-3
2864dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00, 0x00, 0x00,
2874dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00, 0x00, 0x00,
2884dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x00, 0x00, 0x00, 0x00,
2894dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2904dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        0x05, 2,
2914dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        // AudioSpecificInfo follows
2924dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    };
2934dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
2944dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
2954dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    uint8_t *dst = csd->data();
2964dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x03;
2974dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 20 + config->size();
2984dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x00;  // ES_ID
2994dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x00;
3004dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
3014dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x04;
3024dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 15 + config->size();
3034dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = objectType;
3044dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
3054dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = 0x05;
3064dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    *dst++ = config->size();
3074dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    memcpy(dst, config->data(), config->size());
3084dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
3094dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    // hexdump(csd->data(), csd->size());
3104dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
3114dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    return csd;
3124dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber}
3134dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
31462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic size_t GetSizeWidth(size_t x) {
31562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t n = 1;
31662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    while (x > 127) {
31762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        ++n;
31862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        x >>= 7;
31962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
32062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    return n;
32162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
32262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
32362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) {
32462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    while (x > 127) {
32562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        *dst++ = (x & 0x7f) | 0x80;
32662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        x >>= 7;
32762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
32862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = x;
32962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    return dst;
33062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
33162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
332386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic bool ExtractDimensionsMPEG4Config(
33362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        const sp<ABuffer> &config, int32_t *width, int32_t *height) {
33462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *width = 0;
33562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *height = 0;
33662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
33762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    const uint8_t *ptr = config->data();
33862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t offset = 0;
33962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    bool foundVOL = false;
34062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    while (offset + 3 < config->size()) {
34162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        if (memcmp("\x00\x00\x01", &ptr[offset], 3)
34262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                || (ptr[offset + 3] & 0xf0) != 0x20) {
34362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            ++offset;
34462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            continue;
34562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
34662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
34762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        foundVOL = true;
34862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        break;
34962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
35062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
35162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    if (!foundVOL) {
35262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        return false;
35362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
35462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
355386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return ExtractDimensionsFromVOLHeader(
356386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            &ptr[offset], config->size() - offset, width, height);
35762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
35862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
359386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic sp<ABuffer> MakeMPEG4VideoCodecSpecificData(
36062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        const char *params, int32_t *width, int32_t *height) {
36162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *width = 0;
36262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *height = 0;
36362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
36462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    AString val;
36562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(GetAttribute(params, "config", &val));
36662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
36762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    sp<ABuffer> config = decodeHex(val);
36862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    CHECK(config != NULL);
36962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
370386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (!ExtractDimensionsMPEG4Config(config, width, height)) {
37162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        return NULL;
37262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
37362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
374386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    LOGI("VOL dimensions = %dx%d", *width, *height);
375386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
37662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
37762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
37862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
37962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
38062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    sp<ABuffer> csd = new ABuffer(len3);
38162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    uint8_t *dst = csd->data();
38262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x03;
38362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst = EncodeSize(dst, len2 + 3);
38462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x00;  // ES_ID
38562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x00;
38662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
38762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
38862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x04;
38962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst = EncodeSize(dst, len1 + 13);
39062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x01;  // Video ISO/IEC 14496-2 Simple Profile
39162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    for (size_t i = 0; i < 12; ++i) {
39262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        *dst++ = 0x00;
39362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    }
39462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
39562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    *dst++ = 0x05;
39662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst = EncodeSize(dst, config->size());
39762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    memcpy(dst, config->data(), config->size());
39862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    dst += config->size();
39962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
40062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    // hexdump(csd->data(), csd->size());
40162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
40262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    return csd;
40362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber}
40462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
4058d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic bool GetClockRate(const AString &desc, uint32_t *clockRate) {
4068d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    ssize_t slashPos = desc.find("/");
4078d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    if (slashPos < 0) {
4088d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        return false;
4098d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    }
4108d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4118d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    const char *s = desc.c_str() + slashPos + 1;
4128d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4138d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    char *end;
4148d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    unsigned long x = strtoul(s, &end, 10);
4158d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4168d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    if (end == s || (*end != '\0' && *end != '/')) {
4178d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        return false;
4188d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    }
4198d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4208d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    *clockRate = x;
4218d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
4228d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    return true;
4238d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
4248d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
425cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::APacketSource(
426cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ASessionDescription> &sessionDesc, size_t index)
42739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    : mInitCheck(NO_INIT),
42839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mFormat(new MetaData),
4298d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mEOSResult(OK),
430c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber      mIsAVC(false),
431c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber      mScanForIDR(true),
4328d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mRTPTimeBase(0),
4338d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mNormalPlayTimeBaseUs(0),
4348d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber      mLastNormalPlayTimeUs(0) {
435cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long PT;
436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString desc;
437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString params;
438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sessionDesc->getFormatType(index, &PT, &desc, &params);
439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
4408d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CHECK(GetClockRate(desc, &mClockRate));
4418d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int64_t durationUs;
443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (sessionDesc->getDurationUs(&durationUs)) {
444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt64(kKeyDuration, durationUs);
445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
446cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll);
447cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
448cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
44939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mInitCheck = OK;
450cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!strncmp(desc.c_str(), "H264/", 5)) {
451c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        mIsAVC = true;
452c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber
453cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
454cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
455cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t width, height;
456ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
45785f12e9b9062402d6110df3f7099707912040edbAndreas Huber            width = -1;
45885f12e9b9062402d6110df3f7099707912040edbAndreas Huber            height = -1;
459ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
460cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
46185f12e9b9062402d6110df3f7099707912040edbAndreas Huber        int32_t encWidth, encHeight;
462cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> codecSpecificData =
46385f12e9b9062402d6110df3f7099707912040edbAndreas Huber            MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight);
464cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
46533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        if (codecSpecificData != NULL) {
46685f12e9b9062402d6110df3f7099707912040edbAndreas Huber            if (width < 0) {
46785f12e9b9062402d6110df3f7099707912040edbAndreas Huber                // If no explicit width/height given in the sdp, use the dimensions
46885f12e9b9062402d6110df3f7099707912040edbAndreas Huber                // extracted from the first sequence parameter set.
46985f12e9b9062402d6110df3f7099707912040edbAndreas Huber                width = encWidth;
47085f12e9b9062402d6110df3f7099707912040edbAndreas Huber                height = encHeight;
47185f12e9b9062402d6110df3f7099707912040edbAndreas Huber            }
47285f12e9b9062402d6110df3f7099707912040edbAndreas Huber
47333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber            mFormat->setData(
47433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber                    kKeyAVCC, 0,
47533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber                    codecSpecificData->data(), codecSpecificData->size());
47685f12e9b9062402d6110df3f7099707912040edbAndreas Huber        } else if (width < 0) {
47785f12e9b9062402d6110df3f7099707912040edbAndreas Huber            mInitCheck = ERROR_UNSUPPORTED;
47885f12e9b9062402d6110df3f7099707912040edbAndreas Huber            return;
47933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        }
48085f12e9b9062402d6110df3f7099707912040edbAndreas Huber
48185f12e9b9062402d6110df3f7099707912040edbAndreas Huber        mFormat->setInt32(kKeyWidth, width);
48285f12e9b9062402d6110df3f7099707912040edbAndreas Huber        mFormat->setInt32(kKeyHeight, height);
48339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "H263-2000/", 10)
48439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            || !strncmp(desc.c_str(), "H263-1998/", 10)) {
48539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
486cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
48739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t width, height;
488ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
489ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
490ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            return;
491ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
49239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
49339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyWidth, width);
49439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyHeight, height);
49539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
496cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
497cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
498cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t sampleRate, numChannels;
499cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ASessionDescription::ParseFormatDesc(
500cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
501cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
502cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
503cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
504cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
505cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> codecSpecificData =
506cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            MakeAACCodecSpecificData(params.c_str());
507cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
508cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setData(
509cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                kKeyESDS, 0,
510cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                codecSpecificData->data(), codecSpecificData->size());
51139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
51239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
51339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
51439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t sampleRate, numChannels;
51539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ASessionDescription::ParseFormatDesc(
51639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
51739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
51839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
51939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
52039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
52139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (sampleRate != 8000 || numChannels != 1) {
52239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
52339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
52439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
52539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
52639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
52739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t sampleRate, numChannels;
52839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ASessionDescription::ParseFormatDesc(
52939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
53039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
53139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
53239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
53339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
53439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (sampleRate != 16000 || numChannels != 1) {
53539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
53639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
53762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
53862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
53962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
54062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        int32_t width, height;
54162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
54262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            width = -1;
54362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            height = -1;
54462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
54562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
54662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        int32_t encWidth, encHeight;
54762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        sp<ABuffer> codecSpecificData =
54862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            MakeMPEG4VideoCodecSpecificData(
54962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                    params.c_str(), &encWidth, &encHeight);
55062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
55162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        if (codecSpecificData != NULL) {
55262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            mFormat->setData(
55362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                    kKeyESDS, 0,
55462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                    codecSpecificData->data(), codecSpecificData->size());
55562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
55662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            if (width < 0) {
55762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                width = encWidth;
55862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber                height = encHeight;
55962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            }
56062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        } else if (width < 0) {
56162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
56262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber            return;
56362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        }
56462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
56562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        mFormat->setInt32(kKeyWidth, width);
56662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        mFormat->setInt32(kKeyHeight, height);
567dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber    } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
5684dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        AString val;
5694dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        if (!GetAttribute(params.c_str(), "mode", &val)
5704dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                || (strcasecmp(val.c_str(), "AAC-lbr")
5714dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                    && strcasecmp(val.c_str(), "AAC-hbr"))) {
5724dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
5734dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber            return;
5744dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        }
5754dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
5764dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
5774dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
5784dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        int32_t sampleRate, numChannels;
5794dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        ASessionDescription::ParseFormatDesc(
5804dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
5814dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
5824dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
5834dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
5844dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
5854dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        sp<ABuffer> codecSpecificData =
5864dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber            MakeAACCodecSpecificData2(params.c_str());
5874dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber
5884dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mFormat->setData(
5894dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                kKeyESDS, 0,
5904dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber                codecSpecificData->data(), codecSpecificData->size());
591fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber    } else if (ARawAudioAssembler::Supports(desc.c_str())) {
592fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber        ARawAudioAssembler::MakeFormat(desc.c_str(), mFormat);
593cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
59439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mInitCheck = ERROR_UNSUPPORTED;
595cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
596cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
597cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
598cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::~APacketSource() {
599cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
600cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
60139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t APacketSource::initCheck() const {
60239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return mInitCheck;
60339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
60439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
605cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::start(MetaData *params) {
606cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
607cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
608cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
609cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::stop() {
610cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
611cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
612cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
613cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<MetaData> APacketSource::getFormat() {
614cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mFormat;
615cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
616cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
617cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::read(
618cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        MediaBuffer **out, const ReadOptions *) {
619cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out = NULL;
620cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
621cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
622cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (mEOSResult == OK && mBuffers.empty()) {
623cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mCondition.wait(mLock);
624cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
625cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
626cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!mBuffers.empty()) {
627cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ABuffer> buffer = *mBuffers.begin();
628cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
6298d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        updateNormalPlayTime_l(buffer);
6308d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
63139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
63239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
633f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        int64_t timeUs;
634f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
635cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
636cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
63739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
638cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
639cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out = mediaBuffer;
640cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
641cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mBuffers.erase(mBuffers.begin());
642cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return OK;
643cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
644cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
645cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mEOSResult;
646cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
647cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
6488d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::updateNormalPlayTime_l(const sp<ABuffer> &buffer) {
6498d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    uint32_t rtpTime;
6508d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
6518d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
6528d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    mLastNormalPlayTimeUs =
6538d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        (((double)rtpTime - (double)mRTPTimeBase) / mClockRate)
6548d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber            * 1000000ll
6558d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber            + mNormalPlayTimeBaseUs;
6568d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
6578d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
658cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
659cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int32_t damaged;
660cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
6616e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        LOGV("discarding damaged AU");
662cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return;
663cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
664cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
665c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber    if (mScanForIDR && mIsAVC) {
666c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        // This pretty piece of code ensures that the first access unit
667c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        // fed to the decoder after stream-start or seek is guaranteed to
668c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        // be an IDR frame. This is to workaround limitations of a certain
669c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        // hardware h.264 decoder that requires this to be the case.
670c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber
671c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        if (!IsIDR(buffer)) {
672c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber            LOGV("skipping AU while scanning for next IDR frame.");
673c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber            return;
674c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        }
675c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber
676c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber        mScanForIDR = false;
677c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber    }
678c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber
679cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
680cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mBuffers.push_back(buffer);
681cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mCondition.signal();
682cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
683cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
684cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::signalEOS(status_t result) {
685cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(result != OK);
686cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
687cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
688cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mEOSResult = result;
689cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mCondition.signal();
690cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
691cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
692cce326fe43411855aca2f719e505b051bc4b61b3Andreas Hubervoid APacketSource::flushQueue() {
69339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    Mutex::Autolock autoLock(mLock);
694cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber    mBuffers.clear();
695c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber
696c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber    mScanForIDR = true;
69739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
69839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
6998d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberint64_t APacketSource::getNormalPlayTimeUs() {
7008d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    Mutex::Autolock autoLock(mLock);
7018d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    return mLastNormalPlayTimeUs;
7028d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
7038d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
7048d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::setNormalPlayTimeMapping(
7058d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        uint32_t rtpTime, int64_t normalPlayTimeUs) {
7068d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    Mutex::Autolock autoLock(mLock);
7078d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
7088d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    mRTPTimeBase = rtpTime;
7098d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    mNormalPlayTimeBaseUs = normalPlayTimeUs;
7108d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
7118d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
712c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huberint64_t APacketSource::getQueueDurationUs(bool *eos) {
713c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    Mutex::Autolock autoLock(mLock);
714c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
715c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    *eos = (mEOSResult != OK);
716c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
717c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    if (mBuffers.size() < 2) {
718c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber        return 0;
719c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    }
720c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
721c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    const sp<ABuffer> first = *mBuffers.begin();
722c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    const sp<ABuffer> last = *--mBuffers.end();
723c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
724c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    int64_t firstTimeUs;
725c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    CHECK(first->meta()->findInt64("timeUs", &firstTimeUs));
726c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
727c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    int64_t lastTimeUs;
728c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    CHECK(last->meta()->findInt64("timeUs", &lastTimeUs));
729c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
7306f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber    if (lastTimeUs < firstTimeUs) {
7316e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        LOGE("Huh? Time moving backwards? %lld > %lld",
7326e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber             firstTimeUs, lastTimeUs);
7336e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
7346f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber        return 0;
7356f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber    }
736c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
737c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber    return lastTimeUs - firstTimeUs;
738c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber}
739c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
740cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
741