ARTPSource.cpp revision cf7b9c7aae758ac0b99833915053c63c2ac46e09
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "ARTPSource.h"
18
19#include "AAVCAssembler.h"
20#include "AMPEG4AudioAssembler.h"
21#include "ASessionDescription.h"
22
23#include <media/stagefright/foundation/ABuffer.h>
24#include <media/stagefright/foundation/ADebug.h>
25#include <media/stagefright/foundation/AMessage.h>
26
27#define VERBOSE         0
28
29namespace android {
30
31ARTPSource::ARTPSource(
32        uint32_t id,
33        const sp<ASessionDescription> &sessionDesc, size_t index,
34        const sp<AMessage> &notify)
35    : mID(id),
36      mHighestSeqNumber(0),
37      mNumBuffersReceived(0),
38      mNumTimes(0) {
39    unsigned long PT;
40    AString desc;
41    AString params;
42    sessionDesc->getFormatType(index, &PT, &desc, &params);
43
44    if (!strncmp(desc.c_str(), "H264/", 5)) {
45        mAssembler = new AAVCAssembler(notify);
46    } else if (!strncmp(desc.c_str(), "MP4A-LATM", 9)) {
47        mAssembler = new AMPEG4AudioAssembler(notify);
48    } else {
49        TRESPASS();
50    }
51}
52
53static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
54    return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
55}
56
57void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
58    if (queuePacket(buffer) && mNumTimes == 2 && mAssembler != NULL) {
59        mAssembler->onPacketReceived(this);
60    }
61
62    dump();
63}
64
65void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
66#if VERBOSE
67    LOG(VERBOSE) << "timeUpdate";
68#endif
69
70    if (mNumTimes == 2) {
71        mNTPTime[0] = mNTPTime[1];
72        mRTPTime[0] = mRTPTime[1];
73        mNumTimes = 1;
74    }
75    mNTPTime[mNumTimes] = ntpTime;
76    mRTPTime[mNumTimes++] = rtpTime;
77
78    if (mNumTimes == 2) {
79        for (List<sp<ABuffer> >::iterator it = mQueue.begin();
80             it != mQueue.end(); ++it) {
81            sp<AMessage> meta = (*it)->meta();
82
83            uint32_t rtpTime;
84            CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
85
86            meta->setInt64("ntp-time", RTP2NTP(rtpTime));
87        }
88    }
89}
90
91bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
92    uint32_t seqNum = (uint32_t)buffer->int32Data();
93
94    if (mNumTimes == 2) {
95        sp<AMessage> meta = buffer->meta();
96
97        uint32_t rtpTime;
98        CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
99
100        meta->setInt64("ntp-time", RTP2NTP(rtpTime));
101    }
102
103    if (mNumBuffersReceived++ == 0) {
104        mHighestSeqNumber = seqNum;
105        mQueue.push_back(buffer);
106        return true;
107    }
108
109    // Only the lower 16-bit of the sequence numbers are transmitted,
110    // derive the high-order bits by choosing the candidate closest
111    // to the highest sequence number (extended to 32 bits) received so far.
112
113    uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
114    uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
115    uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
116    uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
117    uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
118    uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
119
120    if (diff1 < diff2) {
121        if (diff1 < diff3) {
122            // diff1 < diff2 ^ diff1 < diff3
123            seqNum = seq1;
124        } else {
125            // diff3 <= diff1 < diff2
126            seqNum = seq3;
127        }
128    } else if (diff2 < diff3) {
129        // diff2 <= diff1 ^ diff2 < diff3
130        seqNum = seq2;
131    } else {
132        // diff3 <= diff2 <= diff1
133        seqNum = seq3;
134    }
135
136    if (seqNum > mHighestSeqNumber) {
137        mHighestSeqNumber = seqNum;
138    }
139
140    buffer->setInt32Data(seqNum);
141
142    List<sp<ABuffer> >::iterator it = mQueue.begin();
143    while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
144        ++it;
145    }
146
147    if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
148        LOG(WARNING) << "Discarding duplicate buffer";
149        return false;
150    }
151
152    mQueue.insert(it, buffer);
153
154    return true;
155}
156
157void ARTPSource::dump() const {
158    if ((mNumBuffersReceived % 128) != 0) {
159        return;
160    }
161
162#if 0
163    if (mAssembler == NULL) {
164        char tmp[20];
165        sprintf(tmp, "0x%08x", mID);
166
167        int32_t numMissing = 0;
168
169        if (!mQueue.empty()) {
170            List<sp<ABuffer> >::const_iterator it = mQueue.begin();
171            uint32_t expectedSeqNum = (uint32_t)(*it)->int32Data();
172            ++expectedSeqNum;
173            ++it;
174
175            for (; it != mQueue.end(); ++it) {
176                uint32_t seqNum = (uint32_t)(*it)->int32Data();
177                CHECK_GE(seqNum, expectedSeqNum);
178
179                if (seqNum != expectedSeqNum) {
180                    numMissing += seqNum - expectedSeqNum;
181                    expectedSeqNum = seqNum;
182                }
183
184                ++expectedSeqNum;
185            }
186        }
187
188        LOG(VERBOSE) << "[" << tmp << "] Missing " << numMissing
189             << " / " << (mNumBuffersReceived + numMissing) << " packets. ("
190             << (100.0 * numMissing / (mNumBuffersReceived + numMissing))
191             << " %%)";
192    }
193#endif
194
195#if 0
196    AString out;
197
198    out.append(tmp);
199    out.append(" [");
200
201    List<sp<ABuffer> >::const_iterator it = mQueue.begin();
202    while (it != mQueue.end()) {
203        uint32_t start = (uint32_t)(*it)->int32Data();
204
205        out.append(start);
206
207        ++it;
208        uint32_t expected = start + 1;
209
210        while (it != mQueue.end()) {
211            uint32_t seqNum = (uint32_t)(*it)->int32Data();
212
213            if (seqNum != expected) {
214                if (expected > start + 1) {
215                    out.append("-");
216                    out.append(expected - 1);
217                }
218                out.append(", ");
219                break;
220            }
221
222            ++it;
223            ++expected;
224        }
225
226        if (it == mQueue.end()) {
227            if (expected > start + 1) {
228                out.append("-");
229                out.append(expected - 1);
230            }
231        }
232    }
233
234    out.append("]");
235
236    LOG(VERBOSE) << out;
237#endif
238}
239
240uint64_t ARTPSource::RTP2NTP(uint32_t rtpTime) const {
241    CHECK_EQ(mNumTimes, 2u);
242
243    return mNTPTime[0] + (double)(mNTPTime[1] - mNTPTime[0])
244            * ((double)rtpTime - (double)mRTPTime[0])
245            / (double)(mRTPTime[1] - mRTPTime[0]);
246}
247
248}  // namespace android
249
250
251