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