> Revert 8810 "- Add a SetPriority method to ThreadWrapper" > Seeing if this is causing roll issues. > > > - Add a SetPriority method to ThreadWrapper > > - Remove 'priority' from CreateThread and related member variables from implementations > > - Make supplying a name for threads, non-optional > > > > BUG= > > R=magjed@webrtc.org > > > > Review URL: https://webrtc-codereview.appspot.com/44729004 > > TBR=tommi@webrtc.org > > Review URL: https://webrtc-codereview.appspot.com/48609004 TBR=tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/50459005 Cr-Commit-Position: refs/heads/master@{#8819} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8819 4adac7df-926f-26a2-2b94-8c16560cd09d
414 lines
9.7 KiB
C++
414 lines
9.7 KiB
C++
/*
|
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
|
#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h"
|
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
|
#include "webrtc/system_wrappers/interface/tick_util.h"
|
|
#include "webrtc/test/channel_transport/udp_transport.h"
|
|
|
|
#define NR_OF_SOCKET_BUFFERS 500
|
|
|
|
|
|
bool ProcThreadFunction(void *obj)
|
|
{
|
|
if (obj == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
TestSenderReceiver *theObj = static_cast<TestSenderReceiver *>(obj);
|
|
|
|
return theObj->ProcLoop();
|
|
}
|
|
|
|
|
|
TestSenderReceiver::TestSenderReceiver (void)
|
|
:
|
|
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
|
|
_eventPtr(NULL),
|
|
_running(false),
|
|
_payloadType(0),
|
|
_loadGenerator(NULL),
|
|
_isSender(false),
|
|
_isReceiver(false),
|
|
_sendRecCB(NULL),
|
|
_lastBytesReceived(0),
|
|
_lastTime(-1)
|
|
{
|
|
// RTP/RTCP module
|
|
_rtp = RtpRtcp::CreateRtpRtcp(0, false);
|
|
if (!_rtp)
|
|
{
|
|
throw "Could not create RTP/RTCP module";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->InitReceiver() != 0)
|
|
{
|
|
throw "_rtp->InitReceiver()";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->InitSender() != 0)
|
|
{
|
|
throw "_rtp->InitSender()";
|
|
exit(1);
|
|
}
|
|
|
|
// SocketTransport module
|
|
uint8_t numberOfThreads = 1;
|
|
_transport = UdpTransport::Create(0, numberOfThreads);
|
|
if (!_transport)
|
|
{
|
|
throw "Could not create transport module";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
TestSenderReceiver::~TestSenderReceiver (void)
|
|
{
|
|
|
|
Stop(); // N.B. without critSect
|
|
|
|
_critSect->Enter();
|
|
|
|
if (_rtp)
|
|
{
|
|
RtpRtcp::DestroyRtpRtcp(_rtp);
|
|
_rtp = NULL;
|
|
}
|
|
|
|
if (_transport)
|
|
{
|
|
UdpTransport::Destroy(_transport);
|
|
_transport = NULL;
|
|
}
|
|
|
|
delete _critSect;
|
|
|
|
}
|
|
|
|
|
|
int32_t TestSenderReceiver::InitReceiver (const uint16_t rtpPort,
|
|
const uint16_t rtcpPort,
|
|
const int8_t payloadType /*= 127*/)
|
|
{
|
|
CriticalSectionScoped cs(_critSect);
|
|
|
|
// init transport
|
|
if (_transport->InitializeReceiveSockets(this, rtpPort/*, 0, NULL, 0, true*/) != 0)
|
|
{
|
|
throw "_transport->InitializeReceiveSockets";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->RegisterIncomingRTPCallback(this) != 0)
|
|
{
|
|
throw "_rtp->RegisterIncomingRTPCallback";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->RegisterIncomingDataCallback(this) != 0)
|
|
{
|
|
throw "_rtp->RegisterIncomingRTPCallback";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->SetRTCPStatus(kRtcpNonCompound) != 0)
|
|
{
|
|
throw "_rtp->SetRTCPStatus";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->SetTMMBRStatus(true) != 0)
|
|
{
|
|
throw "_rtp->SetTMMBRStatus";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->RegisterReceivePayload("I420", payloadType, 90000) != 0)
|
|
{
|
|
throw "_rtp->RegisterReceivePayload";
|
|
exit(1);
|
|
}
|
|
|
|
_isReceiver = true;
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
int32_t TestSenderReceiver::Start()
|
|
{
|
|
CriticalSectionScoped cs(_critSect);
|
|
|
|
_eventPtr = EventWrapper::Create();
|
|
|
|
if (_rtp->SetSendingStatus(true) != 0)
|
|
{
|
|
throw "_rtp->SetSendingStatus";
|
|
exit(1);
|
|
}
|
|
|
|
_procThread = ThreadWrapper::CreateThread(ProcThreadFunction, this,
|
|
"TestSenderReceiver");
|
|
|
|
_running = true;
|
|
|
|
if (_isReceiver)
|
|
{
|
|
if (_transport->StartReceiving(NR_OF_SOCKET_BUFFERS) != 0)
|
|
{
|
|
throw "_transport->StartReceiving";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
_procThread->Start();
|
|
_procThread->SetPriority(kRealtimePriority);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
int32_t TestSenderReceiver::Stop ()
|
|
{
|
|
CriticalSectionScoped cs(_critSect);
|
|
|
|
_transport->StopReceiving();
|
|
|
|
if (_procThread)
|
|
{
|
|
_running = false;
|
|
_eventPtr->Set();
|
|
|
|
_procThread->Stop();
|
|
_procThread.reset();
|
|
|
|
delete _eventPtr;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
bool TestSenderReceiver::ProcLoop(void)
|
|
{
|
|
|
|
// process RTP/RTCP module
|
|
_rtp->Process();
|
|
|
|
// process SocketTransport module
|
|
_transport->Process();
|
|
|
|
// no critSect
|
|
while (_running)
|
|
{
|
|
// ask RTP/RTCP module for wait time
|
|
int32_t rtpWait = _rtp->TimeUntilNextProcess();
|
|
|
|
// ask SocketTransport module for wait time
|
|
int32_t tpWait = _transport->TimeUntilNextProcess();
|
|
|
|
int32_t minWait = (rtpWait < tpWait) ? rtpWait: tpWait;
|
|
minWait = (minWait > 0) ? minWait : 0;
|
|
// wait
|
|
_eventPtr->Wait(minWait);
|
|
|
|
// process RTP/RTCP module
|
|
_rtp->Process();
|
|
|
|
// process SocketTransport module
|
|
_transport->Process();
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
int32_t TestSenderReceiver::ReceiveBitrateKbps ()
|
|
{
|
|
size_t bytesSent;
|
|
uint32_t packetsSent;
|
|
size_t bytesReceived;
|
|
uint32_t packetsReceived;
|
|
|
|
if (_rtp->DataCountersRTP(&bytesSent, &packetsSent, &bytesReceived, &packetsReceived) == 0)
|
|
{
|
|
int64_t now = TickTime::MillisecondTimestamp();
|
|
int32_t kbps = 0;
|
|
if (now > _lastTime)
|
|
{
|
|
if (_lastTime > 0)
|
|
{
|
|
// 8 * bytes / ms = kbps
|
|
kbps = static_cast<int32_t>(
|
|
(8 * (bytesReceived - _lastBytesReceived)) / (now - _lastTime));
|
|
}
|
|
_lastTime = now;
|
|
_lastBytesReceived = bytesReceived;
|
|
}
|
|
return (kbps);
|
|
}
|
|
|
|
return (-1);
|
|
}
|
|
|
|
|
|
int32_t TestSenderReceiver::SetPacketTimeout(const uint32_t timeoutMS)
|
|
{
|
|
return (_rtp->SetPacketTimeout(timeoutMS, 0 /* RTCP timeout */));
|
|
}
|
|
|
|
|
|
int32_t TestSenderReceiver::OnReceivedPayloadData(const uint8_t* payloadData,
|
|
const size_t payloadSize,
|
|
const webrtc::WebRtcRTPHeader* rtpHeader)
|
|
{
|
|
//printf("OnReceivedPayloadData\n");
|
|
return (0);
|
|
}
|
|
|
|
|
|
void TestSenderReceiver::IncomingRTPPacket(const int8_t* incomingRtpPacket,
|
|
const size_t rtpPacketLength,
|
|
const int8_t* fromIP,
|
|
const uint16_t fromPort)
|
|
{
|
|
_rtp->IncomingPacket((uint8_t *) incomingRtpPacket, rtpPacketLength);
|
|
}
|
|
|
|
|
|
|
|
void TestSenderReceiver::IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
|
|
const size_t rtcpPacketLength,
|
|
const int8_t* fromIP,
|
|
const uint16_t fromPort)
|
|
{
|
|
_rtp->IncomingPacket((uint8_t *) incomingRtcpPacket, rtcpPacketLength);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
|
|
|
|
int32_t TestSenderReceiver::InitSender (const uint32_t startBitrateKbps,
|
|
const int8_t* ipAddr,
|
|
const uint16_t rtpPort,
|
|
const uint16_t rtcpPort /*= 0*/,
|
|
const int8_t payloadType /*= 127*/)
|
|
{
|
|
CriticalSectionScoped cs(_critSect);
|
|
|
|
_payloadType = payloadType;
|
|
|
|
// check load generator valid
|
|
if (_loadGenerator)
|
|
{
|
|
_loadGenerator->SetBitrate(startBitrateKbps);
|
|
}
|
|
|
|
if (_rtp->RegisterSendTransport(_transport) != 0)
|
|
{
|
|
throw "_rtp->RegisterSendTransport";
|
|
exit(1);
|
|
}
|
|
if (_rtp->RegisterSendPayload("I420", _payloadType, 90000) != 0)
|
|
{
|
|
throw "_rtp->RegisterSendPayload";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->RegisterIncomingVideoCallback(this) != 0)
|
|
{
|
|
throw "_rtp->RegisterIncomingVideoCallback";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->SetRTCPStatus(kRtcpNonCompound) != 0)
|
|
{
|
|
throw "_rtp->SetRTCPStatus";
|
|
exit(1);
|
|
}
|
|
|
|
if (_rtp->SetSendBitrate(startBitrateKbps*1000, 0, MAX_BITRATE_KBPS) != 0)
|
|
{
|
|
throw "_rtp->SetSendBitrate";
|
|
exit(1);
|
|
}
|
|
|
|
|
|
// SocketTransport
|
|
if (_transport->InitializeSendSockets(ipAddr, rtpPort, rtcpPort))
|
|
{
|
|
throw "_transport->InitializeSendSockets";
|
|
exit(1);
|
|
}
|
|
|
|
_isSender = true;
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
|
|
int32_t
|
|
TestSenderReceiver::SendOutgoingData(const uint32_t timeStamp,
|
|
const uint8_t* payloadData,
|
|
const size_t payloadSize,
|
|
const webrtc::FrameType frameType /*= webrtc::kVideoFrameDelta*/)
|
|
{
|
|
return (_rtp->SendOutgoingData(frameType, _payloadType, timeStamp, payloadData, payloadSize));
|
|
}
|
|
|
|
|
|
int32_t TestSenderReceiver::SetLoadGenerator(TestLoadGenerator *generator)
|
|
{
|
|
CriticalSectionScoped cs(_critSect);
|
|
|
|
_loadGenerator = generator;
|
|
return(0);
|
|
|
|
}
|
|
|
|
void TestSenderReceiver::OnNetworkChanged(const int32_t id,
|
|
const uint32_t minBitrateBps,
|
|
const uint32_t maxBitrateBps,
|
|
const uint8_t fractionLost,
|
|
const uint16_t roundTripTimeMs,
|
|
const uint16_t bwEstimateKbitMin,
|
|
const uint16_t bwEstimateKbitMax)
|
|
{
|
|
if (_loadGenerator)
|
|
{
|
|
_loadGenerator->SetBitrate(maxBitrateBps/1000);
|
|
}
|
|
|
|
if (_sendRecCB)
|
|
{
|
|
_sendRecCB->OnOnNetworkChanged(maxBitrateBps,
|
|
fractionLost,
|
|
roundTripTimeMs,
|
|
bwEstimateKbitMin,
|
|
bwEstimateKbitMax);
|
|
}
|
|
}
|