blob: 3aa07cec4c4418241de97f9ee927b818ca20680a [file] [log] [blame]
Andreas Huber7a747b82010-06-07 15:19:40 -07001/*
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
Andreas Huber6e3fa442010-09-21 13:13:15 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "ARTPSource"
19#include <utils/Log.h>
20
Andreas Huber7a747b82010-06-07 15:19:40 -070021#include "ARTPSource.h"
22
Andreas Huber57648e42010-08-04 10:14:30 -070023#include "AAMRAssembler.h"
Andreas Huber7a747b82010-06-07 15:19:40 -070024#include "AAVCAssembler.h"
Andreas Huber57648e42010-08-04 10:14:30 -070025#include "AH263Assembler.h"
Andreas Huber7a747b82010-06-07 15:19:40 -070026#include "AMPEG4AudioAssembler.h"
Andreas Hubera979ad62010-08-19 10:56:15 -070027#include "AMPEG4ElementaryAssembler.h"
Andreas Huberb6723732011-02-22 16:25:00 -080028#include "ARawAudioAssembler.h"
Andreas Huber7a747b82010-06-07 15:19:40 -070029#include "ASessionDescription.h"
30
31#include <media/stagefright/foundation/ABuffer.h>
32#include <media/stagefright/foundation/ADebug.h>
33#include <media/stagefright/foundation/AMessage.h>
34
Andreas Huber7a747b82010-06-07 15:19:40 -070035namespace android {
36
Andreas Huber57648e42010-08-04 10:14:30 -070037static const uint32_t kSourceID = 0xdeadbeef;
38
Andreas Huber7a747b82010-06-07 15:19:40 -070039ARTPSource::ARTPSource(
40 uint32_t id,
41 const sp<ASessionDescription> &sessionDesc, size_t index,
42 const sp<AMessage> &notify)
43 : mID(id),
44 mHighestSeqNumber(0),
45 mNumBuffersReceived(0),
Andreas Huber57648e42010-08-04 10:14:30 -070046 mLastNTPTime(0),
47 mLastNTPTimeUpdateUs(0),
48 mIssueFIRRequests(false),
49 mLastFIRRequestUs(-1),
Andreas Huberb2934b12011-02-08 10:18:41 -080050 mNextFIRSeqNo((rand() * 256.0) / RAND_MAX),
51 mNotify(notify) {
Andreas Huber7a747b82010-06-07 15:19:40 -070052 unsigned long PT;
53 AString desc;
54 AString params;
55 sessionDesc->getFormatType(index, &PT, &desc, &params);
56
57 if (!strncmp(desc.c_str(), "H264/", 5)) {
58 mAssembler = new AAVCAssembler(notify);
Andreas Huber57648e42010-08-04 10:14:30 -070059 mIssueFIRRequests = true;
60 } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
Andreas Huberb0d25a02010-10-27 13:59:59 -070061 mAssembler = new AMPEG4AudioAssembler(notify, params);
Andreas Huber57648e42010-08-04 10:14:30 -070062 } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
63 || !strncmp(desc.c_str(), "H263-2000/", 10)) {
64 mAssembler = new AH263Assembler(notify);
Andreas Huber3eaa3002010-08-05 09:22:25 -070065 mIssueFIRRequests = true;
Andreas Huber57648e42010-08-04 10:14:30 -070066 } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
67 mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
68 } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
69 mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
Andreas Hubere536f802010-08-31 14:25:36 -070070 } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
Andreas Huber04072692011-02-15 10:39:48 -080071 || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
Andreas Hubere536f802010-08-31 14:25:36 -070072 mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
Andreas Hubera979ad62010-08-19 10:56:15 -070073 mIssueFIRRequests = true;
Andreas Huberb6723732011-02-22 16:25:00 -080074 } else if (ARawAudioAssembler::Supports(desc.c_str())) {
75 mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params);
Andreas Huber7a747b82010-06-07 15:19:40 -070076 } else {
77 TRESPASS();
78 }
79}
80
81static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
82 return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
83}
84
85void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
Andreas Huberb2934b12011-02-08 10:18:41 -080086 if (queuePacket(buffer) && mAssembler != NULL) {
Andreas Huber7a747b82010-06-07 15:19:40 -070087 mAssembler->onPacketReceived(this);
88 }
Andreas Huber7a747b82010-06-07 15:19:40 -070089}
90
91void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
Andreas Huber57648e42010-08-04 10:14:30 -070092 mLastNTPTime = ntpTime;
93 mLastNTPTimeUpdateUs = ALooper::GetNowUs();
94
Andreas Huberb2934b12011-02-08 10:18:41 -080095 sp<AMessage> notify = mNotify->dup();
96 notify->setInt32("time-update", true);
97 notify->setInt32("rtp-time", rtpTime);
98 notify->setInt64("ntp-time", ntpTime);
99 notify->post();
Andreas Huber7a747b82010-06-07 15:19:40 -0700100}
101
102bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
103 uint32_t seqNum = (uint32_t)buffer->int32Data();
104
Andreas Huber7a747b82010-06-07 15:19:40 -0700105 if (mNumBuffersReceived++ == 0) {
106 mHighestSeqNumber = seqNum;
107 mQueue.push_back(buffer);
108 return true;
109 }
110
111 // Only the lower 16-bit of the sequence numbers are transmitted,
112 // derive the high-order bits by choosing the candidate closest
113 // to the highest sequence number (extended to 32 bits) received so far.
114
115 uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
116 uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
117 uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
118 uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
119 uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
120 uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
121
122 if (diff1 < diff2) {
123 if (diff1 < diff3) {
124 // diff1 < diff2 ^ diff1 < diff3
125 seqNum = seq1;
126 } else {
127 // diff3 <= diff1 < diff2
128 seqNum = seq3;
129 }
130 } else if (diff2 < diff3) {
131 // diff2 <= diff1 ^ diff2 < diff3
132 seqNum = seq2;
133 } else {
134 // diff3 <= diff2 <= diff1
135 seqNum = seq3;
136 }
137
138 if (seqNum > mHighestSeqNumber) {
139 mHighestSeqNumber = seqNum;
140 }
141
142 buffer->setInt32Data(seqNum);
143
144 List<sp<ABuffer> >::iterator it = mQueue.begin();
145 while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
146 ++it;
147 }
148
149 if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
Andreas Huber6e3fa442010-09-21 13:13:15 -0700150 LOGW("Discarding duplicate buffer");
Andreas Huber7a747b82010-06-07 15:19:40 -0700151 return false;
152 }
153
154 mQueue.insert(it, buffer);
155
156 return true;
157}
158
Andreas Huber57648e42010-08-04 10:14:30 -0700159void ARTPSource::byeReceived() {
160 mAssembler->onByeReceived();
161}
162
163void ARTPSource::addFIR(const sp<ABuffer> &buffer) {
164 if (!mIssueFIRRequests) {
165 return;
166 }
167
168 int64_t nowUs = ALooper::GetNowUs();
169 if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
170 // Send FIR requests at most every 5 secs.
171 return;
172 }
173
174 mLastFIRRequestUs = nowUs;
175
176 if (buffer->size() + 20 > buffer->capacity()) {
Andreas Huber6e3fa442010-09-21 13:13:15 -0700177 LOGW("RTCP buffer too small to accomodate FIR.");
Andreas Huber57648e42010-08-04 10:14:30 -0700178 return;
179 }
180
181 uint8_t *data = buffer->data() + buffer->size();
182
183 data[0] = 0x80 | 4;
184 data[1] = 206; // PSFB
185 data[2] = 0;
186 data[3] = 4;
187 data[4] = kSourceID >> 24;
188 data[5] = (kSourceID >> 16) & 0xff;
189 data[6] = (kSourceID >> 8) & 0xff;
190 data[7] = kSourceID & 0xff;
191
192 data[8] = 0x00; // SSRC of media source (unused)
193 data[9] = 0x00;
194 data[10] = 0x00;
195 data[11] = 0x00;
196
197 data[12] = mID >> 24;
198 data[13] = (mID >> 16) & 0xff;
199 data[14] = (mID >> 8) & 0xff;
200 data[15] = mID & 0xff;
201
202 data[16] = mNextFIRSeqNo++; // Seq Nr.
203
204 data[17] = 0x00; // Reserved
205 data[18] = 0x00;
206 data[19] = 0x00;
207
208 buffer->setRange(buffer->offset(), buffer->size() + 20);
209
Andreas Huber6e3fa442010-09-21 13:13:15 -0700210 LOGV("Added FIR request.");
Andreas Huber57648e42010-08-04 10:14:30 -0700211}
212
213void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
214 if (buffer->size() + 32 > buffer->capacity()) {
Andreas Huber6e3fa442010-09-21 13:13:15 -0700215 LOGW("RTCP buffer too small to accomodate RR.");
Andreas Huber57648e42010-08-04 10:14:30 -0700216 return;
217 }
218
219 uint8_t *data = buffer->data() + buffer->size();
220
221 data[0] = 0x80 | 1;
222 data[1] = 201; // RR
223 data[2] = 0;
224 data[3] = 7;
225 data[4] = kSourceID >> 24;
226 data[5] = (kSourceID >> 16) & 0xff;
227 data[6] = (kSourceID >> 8) & 0xff;
228 data[7] = kSourceID & 0xff;
229
230 data[8] = mID >> 24;
231 data[9] = (mID >> 16) & 0xff;
232 data[10] = (mID >> 8) & 0xff;
233 data[11] = mID & 0xff;
234
235 data[12] = 0x00; // fraction lost
236
237 data[13] = 0x00; // cumulative lost
238 data[14] = 0x00;
239 data[15] = 0x00;
240
241 data[16] = mHighestSeqNumber >> 24;
242 data[17] = (mHighestSeqNumber >> 16) & 0xff;
243 data[18] = (mHighestSeqNumber >> 8) & 0xff;
244 data[19] = mHighestSeqNumber & 0xff;
245
246 data[20] = 0x00; // Interarrival jitter
247 data[21] = 0x00;
248 data[22] = 0x00;
249 data[23] = 0x00;
250
251 uint32_t LSR = 0;
252 uint32_t DLSR = 0;
253 if (mLastNTPTime != 0) {
254 LSR = (mLastNTPTime >> 16) & 0xffffffff;
255
256 DLSR = (uint32_t)
257 ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6);
258 }
259
260 data[24] = LSR >> 24;
261 data[25] = (LSR >> 16) & 0xff;
262 data[26] = (LSR >> 8) & 0xff;
263 data[27] = LSR & 0xff;
264
265 data[28] = DLSR >> 24;
266 data[29] = (DLSR >> 16) & 0xff;
267 data[30] = (DLSR >> 8) & 0xff;
268 data[31] = DLSR & 0xff;
269
270 buffer->setRange(buffer->offset(), buffer->size() + 32);
271}
272
Andreas Huber7a747b82010-06-07 15:19:40 -0700273} // namespace android
274
275