APacketSource.cpp revision 85f12e9b9062402d6110df3f7099707912040edb
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
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h>
29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/base64.h>
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/hexdump.h>
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaBuffer.h>
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaDefs.h>
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MetaData.h>
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <utils/Vector.h>
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool GetAttribute(const char *s, const char *key, AString *value) {
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    value->clear();
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t keyLen = strlen(key);
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
44ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        while (isspace(*s)) {
45ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            ++s;
46ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
47ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const char *colonPos = strchr(s, ';');
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t len =
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            (colonPos == NULL) ? strlen(s) : colonPos - s;
52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value->setTo(&s[keyLen + 1], len - keyLen - 1);
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return true;
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (colonPos == NULL) {
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return false;
60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        s = colonPos + 1;
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic sp<ABuffer> decodeHex(const AString &s) {
67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if ((s.size() % 2) != 0) {
68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return NULL;
69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t outLen = s.size() / 2;
72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> buffer = new ABuffer(outLen);
73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t *out = buffer->data();
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t accum = 0;
76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < s.size(); ++i) {
77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        char c = s.c_str()[i];
78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        unsigned value;
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (c >= '0' && c <= '9') {
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - '0';
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (c >= 'a' && c <= 'f') {
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - 'a' + 10;
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (c >= 'A' && c <= 'F') {
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            value = c - 'A' + 10;
85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else {
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return NULL;
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        accum = (accum << 4) | value;
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (i & 1) {
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            *out++ = accum;
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            accum = 0;
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return buffer;
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
10185f12e9b9062402d6110df3f7099707912040edbAndreas Huberstatic sp<ABuffer> MakeAVCCodecSpecificData(
10285f12e9b9062402d6110df3f7099707912040edbAndreas Huber        const char *params, int32_t *width, int32_t *height) {
10385f12e9b9062402d6110df3f7099707912040edbAndreas Huber    *width = 0;
10485f12e9b9062402d6110df3f7099707912040edbAndreas Huber    *height = 0;
10585f12e9b9062402d6110df3f7099707912040edbAndreas Huber
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString val;
10733a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    if (!GetAttribute(params, "profile-level-id", &val)) {
10833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        return NULL;
10933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    }
110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> profileLevelID = decodeHex(val);
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(profileLevelID != NULL);
113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(profileLevelID->size(), 3u);
114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Vector<sp<ABuffer> > paramSets;
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t numSeqParameterSets = 0;
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalSeqParameterSetSize = 0;
119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t numPicParameterSets = 0;
120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalPicParameterSetSize = 0;
121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
12233a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
12333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        return NULL;
12433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber    }
12533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber
126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t start = 0;
127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ssize_t commaPos = val.find(",", start);
129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t end = (commaPos < 0) ? val.size() : commaPos;
130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        AString nalString(val, start, end - start);
132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = decodeBase64(nalString);
133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK(nal != NULL);
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_GT(nal->size(), 0u);
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_LE(nal->size(), 65535u);
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint8_t nalType = nal->data()[0] & 0x1f;
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (numSeqParameterSets == 0) {
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 7u);
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else if (numPicParameterSets > 0) {
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 8u);
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (nalType == 7) {
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++numSeqParameterSets;
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            totalSeqParameterSetSize += nal->size();
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else  {
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK_EQ((unsigned)nalType, 8u);
148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++numPicParameterSets;
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            totalPicParameterSetSize += nal->size();
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        paramSets.push(nal);
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (commaPos < 0) {
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        start = commaPos + 1;
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LT(numSeqParameterSets, 32u);
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LE(numPicParameterSets, 255u);
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t csdSize =
165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        1 + 3 + 1 + 1
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        + 2 * numSeqParameterSets + totalSeqParameterSetSize
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        + 1 + 2 * numPicParameterSets + totalPicParameterSetSize;
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> csd = new ABuffer(csdSize);
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint8_t *out = csd->data();
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = 0x01;  // configurationVersion
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    memcpy(out, profileLevelID->data(), 3);
174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    out += 3;
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = 0xe0 | numSeqParameterSets;
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < numSeqParameterSets; ++i) {
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = paramSets.editItemAt(i);
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() >> 8;
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() & 0xff;
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(out, nal->data(), nal->size());
185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        out += nal->size();
18785f12e9b9062402d6110df3f7099707912040edbAndreas Huber
18885f12e9b9062402d6110df3f7099707912040edbAndreas Huber        if (i == 0) {
18985f12e9b9062402d6110df3f7099707912040edbAndreas Huber            FindAVCDimensions(nal, width, height);
19085f12e9b9062402d6110df3f7099707912040edbAndreas Huber            LOG(INFO) << "dimensions " << *width << "x" << *height;
19185f12e9b9062402d6110df3f7099707912040edbAndreas Huber        }
192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out++ = numPicParameterSets;
195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < numPicParameterSets; ++i) {
197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets);
198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() >> 8;
200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out++ = nal->size() & 0xff;
201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(out, nal->data(), nal->size());
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        out += nal->size();
205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
20785f12e9b9062402d6110df3f7099707912040edbAndreas Huber    // hexdump(csd->data(), csd->size());
208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return csd;
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<ABuffer> MakeAACCodecSpecificData(const char *params) {
213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString val;
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(GetAttribute(params, "config", &val));
215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> config = decodeHex(val);
217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(config != NULL);
218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(config->size(), 4u);
219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = config->data();
221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    x = (x >> 1) & 0xffff;
223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    static const uint8_t kStaticESDS[] = {
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x03, 22,
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00,     // ES_ID
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x04, 17,
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x40,                       // Audio ISO/IEC 14496-3
231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x00, 0x00, 0x00, 0x00,
234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        0x05, 2,
236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // AudioSpecificInfo follows
237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    };
238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff;
242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff;
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
24485f12e9b9062402d6110df3f7099707912040edbAndreas Huber    // hexdump(csd->data(), csd->size());
245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return csd;
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::APacketSource(
250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ASessionDescription> &sessionDesc, size_t index)
25139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    : mInitCheck(NO_INIT),
25239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mFormat(new MetaData),
25339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mEOSResult(OK),
25439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mFirstAccessUnit(true),
25539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mFirstAccessUnitNTP(0) {
256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long PT;
257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString desc;
258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString params;
259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sessionDesc->getFormatType(index, &PT, &desc, &params);
260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int64_t durationUs;
262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (sessionDesc->getDurationUs(&durationUs)) {
263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt64(kKeyDuration, durationUs);
264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll);
266cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
267cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
26839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mInitCheck = OK;
269cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!strncmp(desc.c_str(), "H264/", 5)) {
270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
272cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t width, height;
273ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
27485f12e9b9062402d6110df3f7099707912040edbAndreas Huber            width = -1;
27585f12e9b9062402d6110df3f7099707912040edbAndreas Huber            height = -1;
276ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
277cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
27885f12e9b9062402d6110df3f7099707912040edbAndreas Huber        int32_t encWidth, encHeight;
279cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> codecSpecificData =
28085f12e9b9062402d6110df3f7099707912040edbAndreas Huber            MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight);
281cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
28233a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        if (codecSpecificData != NULL) {
28385f12e9b9062402d6110df3f7099707912040edbAndreas Huber            if (width < 0) {
28485f12e9b9062402d6110df3f7099707912040edbAndreas Huber                // If no explicit width/height given in the sdp, use the dimensions
28585f12e9b9062402d6110df3f7099707912040edbAndreas Huber                // extracted from the first sequence parameter set.
28685f12e9b9062402d6110df3f7099707912040edbAndreas Huber                width = encWidth;
28785f12e9b9062402d6110df3f7099707912040edbAndreas Huber                height = encHeight;
28885f12e9b9062402d6110df3f7099707912040edbAndreas Huber            }
28985f12e9b9062402d6110df3f7099707912040edbAndreas Huber
29033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber            mFormat->setData(
29133a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber                    kKeyAVCC, 0,
29233a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber                    codecSpecificData->data(), codecSpecificData->size());
29385f12e9b9062402d6110df3f7099707912040edbAndreas Huber        } else if (width < 0) {
29485f12e9b9062402d6110df3f7099707912040edbAndreas Huber            mInitCheck = ERROR_UNSUPPORTED;
29585f12e9b9062402d6110df3f7099707912040edbAndreas Huber            return;
29633a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber        }
29785f12e9b9062402d6110df3f7099707912040edbAndreas Huber
29885f12e9b9062402d6110df3f7099707912040edbAndreas Huber        mFormat->setInt32(kKeyWidth, width);
29985f12e9b9062402d6110df3f7099707912040edbAndreas Huber        mFormat->setInt32(kKeyHeight, height);
30039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "H263-2000/", 10)
30139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            || !strncmp(desc.c_str(), "H263-1998/", 10)) {
30239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
30439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t width, height;
305ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
306ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
307ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber            return;
308ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        }
30939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
31039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyWidth, width);
31139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyHeight, height);
31239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
313cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
314cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
315cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t sampleRate, numChannels;
316cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ASessionDescription::ParseFormatDesc(
317cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
318cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
319cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
320cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
321cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
322cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> codecSpecificData =
323cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            MakeAACCodecSpecificData(params.c_str());
324cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
325cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormat->setData(
326cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                kKeyESDS, 0,
327cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                codecSpecificData->data(), codecSpecificData->size());
32839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
32939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
33039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
33139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t sampleRate, numChannels;
33239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ASessionDescription::ParseFormatDesc(
33339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
33439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
33539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
33639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
33739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
33839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (sampleRate != 8000 || numChannels != 1) {
33939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
34039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
34139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
34239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
34339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
34439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        int32_t sampleRate, numChannels;
34539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ASessionDescription::ParseFormatDesc(
34639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                desc.c_str(), &sampleRate, &numChannels);
34739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
34839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeySampleRate, sampleRate);
34939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
35039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
35139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (sampleRate != 16000 || numChannels != 1) {
35239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mInitCheck = ERROR_UNSUPPORTED;
35339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
354cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
35539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mInitCheck = ERROR_UNSUPPORTED;
356cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
357cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
358cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
359cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::~APacketSource() {
360cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
361cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
36239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t APacketSource::initCheck() const {
36339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return mInitCheck;
36439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
36539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
366cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::start(MetaData *params) {
36739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mFirstAccessUnit = true;
36839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mFirstAccessUnitNTP = 0;
36939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
370cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
371cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
372cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
373cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::stop() {
374cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
375cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
376cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
377cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<MetaData> APacketSource::getFormat() {
378cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mFormat;
379cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
380cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
381cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::read(
382cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        MediaBuffer **out, const ReadOptions *) {
383cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *out = NULL;
384cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
385cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
386cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (mEOSResult == OK && mBuffers.empty()) {
387cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mCondition.wait(mLock);
388cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
389cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
390cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!mBuffers.empty()) {
391cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ABuffer> buffer = *mBuffers.begin();
392cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
39339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
39439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
395f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        int64_t timeUs;
396f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
397cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
398cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
39939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
400cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
401cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *out = mediaBuffer;
402cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
403cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mBuffers.erase(mBuffers.begin());
404cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return OK;
405cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
406cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
407cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mEOSResult;
408cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
409cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
410cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
411cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int32_t damaged;
412cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
4136dc387a8c3f031f9f17d1138295368946563f7a5Andreas Huber        LOG(VERBOSE) << "discarding damaged AU";
414cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return;
415cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
416cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
417f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    uint64_t ntpTime;
418f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    CHECK(buffer->meta()->findInt64(
419f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber                "ntp-time", (int64_t *)&ntpTime));
420f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
421f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    if (mFirstAccessUnit) {
422f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        mFirstAccessUnit = false;
423f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        mFirstAccessUnitNTP = ntpTime;
424f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    }
425f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
426f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    if (ntpTime > mFirstAccessUnitNTP) {
427f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        ntpTime -= mFirstAccessUnitNTP;
428f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    } else {
429f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        ntpTime = 0;
430f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    }
431f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
432f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    int64_t timeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32));
433f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
434f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    buffer->meta()->setInt64("timeUs", timeUs);
435f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mBuffers.push_back(buffer);
438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mCondition.signal();
439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
440cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
441cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::signalEOS(status_t result) {
442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(result != OK);
443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    Mutex::Autolock autoLock(mLock);
445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mEOSResult = result;
446cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mCondition.signal();
447cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
448cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
44939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberint64_t APacketSource::getQueuedDuration(bool *eos) {
45039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    Mutex::Autolock autoLock(mLock);
45139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
45239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    *eos = (mEOSResult != OK);
45339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
45439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mBuffers.empty()) {
45539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return 0;
45639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
45739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
45839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ABuffer> buffer = *mBuffers.begin();
45939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
46039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    uint64_t ntpTime;
46139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(buffer->meta()->findInt64(
46239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                "ntp-time", (int64_t *)&ntpTime));
46339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
46439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    int64_t firstTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32));
46539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
46639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    buffer = *--mBuffers.end();
46739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
46839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(buffer->meta()->findInt64(
46939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                "ntp-time", (int64_t *)&ntpTime));
47039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
47139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    int64_t lastTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32));
47239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
47339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return lastTimeUs - firstTimeUs;
47439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
47539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
476cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
477