ARTPSource.cpp revision 4dba3e90f211eb5f5af19b10c5d3fc8c967b0086
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 "AAMRAssembler.h"
20#include "AAVCAssembler.h"
21#include "AH263Assembler.h"
22#include "AMPEG4AudioAssembler.h"
23#include "AMPEG4ElementaryAssembler.h"
24#include "ASessionDescription.h"
25
26#include <media/stagefright/foundation/ABuffer.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
29
30#define BE_VERBOSE      0
31
32namespace android {
33
34static const uint32_t kSourceID = 0xdeadbeef;
35
36ARTPSource::ARTPSource(
37        uint32_t id,
38        const sp<ASessionDescription> &sessionDesc, size_t index,
39        const sp<AMessage> &notify)
40    : mID(id),
41      mHighestSeqNumber(0),
42      mNumBuffersReceived(0),
43      mNumTimes(0),
44      mLastNTPTime(0),
45      mLastNTPTimeUpdateUs(0),
46      mIssueFIRRequests(false),
47      mLastFIRRequestUs(-1),
48      mNextFIRSeqNo((rand() * 256.0) / RAND_MAX) {
49    unsigned long PT;
50    AString desc;
51    AString params;
52    sessionDesc->getFormatType(index, &PT, &desc, &params);
53
54    if (!strncmp(desc.c_str(), "H264/", 5)) {
55        mAssembler = new AAVCAssembler(notify);
56        mIssueFIRRequests = true;
57    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
58        mAssembler = new AMPEG4AudioAssembler(notify);
59    } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
60            || !strncmp(desc.c_str(), "H263-2000/", 10)) {
61        mAssembler = new AH263Assembler(notify);
62        mIssueFIRRequests = true;
63    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
64        mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
65    } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
66        mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
67    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
68            || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
69        mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
70        mIssueFIRRequests = true;
71    } else {
72        TRESPASS();
73    }
74}
75
76static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
77    return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
78}
79
80void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
81    if (queuePacket(buffer)
82            && mNumTimes == 2
83            && mAssembler != NULL) {
84        mAssembler->onPacketReceived(this);
85    }
86
87    dump();
88}
89
90void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
91#if BE_VERBOSE
92    LOG(VERBOSE) << "timeUpdate";
93#endif
94
95    mLastNTPTime = ntpTime;
96    mLastNTPTimeUpdateUs = ALooper::GetNowUs();
97
98    if (mNumTimes == 2) {
99        mNTPTime[0] = mNTPTime[1];
100        mRTPTime[0] = mRTPTime[1];
101        mNumTimes = 1;
102    }
103    mNTPTime[mNumTimes] = ntpTime;
104    mRTPTime[mNumTimes++] = rtpTime;
105
106    if (timeEstablished()) {
107        for (List<sp<ABuffer> >::iterator it = mQueue.begin();
108             it != mQueue.end(); ++it) {
109            sp<AMessage> meta = (*it)->meta();
110
111            uint32_t rtpTime;
112            CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
113
114            meta->setInt64("ntp-time", RTP2NTP(rtpTime));
115        }
116    }
117}
118
119bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
120    uint32_t seqNum = (uint32_t)buffer->int32Data();
121
122    if (mNumTimes == 2) {
123        sp<AMessage> meta = buffer->meta();
124
125        uint32_t rtpTime;
126        CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
127
128        meta->setInt64("ntp-time", RTP2NTP(rtpTime));
129    }
130
131    if (mNumBuffersReceived++ == 0) {
132        mHighestSeqNumber = seqNum;
133        mQueue.push_back(buffer);
134        return true;
135    }
136
137    // Only the lower 16-bit of the sequence numbers are transmitted,
138    // derive the high-order bits by choosing the candidate closest
139    // to the highest sequence number (extended to 32 bits) received so far.
140
141    uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
142    uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
143    uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
144    uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
145    uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
146    uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
147
148    if (diff1 < diff2) {
149        if (diff1 < diff3) {
150            // diff1 < diff2 ^ diff1 < diff3
151            seqNum = seq1;
152        } else {
153            // diff3 <= diff1 < diff2
154            seqNum = seq3;
155        }
156    } else if (diff2 < diff3) {
157        // diff2 <= diff1 ^ diff2 < diff3
158        seqNum = seq2;
159    } else {
160        // diff3 <= diff2 <= diff1
161        seqNum = seq3;
162    }
163
164    if (seqNum > mHighestSeqNumber) {
165        mHighestSeqNumber = seqNum;
166    }
167
168    buffer->setInt32Data(seqNum);
169
170    List<sp<ABuffer> >::iterator it = mQueue.begin();
171    while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
172        ++it;
173    }
174
175    if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
176        LOG(WARNING) << "Discarding duplicate buffer";
177        return false;
178    }
179
180    mQueue.insert(it, buffer);
181
182    return true;
183}
184
185void ARTPSource::dump() const {
186    if ((mNumBuffersReceived % 128) != 0) {
187        return;
188    }
189
190#if 0
191    if (mAssembler == NULL) {
192        char tmp[20];
193        sprintf(tmp, "0x%08x", mID);
194
195        int32_t numMissing = 0;
196
197        if (!mQueue.empty()) {
198            List<sp<ABuffer> >::const_iterator it = mQueue.begin();
199            uint32_t expectedSeqNum = (uint32_t)(*it)->int32Data();
200            ++expectedSeqNum;
201            ++it;
202
203            for (; it != mQueue.end(); ++it) {
204                uint32_t seqNum = (uint32_t)(*it)->int32Data();
205                CHECK_GE(seqNum, expectedSeqNum);
206
207                if (seqNum != expectedSeqNum) {
208                    numMissing += seqNum - expectedSeqNum;
209                    expectedSeqNum = seqNum;
210                }
211
212                ++expectedSeqNum;
213            }
214        }
215
216        LOG(VERBOSE) << "[" << tmp << "] Missing " << numMissing
217             << " / " << (mNumBuffersReceived + numMissing) << " packets. ("
218             << (100.0 * numMissing / (mNumBuffersReceived + numMissing))
219             << " %%)";
220    }
221#endif
222
223#if 0
224    AString out;
225
226    out.append(tmp);
227    out.append(" [");
228
229    List<sp<ABuffer> >::const_iterator it = mQueue.begin();
230    while (it != mQueue.end()) {
231        uint32_t start = (uint32_t)(*it)->int32Data();
232
233        out.append(start);
234
235        ++it;
236        uint32_t expected = start + 1;
237
238        while (it != mQueue.end()) {
239            uint32_t seqNum = (uint32_t)(*it)->int32Data();
240
241            if (seqNum != expected) {
242                if (expected > start + 1) {
243                    out.append("-");
244                    out.append(expected - 1);
245                }
246                out.append(", ");
247                break;
248            }
249
250            ++it;
251            ++expected;
252        }
253
254        if (it == mQueue.end()) {
255            if (expected > start + 1) {
256                out.append("-");
257                out.append(expected - 1);
258            }
259        }
260    }
261
262    out.append("]");
263
264    LOG(VERBOSE) << out;
265#endif
266}
267
268uint64_t ARTPSource::RTP2NTP(uint32_t rtpTime) const {
269    CHECK_EQ(mNumTimes, 2u);
270
271    return mNTPTime[0] + (double)(mNTPTime[1] - mNTPTime[0])
272            * ((double)rtpTime - (double)mRTPTime[0])
273            / (double)(mRTPTime[1] - mRTPTime[0]);
274}
275
276void ARTPSource::byeReceived() {
277    mAssembler->onByeReceived();
278}
279
280void ARTPSource::addFIR(const sp<ABuffer> &buffer) {
281    if (!mIssueFIRRequests) {
282        return;
283    }
284
285    int64_t nowUs = ALooper::GetNowUs();
286    if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
287        // Send FIR requests at most every 5 secs.
288        return;
289    }
290
291    mLastFIRRequestUs = nowUs;
292
293    if (buffer->size() + 20 > buffer->capacity()) {
294        LOG(WARNING) << "RTCP buffer too small to accomodate FIR.";
295        return;
296    }
297
298    uint8_t *data = buffer->data() + buffer->size();
299
300    data[0] = 0x80 | 4;
301    data[1] = 206;  // PSFB
302    data[2] = 0;
303    data[3] = 4;
304    data[4] = kSourceID >> 24;
305    data[5] = (kSourceID >> 16) & 0xff;
306    data[6] = (kSourceID >> 8) & 0xff;
307    data[7] = kSourceID & 0xff;
308
309    data[8] = 0x00;  // SSRC of media source (unused)
310    data[9] = 0x00;
311    data[10] = 0x00;
312    data[11] = 0x00;
313
314    data[12] = mID >> 24;
315    data[13] = (mID >> 16) & 0xff;
316    data[14] = (mID >> 8) & 0xff;
317    data[15] = mID & 0xff;
318
319    data[16] = mNextFIRSeqNo++;  // Seq Nr.
320
321    data[17] = 0x00;  // Reserved
322    data[18] = 0x00;
323    data[19] = 0x00;
324
325    buffer->setRange(buffer->offset(), buffer->size() + 20);
326
327    LOG(VERBOSE) << "Added FIR request.";
328}
329
330void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
331    if (buffer->size() + 32 > buffer->capacity()) {
332        LOG(WARNING) << "RTCP buffer too small to accomodate RR.";
333        return;
334    }
335
336    uint8_t *data = buffer->data() + buffer->size();
337
338    data[0] = 0x80 | 1;
339    data[1] = 201;  // RR
340    data[2] = 0;
341    data[3] = 7;
342    data[4] = kSourceID >> 24;
343    data[5] = (kSourceID >> 16) & 0xff;
344    data[6] = (kSourceID >> 8) & 0xff;
345    data[7] = kSourceID & 0xff;
346
347    data[8] = mID >> 24;
348    data[9] = (mID >> 16) & 0xff;
349    data[10] = (mID >> 8) & 0xff;
350    data[11] = mID & 0xff;
351
352    data[12] = 0x00;  // fraction lost
353
354    data[13] = 0x00;  // cumulative lost
355    data[14] = 0x00;
356    data[15] = 0x00;
357
358    data[16] = mHighestSeqNumber >> 24;
359    data[17] = (mHighestSeqNumber >> 16) & 0xff;
360    data[18] = (mHighestSeqNumber >> 8) & 0xff;
361    data[19] = mHighestSeqNumber & 0xff;
362
363    data[20] = 0x00;  // Interarrival jitter
364    data[21] = 0x00;
365    data[22] = 0x00;
366    data[23] = 0x00;
367
368    uint32_t LSR = 0;
369    uint32_t DLSR = 0;
370    if (mLastNTPTime != 0) {
371        LSR = (mLastNTPTime >> 16) & 0xffffffff;
372
373        DLSR = (uint32_t)
374            ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6);
375    }
376
377    data[24] = LSR >> 24;
378    data[25] = (LSR >> 16) & 0xff;
379    data[26] = (LSR >> 8) & 0xff;
380    data[27] = LSR & 0xff;
381
382    data[28] = DLSR >> 24;
383    data[29] = (DLSR >> 16) & 0xff;
384    data[30] = (DLSR >> 8) & 0xff;
385    data[31] = DLSR & 0xff;
386
387    buffer->setRange(buffer->offset(), buffer->size() + 32);
388}
389
390}  // namespace android
391
392
393