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