OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h" | |
12 | |
13 #include <stdio.h> | |
14 #include <stdlib.h> | |
15 | |
16 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | |
17 #include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h" | |
18 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
19 #include "webrtc/system_wrappers/include/event_wrapper.h" | |
20 #include "webrtc/system_wrappers/include/tick_util.h" | |
21 #include "webrtc/test/channel_transport/udp_transport.h" | |
22 | |
23 #define NR_OF_SOCKET_BUFFERS 500 | |
24 | |
25 | |
26 bool ProcThreadFunction(void *obj) | |
27 { | |
28 if (obj == NULL) | |
29 { | |
30 return false; | |
31 } | |
32 TestSenderReceiver *theObj = static_cast<TestSenderReceiver *>(obj); | |
33 | |
34 return theObj->ProcLoop(); | |
35 } | |
36 | |
37 | |
38 TestSenderReceiver::TestSenderReceiver (void) | |
39 : | |
40 _critSect(CriticalSectionWrapper::CreateCriticalSection()), | |
41 _eventPtr(NULL), | |
42 _procThread(ProcThreadFunction, this, "TestSenderReceiver"), | |
43 _running(false), | |
44 _payloadType(0), | |
45 _loadGenerator(NULL), | |
46 _isSender(false), | |
47 _isReceiver(false), | |
48 _sendRecCB(NULL), | |
49 _lastBytesReceived(0), | |
50 _lastTime(-1) | |
51 { | |
52 // RTP/RTCP module | |
53 _rtp = RtpRtcp::CreateRtpRtcp(0, false); | |
54 if (!_rtp) | |
55 { | |
56 throw "Could not create RTP/RTCP module"; | |
57 exit(1); | |
58 } | |
59 | |
60 if (_rtp->InitReceiver() != 0) | |
61 { | |
62 throw "_rtp->InitReceiver()"; | |
63 exit(1); | |
64 } | |
65 | |
66 if (_rtp->InitSender() != 0) | |
67 { | |
68 throw "_rtp->InitSender()"; | |
69 exit(1); | |
70 } | |
71 | |
72 // SocketTransport module | |
73 uint8_t numberOfThreads = 1; | |
74 _transport = UdpTransport::Create(0, numberOfThreads); | |
75 if (!_transport) | |
76 { | |
77 throw "Could not create transport module"; | |
78 exit(1); | |
79 } | |
80 } | |
81 | |
82 TestSenderReceiver::~TestSenderReceiver (void) | |
83 { | |
84 | |
85 Stop(); // N.B. without critSect | |
86 | |
87 _critSect->Enter(); | |
88 | |
89 if (_rtp) | |
90 { | |
91 RtpRtcp::DestroyRtpRtcp(_rtp); | |
92 _rtp = NULL; | |
93 } | |
94 | |
95 if (_transport) | |
96 { | |
97 UdpTransport::Destroy(_transport); | |
98 _transport = NULL; | |
99 } | |
100 | |
101 delete _critSect; | |
102 | |
103 } | |
104 | |
105 | |
106 int32_t TestSenderReceiver::InitReceiver (const uint16_t rtpPort, | |
107 const uint16_t rtcpPort, | |
108 const int8_t payloadType /*= 127*/) | |
109 { | |
110 CriticalSectionScoped cs(_critSect); | |
111 | |
112 // init transport | |
113 if (_transport->InitializeReceiveSockets(this, rtpPort/*, 0, NULL, 0, true*/
) != 0) | |
114 { | |
115 throw "_transport->InitializeReceiveSockets"; | |
116 exit(1); | |
117 } | |
118 | |
119 if (_rtp->RegisterIncomingRTPCallback(this) != 0) | |
120 { | |
121 throw "_rtp->RegisterIncomingRTPCallback"; | |
122 exit(1); | |
123 } | |
124 | |
125 if (_rtp->RegisterIncomingDataCallback(this) != 0) | |
126 { | |
127 throw "_rtp->RegisterIncomingRTPCallback"; | |
128 exit(1); | |
129 } | |
130 | |
131 if (_rtp->SetRTCPStatus(RtcpMode::kReducedSize) != 0) { | |
132 throw "_rtp->SetRTCPStatus"; | |
133 exit(1); | |
134 } | |
135 | |
136 if (_rtp->SetTMMBRStatus(true) != 0) | |
137 { | |
138 throw "_rtp->SetTMMBRStatus"; | |
139 exit(1); | |
140 } | |
141 | |
142 if (_rtp->RegisterReceivePayload("I420", payloadType, 90000) != 0) | |
143 { | |
144 throw "_rtp->RegisterReceivePayload"; | |
145 exit(1); | |
146 } | |
147 | |
148 _isReceiver = true; | |
149 | |
150 return (0); | |
151 } | |
152 | |
153 | |
154 int32_t TestSenderReceiver::Start() | |
155 { | |
156 CriticalSectionScoped cs(_critSect); | |
157 | |
158 _eventPtr = EventWrapper::Create(); | |
159 | |
160 if (_rtp->SetSendingStatus(true) != 0) | |
161 { | |
162 throw "_rtp->SetSendingStatus"; | |
163 exit(1); | |
164 } | |
165 | |
166 _running = true; | |
167 | |
168 if (_isReceiver) | |
169 { | |
170 if (_transport->StartReceiving(NR_OF_SOCKET_BUFFERS) != 0) | |
171 { | |
172 throw "_transport->StartReceiving"; | |
173 exit(1); | |
174 } | |
175 } | |
176 | |
177 _procThread.Start(); | |
178 _procThread.SetPriority(rtc::kRealtimePriority); | |
179 | |
180 return 0; | |
181 | |
182 } | |
183 | |
184 | |
185 int32_t TestSenderReceiver::Stop () | |
186 { | |
187 CriticalSectionScoped cs(_critSect); | |
188 | |
189 _transport->StopReceiving(); | |
190 | |
191 if (_running) | |
192 { | |
193 _running = false; | |
194 _eventPtr->Set(); | |
195 | |
196 _procThread.Stop(); | |
197 | |
198 delete _eventPtr; | |
199 } | |
200 | |
201 return (0); | |
202 } | |
203 | |
204 | |
205 bool TestSenderReceiver::ProcLoop(void) | |
206 { | |
207 | |
208 // process RTP/RTCP module | |
209 _rtp->Process(); | |
210 | |
211 // process SocketTransport module | |
212 _transport->Process(); | |
213 | |
214 // no critSect | |
215 while (_running) | |
216 { | |
217 // ask RTP/RTCP module for wait time | |
218 int32_t rtpWait = _rtp->TimeUntilNextProcess(); | |
219 | |
220 // ask SocketTransport module for wait time | |
221 int32_t tpWait = _transport->TimeUntilNextProcess(); | |
222 | |
223 int32_t minWait = (rtpWait < tpWait) ? rtpWait: tpWait; | |
224 minWait = (minWait > 0) ? minWait : 0; | |
225 // wait | |
226 _eventPtr->Wait(minWait); | |
227 | |
228 // process RTP/RTCP module | |
229 _rtp->Process(); | |
230 | |
231 // process SocketTransport module | |
232 _transport->Process(); | |
233 | |
234 } | |
235 | |
236 return true; | |
237 } | |
238 | |
239 | |
240 int32_t TestSenderReceiver::ReceiveBitrateKbps () | |
241 { | |
242 size_t bytesSent; | |
243 uint32_t packetsSent; | |
244 size_t bytesReceived; | |
245 uint32_t packetsReceived; | |
246 | |
247 if (_rtp->DataCountersRTP(&bytesSent, &packetsSent, &bytesReceived, &packets
Received) == 0) | |
248 { | |
249 int64_t now = TickTime::MillisecondTimestamp(); | |
250 int32_t kbps = 0; | |
251 if (now > _lastTime) | |
252 { | |
253 if (_lastTime > 0) | |
254 { | |
255 // 8 * bytes / ms = kbps | |
256 kbps = static_cast<int32_t>( | |
257 (8 * (bytesReceived - _lastBytesReceived)) / (now - _lastTim
e)); | |
258 } | |
259 _lastTime = now; | |
260 _lastBytesReceived = bytesReceived; | |
261 } | |
262 return (kbps); | |
263 } | |
264 | |
265 return (-1); | |
266 } | |
267 | |
268 | |
269 int32_t TestSenderReceiver::SetPacketTimeout(const uint32_t timeoutMS) | |
270 { | |
271 return (_rtp->SetPacketTimeout(timeoutMS, 0 /* RTCP timeout */)); | |
272 } | |
273 | |
274 | |
275 int32_t TestSenderReceiver::OnReceivedPayloadData(const uint8_t* payloadData, | |
276 const size_t payloadSize, | |
277 const webrtc::WebRtcRTPHeader*
rtpHeader) | |
278 { | |
279 //printf("OnReceivedPayloadData\n"); | |
280 return (0); | |
281 } | |
282 | |
283 | |
284 void TestSenderReceiver::IncomingRTPPacket(const int8_t* incomingRtpPacket, | |
285 const size_t rtpPacketLength, | |
286 const int8_t* fromIP, | |
287 const uint16_t fromPort) | |
288 { | |
289 _rtp->IncomingPacket((uint8_t *) incomingRtpPacket, rtpPacketLength); | |
290 } | |
291 | |
292 | |
293 | |
294 void TestSenderReceiver::IncomingRTCPPacket(const int8_t* incomingRtcpPacket, | |
295 const size_t rtcpPacketLength, | |
296 const int8_t* fromIP, | |
297 const uint16_t fromPort) | |
298 { | |
299 _rtp->IncomingPacket((uint8_t *) incomingRtcpPacket, rtcpPacketLength); | |
300 } | |
301 | |
302 | |
303 | |
304 | |
305 | |
306 /////////////////// | |
307 | |
308 | |
309 int32_t TestSenderReceiver::InitSender (const uint32_t startBitrateKbps, | |
310 const int8_t* ipAddr, | |
311 const uint16_t rtpPort, | |
312 const uint16_t rtcpPort /*= 0*/, | |
313 const int8_t payloadType /*= 127*/) | |
314 { | |
315 CriticalSectionScoped cs(_critSect); | |
316 | |
317 _payloadType = payloadType; | |
318 | |
319 // check load generator valid | |
320 if (_loadGenerator) | |
321 { | |
322 _loadGenerator->SetBitrate(startBitrateKbps); | |
323 } | |
324 | |
325 if (_rtp->RegisterSendTransport(_transport) != 0) | |
326 { | |
327 throw "_rtp->RegisterSendTransport"; | |
328 exit(1); | |
329 } | |
330 if (_rtp->RegisterSendPayload("I420", _payloadType, 90000) != 0) | |
331 { | |
332 throw "_rtp->RegisterSendPayload"; | |
333 exit(1); | |
334 } | |
335 | |
336 if (_rtp->RegisterIncomingVideoCallback(this) != 0) | |
337 { | |
338 throw "_rtp->RegisterIncomingVideoCallback"; | |
339 exit(1); | |
340 } | |
341 | |
342 if (_rtp->SetRTCPStatus(RtcpMode::kReducedSize) != 0) { | |
343 throw "_rtp->SetRTCPStatus"; | |
344 exit(1); | |
345 } | |
346 | |
347 if (_rtp->SetSendBitrate(startBitrateKbps*1000, 0, MAX_BITRATE_KBPS) != 0) | |
348 { | |
349 throw "_rtp->SetSendBitrate"; | |
350 exit(1); | |
351 } | |
352 | |
353 | |
354 // SocketTransport | |
355 if (_transport->InitializeSendSockets(ipAddr, rtpPort, rtcpPort)) | |
356 { | |
357 throw "_transport->InitializeSendSockets"; | |
358 exit(1); | |
359 } | |
360 | |
361 _isSender = true; | |
362 | |
363 return (0); | |
364 } | |
365 | |
366 | |
367 | |
368 int32_t | |
369 TestSenderReceiver::SendOutgoingData(const uint32_t timeStamp, | |
370 const uint8_t* payloadData, | |
371 const size_t payloadSize, | |
372 const webrtc::FrameType frameType /*= webrt
c::kVideoFrameDelta*/) | |
373 { | |
374 return (_rtp->SendOutgoingData(frameType, _payloadType, timeStamp, payloadDa
ta, payloadSize)); | |
375 } | |
376 | |
377 | |
378 int32_t TestSenderReceiver::SetLoadGenerator(TestLoadGenerator *generator) | |
379 { | |
380 CriticalSectionScoped cs(_critSect); | |
381 | |
382 _loadGenerator = generator; | |
383 return(0); | |
384 | |
385 } | |
386 | |
387 void TestSenderReceiver::OnNetworkChanged(const int32_t id, | |
388 const uint32_t minBitrateBps, | |
389 const uint32_t maxBitrateBps, | |
390 const uint8_t fractionLost, | |
391 const uint16_t roundTripTimeMs, | |
392 const uint16_t bwEstimateKbitMin, | |
393 const uint16_t bwEstimateKbitMax) | |
394 { | |
395 if (_loadGenerator) | |
396 { | |
397 _loadGenerator->SetBitrate(maxBitrateBps/1000); | |
398 } | |
399 | |
400 if (_sendRecCB) | |
401 { | |
402 _sendRecCB->OnOnNetworkChanged(maxBitrateBps, | |
403 fractionLost, | |
404 roundTripTimeMs, | |
405 bwEstimateKbitMin, | |
406 bwEstimateKbitMax); | |
407 } | |
408 } | |
OLD | NEW |