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