|
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> ¬ify) |
|
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, ¶ms); |
|
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 |