netwerk/protocol/rtsp/rtsp/ARTPSource.cpp

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

mercurial