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