Introduce a mockable RtpRtcpClock interface replacing ModuleRTPUtility time functions

A new RtpRtcpClock interface has been added to rtp_rtcp_defines.h
and provides time facilities used by an RTP/RTCP module. Also,
NTP constants have been made public in the
webrtc::ModuleRTPUtility namespace to make implementation of
external clocks easier.

An overloaded version of CreateRtpRtcp() accepts a clock argument. By
default, if no clock is provided, the module uses the system clock
(old ModuleRTPUtility implementation).

Throughout the RTP/RTCP module code, calls to TickTime and
ModuleRTPUtility time functions have been replaced with calls to time
methods on a clock object.

The following classes take a clock object in their constructor and
hold a _clock field (either directly, or inherited from a parent):

Bitrate
ModuleRtpRtcpImpl
RTCPReceiver
RTCPSender
RTPReceiver
RTPSender
RTPSenderAudio
RTPSenderVideo

Methods from other classes that do not derive any of those and
require a time take an additional nowMS parameter, that should be
the result of calling GetTimeInMS() on a clock object.
Review URL: http://webrtc-codereview.appspot.com/268017

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1076 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pwestin@webrtc.org 2011-12-01 15:42:31 +00:00
parent 132feb1270
commit 0644b1dc35
31 changed files with 433 additions and 266 deletions

View File

@ -22,7 +22,7 @@ class RtpRtcp : public Module
{
public:
/*
* create a RTP/RTCP module object
* create a RTP/RTCP module object using the system clock
*
* id - unique identifier of this RTP/RTCP module object
* audio - true for a audio version of the RTP/RTCP module object false will create a video version
@ -30,6 +30,18 @@ public:
static RtpRtcp* CreateRtpRtcp(const WebRtc_Word32 id,
const bool audio);
/*
* create a RTP/RTCP module object
*
* id - unique identifier of this RTP/RTCP module object
* audio - true for a audio version of the RTP/RTCP module object
* false will create a video version
* clock - the clock to use to read time; must not be NULL
*/
static RtpRtcp* CreateRtpRtcp(const WebRtc_Word32 id,
const bool audio,
RtpRtcpClock* clock);
/*
* destroy a RTP/RTCP module object
*

View File

@ -222,6 +222,22 @@ public:
protected:
virtual ~RtpVideoFeedback() {}
};
// A clock interface that allows reading of absolute and relative
// timestamps in an RTP/RTCP module.
class RtpRtcpClock {
public:
// Return a timestamp in milliseconds relative to some arbitrary
// source; the source is fixed for this clock.
virtual WebRtc_UWord32 GetTimeInMS() = 0;
// Retrieve an NTP absolute timestamp.
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac) = 0;
protected:
virtual ~RtpRtcpClock() {}
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_

View File

@ -18,10 +18,12 @@
#include <list>
namespace webrtc {
class RtpRtcpClock;
class Bitrate
{
public:
Bitrate();
Bitrate(RtpRtcpClock* clock);
// initialize members
void Init();
@ -41,6 +43,9 @@ public:
// bitrate last second, updated now
WebRtc_UWord32 BitrateNow() const;
protected:
RtpRtcpClock& _clock;
private:
WebRtc_UWord32 _packetRate;
WebRtc_UWord32 _bitrate;

View File

@ -12,7 +12,6 @@
#include "trace.h"
#include "rtp_utility.h"
#include "rtp_rtcp_config.h"
#include "tick_util.h"
#include <math.h> // sqrt()
@ -110,7 +109,8 @@ WebRtc_Word32 BandwidthManagement::UpdatePacketLoss(
WebRtc_UWord32 sentBitrate,
const WebRtc_UWord16 rtt,
WebRtc_UWord8* loss,
WebRtc_UWord32* newBitrate)
WebRtc_UWord32* newBitrate,
WebRtc_Word64 nowMS)
{
CriticalSectionScoped cs(_critsect);
@ -172,7 +172,7 @@ WebRtc_Word32 BandwidthManagement::UpdatePacketLoss(
// Remember the sequence number until next time
_lastPacketLossExtendedHighSeqNum = lastReceivedExtendedHighSeqNum;
WebRtc_UWord32 bitRate = ShapeSimple(*loss, rtt, sentBitrate);
WebRtc_UWord32 bitRate = ShapeSimple(*loss, rtt, sentBitrate, nowMS);
if (bitRate == 0)
{
// no change
@ -216,7 +216,8 @@ WebRtc_Word32 BandwidthManagement::CalcTFRCbps(WebRtc_Word16 avgPackSizeBytes,
// protected
WebRtc_UWord32 BandwidthManagement::ShapeSimple(WebRtc_Word32 packetLoss,
WebRtc_Word32 rtt,
WebRtc_UWord32 sentBitrate)
WebRtc_UWord32 sentBitrate,
WebRtc_Word64 nowMS)
{
WebRtc_UWord32 newBitRate = 0;
bool reducing = false;
@ -224,12 +225,12 @@ WebRtc_UWord32 BandwidthManagement::ShapeSimple(WebRtc_Word32 packetLoss,
// Limit the rate increases to once a second.
if (packetLoss <= 5)
{
if ((TickTime::MillisecondTimestamp() - _timeLastIncrease) <
if ((nowMS - _timeLastIncrease) <
kBWEUpdateIntervalMs)
{
return _bitRate;
}
_timeLastIncrease = TickTime::MillisecondTimestamp();
_timeLastIncrease = nowMS;
}
if (packetLoss > 5 && packetLoss <= 26)

View File

@ -38,7 +38,8 @@ public:
WebRtc_UWord32 sentBitrate,
const WebRtc_UWord16 rtt,
WebRtc_UWord8* loss,
WebRtc_UWord32* newBitrate);
WebRtc_UWord32* newBitrate,
WebRtc_Word64 nowMS);
WebRtc_Word32 AvailableBandwidth(WebRtc_UWord16* bandwidthKbit) const;
@ -51,7 +52,8 @@ public:
protected:
WebRtc_UWord32 ShapeSimple(WebRtc_Word32 packetLoss,
WebRtc_Word32 rtt,
WebRtc_UWord32 sentBitrate);
WebRtc_UWord32 sentBitrate,
WebRtc_Word64 nowMS);
WebRtc_Word32 CalcTFRCbps(WebRtc_Word16 avgPackSizeBytes,
WebRtc_Word32 rttMs,

View File

@ -10,12 +10,12 @@
#include "Bitrate.h"
#include "rtp_utility.h"
#include "tick_util.h"
#define BITRATE_AVERAGE_WINDOW 2000
namespace webrtc {
Bitrate::Bitrate() :
Bitrate::Bitrate(RtpRtcpClock* clock) :
_clock(*clock),
_packetRate(0),
_bitrate(0),
_bitrateNextIdx(0),
@ -65,7 +65,7 @@ Bitrate::BitrateLast() const
WebRtc_UWord32
Bitrate::BitrateNow() const
{
WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 now = _clock.GetTimeInMS();
WebRtc_UWord32 diffMS = now -_timeLastRateUpdate;
if(diffMS > 10000) // 10 sec
@ -85,7 +85,7 @@ void
Bitrate::Process()
{
// triggered by timer
WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 now = _clock.GetTimeInMS();
WebRtc_UWord32 diffMS = now -_timeLastRateUpdate;
if(diffMS > 100)

View File

@ -8,7 +8,6 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "tick_util.h"
#include "trace.h"
#include "overuse_detector.h"
#include "remote_rate_control.h"
@ -135,11 +134,13 @@ void OverUseDetector::Reset()
}
}
bool OverUseDetector::Update(const WebRtcRTPHeader& rtpHeader, const WebRtc_UWord16 packetSize)
bool OverUseDetector::Update(const WebRtcRTPHeader& rtpHeader,
const WebRtc_UWord16 packetSize,
const WebRtc_Word64 nowMS)
{
#ifdef MATLAB
// Create plots
const WebRtc_Word64 startTimeMs = TickTime::MillisecondTimestamp();
const WebRtc_Word64 startTimeMs = nowMS;
if (_plot1 == NULL)
{
_plot1 = eng.NewPlot(new MatlabPlot());
@ -173,7 +174,6 @@ bool OverUseDetector::Update(const WebRtcRTPHeader& rtpHeader, const WebRtc_UWor
bool wrapped = false;
bool completeFrame = false;
const WebRtc_Word64 nowMs = TickTime::MillisecondTimestamp();
if (_currentFrame._timestamp == -1)
{
_currentFrame._timestamp = rtpHeader.header.timestamp;
@ -206,7 +206,7 @@ bool OverUseDetector::Update(const WebRtcRTPHeader& rtpHeader, const WebRtc_UWor
}
// Accumulate the frame size
_currentFrame._size += packetSize;
_currentFrame._completeTimeMs = nowMs;
_currentFrame._completeTimeMs = nowMS;
return completeFrame;
}

View File

@ -40,7 +40,9 @@ class OverUseDetector
public:
OverUseDetector();
~OverUseDetector();
bool Update(const WebRtcRTPHeader& rtpHeader, const WebRtc_UWord16 packetSize);
bool Update(const WebRtcRTPHeader& rtpHeader,
const WebRtc_UWord16 packetSize,
const WebRtc_Word64 nowMS);
BandwidthUsage State() const;
void Reset();
double NoiseVar() const;

View File

@ -9,7 +9,6 @@
*/
#include "remote_rate_control.h"
#include "tick_util.h"
#include "trace.h"
#include <math.h>
#include <string.h>
@ -100,14 +99,17 @@ WebRtc_Word32 RemoteRateControl::SetConfiguredBitRates(WebRtc_UWord32 minBitRate
return 0;
}
WebRtc_UWord32 RemoteRateControl::TargetBitRate(WebRtc_UWord32 RTT)
WebRtc_UWord32 RemoteRateControl::TargetBitRate(WebRtc_UWord32 RTT,
WebRtc_Word64 nowMS)
{
_currentBitRate = ChangeBitRate(_currentBitRate, _currentInput._incomingBitRate,
_currentInput._noiseVar, RTT);
_currentInput._noiseVar, RTT, nowMS);
return _currentBitRate;
}
RateControlRegion RemoteRateControl::Update(const RateControlInput& input, bool& firstOverUse)
RateControlRegion RemoteRateControl::Update(const RateControlInput& input,
bool& firstOverUse,
WebRtc_Word64 nowMS)
{
#ifdef MATLAB
// Create plots
@ -141,10 +143,10 @@ RateControlRegion RemoteRateControl::Update(const RateControlInput& input, bool&
{
if (input._incomingBitRate > 0)
{
_timeFirstIncomingEstimate = TickTime::MillisecondTimestamp();
_timeFirstIncomingEstimate = nowMS;
}
}
else if (TickTime::MillisecondTimestamp() - _timeFirstIncomingEstimate > 1000 &&
else if (nowMS - _timeFirstIncomingEstimate > 1000 &&
input._incomingBitRate > 0)
{
_currentBitRate = input._incomingBitRate;
@ -166,16 +168,18 @@ RateControlRegion RemoteRateControl::Update(const RateControlInput& input, bool&
}
WebRtc_UWord32 RemoteRateControl::ChangeBitRate(WebRtc_UWord32 currentBitRate,
WebRtc_UWord32 incomingBitRate, double noiseVar, WebRtc_UWord32 RTT)
WebRtc_UWord32 incomingBitRate,
double noiseVar,
WebRtc_UWord32 RTT,
WebRtc_Word64 nowMS)
{
const WebRtc_Word64 now = TickTime::MillisecondTimestamp();
if (!_updated)
{
return _currentBitRate;
}
_updated = false;
UpdateChangePeriod(now);
ChangeState(_currentInput, now);
UpdateChangePeriod(nowMS);
ChangeState(_currentInput, nowMS);
// calculated here because it's used in multiple places
const float incomingBitRateKbps = incomingBitRate / 1000.0f;
// Calculate the max bit rate std dev given the normalized
@ -214,7 +218,8 @@ WebRtc_UWord32 RemoteRateControl::ChangeBitRate(WebRtc_UWord32 currentBitRate,
#endif
#endif
const WebRtc_UWord32 responseTime = static_cast<WebRtc_UWord32>(_avgChangePeriod + 0.5f) + RTT + 300;
double alpha = RateIncreaseFactor(now, _lastBitRateChange, responseTime, noiseVar);
double alpha = RateIncreaseFactor(nowMS, _lastBitRateChange,
responseTime, noiseVar);
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1,
"BWE: _avgChangePeriod = %f ms; RTT = %u ms", _avgChangePeriod, RTT);
@ -245,7 +250,7 @@ WebRtc_UWord32 RemoteRateControl::ChangeBitRate(WebRtc_UWord32 currentBitRate,
//TODO
#endif
#endif
_lastBitRateChange = now;
_lastBitRateChange = nowMS;
break;
}
case kRcDecrease:
@ -285,7 +290,7 @@ WebRtc_UWord32 RemoteRateControl::ChangeBitRate(WebRtc_UWord32 currentBitRate,
}
// Stay on hold until the pipes are cleared.
ChangeState(kRcHold);
_lastBitRateChange = now;
_lastBitRateChange = nowMS;
break;
}
}
@ -295,7 +300,7 @@ WebRtc_UWord32 RemoteRateControl::ChangeBitRate(WebRtc_UWord32 currentBitRate,
// Allow changing the bit rate if we are operating at very low rates
// Don't change the bit rate if the send side is too far off
currentBitRate = _currentBitRate;
_lastBitRateChange = now;
_lastBitRateChange = nowMS;
}
#ifdef MATLAB
if (_avgMaxBitRate >= 0.0f)

View File

@ -27,13 +27,16 @@ public:
RemoteRateControl();
~RemoteRateControl();
WebRtc_Word32 SetConfiguredBitRates(WebRtc_UWord32 minBitRate, WebRtc_UWord32 maxBitRate);
WebRtc_UWord32 TargetBitRate(WebRtc_UWord32 RTT);
RateControlRegion Update(const RateControlInput& input, bool& firstOverUse);
WebRtc_UWord32 TargetBitRate(WebRtc_UWord32 RTT, WebRtc_Word64 nowMS);
RateControlRegion Update(const RateControlInput& input, bool& firstOverUse,
WebRtc_Word64 nowMS);
void Reset();
private:
WebRtc_UWord32 ChangeBitRate(WebRtc_UWord32 currentBitRate,
WebRtc_UWord32 incomingBitRate, double delayFactor, WebRtc_UWord32 RTT);
WebRtc_UWord32 incomingBitRate,
double delayFactor, WebRtc_UWord32 RTT,
WebRtc_Word64 nowMS);
double RateIncreaseFactor(WebRtc_Word64 nowMs, WebRtc_Word64 lastMs, WebRtc_UWord32 reactionTimeMs, double noiseVar) const;
void UpdateChangePeriod(WebRtc_Word64 nowMs);
void UpdateMaxBitRateEstimate(float incomingBitRateKbps);

View File

@ -68,9 +68,12 @@ class RtcpFormatRembTest : public ::testing::Test {
};
void RtcpFormatRembTest::SetUp() {
dummy_rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(0, false);
rtcp_sender_ = new RTCPSender(0, false, dummy_rtp_rtcp_impl_);
rtcp_receiver_ = new RTCPReceiver(0, dummy_rtp_rtcp_impl_);
dummy_rtp_rtcp_impl_ =
new ModuleRtpRtcpImpl(0, false, ModuleRTPUtility::GetSystemClock());
rtcp_sender_ = new RTCPSender(0, false, ModuleRTPUtility::GetSystemClock(),
dummy_rtp_rtcp_impl_);
rtcp_receiver_ = new RTCPReceiver(0, ModuleRTPUtility::GetSystemClock(),
dummy_rtp_rtcp_impl_);
test_transport_ = new TestTransport(rtcp_receiver_);
EXPECT_EQ(0, rtcp_sender_->Init());

View File

@ -27,8 +27,11 @@ namespace webrtc {
using namespace RTCPUtility;
using namespace RTCPHelp;
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, ModuleRtpRtcpImpl* owner) :
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id,
RtpRtcpClock* clock,
ModuleRtpRtcpImpl* owner) :
_id(id),
_clock(*clock),
_method(kRtcpOff),
_lastReceived(0),
_rtpRtcp(*owner),
@ -309,7 +312,7 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
{
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
_lastReceived = ModuleRTPUtility::GetTimeInMS();
_lastReceived = _clock.GetTimeInMS();
RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
while (pktType != RTCPUtility::kRtcpNotValidCode)
@ -423,7 +426,7 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
_remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
_remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
ModuleRTPUtility::CurrentNTP(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
_clock.CurrentNTP(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
}
else
{
@ -521,7 +524,7 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
WebRtc_UWord32 lastReceivedRRNTPsecs = 0;
WebRtc_UWord32 lastReceivedRRNTPfrac = 0;
ModuleRTPUtility::CurrentNTP(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
_clock.CurrentNTP(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
// time when we received this in MS
WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
@ -681,7 +684,7 @@ void
RTCPReceiver::UpdateReceiveInformation( RTCPReceiveInformation& receiveInformation)
{
// Update that this remote is alive
receiveInformation.lastTimeReceived = ModuleRTPUtility::GetTimeInMS();
receiveInformation.lastTimeReceived = _clock.GetTimeInMS();
}
bool
@ -690,7 +693,7 @@ RTCPReceiver::UpdateRTCPReceiveInformationTimers()
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
bool updateBoundingSet = false;
WebRtc_UWord32 timeNow = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 timeNow = _clock.GetTimeInMS();
MapItem* receiveInfoItem=_receivedInfoMap.First();
while(receiveInfoItem)
@ -1002,7 +1005,8 @@ RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
{
receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem);
receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
_clock.GetTimeInMS());
rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
}
}
@ -1196,7 +1200,7 @@ RTCPReceiver::HandleFIRItem(RTCPReceiveInformation& receiveInfo,
if (rtcpPacket.FIRItem.CommandSequenceNumber != receiveInfo.lastFIRSequenceNumber)
{
//
WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 now = _clock.GetTimeInMS();
// extra sanity don't go crazy with the callbacks
if( (now - receiveInfo.lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS)
@ -1478,7 +1482,8 @@ RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
}
for (WebRtc_UWord32 i = 0; (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet); i++)
{
if(receiveInfo->GetTMMBRSet(i, num, candidateSet) == 0)
if(receiveInfo->GetTMMBRSet(i, num, candidateSet,
_clock.GetTimeInMS()) == 0)
{
num++;
}
@ -1528,7 +1533,7 @@ void RTCPReceiver::PacketTimeout()
return;
}
WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 now = _clock.GetTimeInMS();
if(now - _lastReceived > _packetTimeOutMS)
{

View File

@ -24,7 +24,8 @@ class ModuleRtpRtcpImpl;
class RTCPReceiver
{
public:
RTCPReceiver(const WebRtc_Word32 id, ModuleRtpRtcpImpl* owner);
RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock,
ModuleRtpRtcpImpl* owner);
virtual ~RTCPReceiver();
void ChangeUniqueId(const WebRtc_Word32 id);
@ -181,6 +182,7 @@ protected:
private:
WebRtc_Word32 _id;
RtpRtcpClock& _clock;
RTCPMethod _method;
WebRtc_UWord32 _lastReceived;
ModuleRtpRtcpImpl& _rtpRtcp;

View File

@ -185,7 +185,8 @@ RTCPReceiveInformation::VerifyAndAllocateTMMBRSet(const WebRtc_UWord32 minimumSi
void
RTCPReceiveInformation::InsertTMMBRItem(const WebRtc_UWord32 senderSSRC,
const RTCPUtility::RTCPPacketRTPFBTMMBRItem& TMMBRItem)
const RTCPUtility::RTCPPacketRTPFBTMMBRItem& TMMBRItem,
const WebRtc_UWord32 currentTimeMS)
{
// serach to see if we have it in our list
for(WebRtc_UWord32 i = 0; i < TmmbrSet.lengthOfSet; i++)
@ -196,7 +197,7 @@ RTCPReceiveInformation::InsertTMMBRItem(const WebRtc_UWord32 senderSSRC,
// update it
TmmbrSet.ptrPacketOHSet[i] = TMMBRItem.MeasuredOverhead;
TmmbrSet.ptrTmmbrSet[i] = TMMBRItem.MaxTotalMediaBitRate;
_tmmbrSetTimeouts[i] = ModuleRTPUtility::GetTimeInMS();
_tmmbrSetTimeouts[i] = currentTimeMS;
return;
}
}
@ -206,14 +207,15 @@ RTCPReceiveInformation::InsertTMMBRItem(const WebRtc_UWord32 senderSSRC,
TmmbrSet.ptrPacketOHSet[idx] = TMMBRItem.MeasuredOverhead;
TmmbrSet.ptrTmmbrSet[idx] = TMMBRItem.MaxTotalMediaBitRate;
TmmbrSet.ptrSsrcSet[idx] = senderSSRC;
_tmmbrSetTimeouts[idx] = ModuleRTPUtility::GetTimeInMS();
_tmmbrSetTimeouts[idx] = currentTimeMS;
TmmbrSet.lengthOfSet++;
}
WebRtc_Word32
RTCPReceiveInformation::GetTMMBRSet(const WebRtc_UWord32 sourceIdx,
const WebRtc_UWord32 targetIdx,
TMMBRSet* candidateSet)
TMMBRSet* candidateSet,
const WebRtc_UWord32 currentTimeMS)
{
if(sourceIdx >= TmmbrSet.lengthOfSet)
{
@ -223,7 +225,7 @@ RTCPReceiveInformation::GetTMMBRSet(const WebRtc_UWord32 sourceIdx,
{
return -1;
}
WebRtc_UWord32 timeNow = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 timeNow = currentTimeMS;
// use audio define since we don't know what interval the remote peer is using
if(timeNow - _tmmbrSetTimeouts[sourceIdx] > 5*RTCP_INTERVAL_AUDIO_MS)

View File

@ -93,12 +93,14 @@ public:
void VerifyAndAllocateTMMBRSet(const WebRtc_UWord32 minimumSize);
void InsertTMMBRItem(const WebRtc_UWord32 senderSSRC,
const RTCPUtility::RTCPPacketRTPFBTMMBRItem& TMMBRItem);
const RTCPUtility::RTCPPacketRTPFBTMMBRItem& TMMBRItem,
const WebRtc_UWord32 currentTimeMS);
// get
WebRtc_Word32 GetTMMBRSet(const WebRtc_UWord32 sourceIdx,
const WebRtc_UWord32 targetIdx,
TMMBRSet* candidateSet);
const WebRtc_UWord32 targetIdx,
TMMBRSet* candidateSet,
const WebRtc_UWord32 currentTimeMS);
WebRtc_UWord32 lastTimeReceived;

View File

@ -16,7 +16,6 @@
#include <cstdlib> // rand
#include "trace.h"
#include "tick_util.h"
#include "common_types.h"
#include "critical_section_wrapper.h"
@ -25,9 +24,11 @@
namespace webrtc {
RTCPSender::RTCPSender(const WebRtc_Word32 id,
const bool audio,
RtpRtcpClock* clock,
ModuleRtpRtcpImpl* owner) :
_id(id),
_audio(audio),
_clock(*clock),
_method(kRtcpOff),
_rtpRtcp(*owner),
_criticalSectionTransport(*CriticalSectionWrapper::CreateCriticalSection()),
@ -187,10 +188,10 @@ RTCPSender::SetRTCPStatus(const RTCPMethod method)
{
if(_audio)
{
_nextTimeToSendRTCP = ModuleRTPUtility::GetTimeInMS() + (RTCP_INTERVAL_AUDIO_MS/2);
_nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_AUDIO_MS/2);
} else
{
_nextTimeToSendRTCP = ModuleRTPUtility::GetTimeInMS() + (RTCP_INTERVAL_VIDEO_MS/2);
_nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_VIDEO_MS/2);
}
}
_method = method;
@ -290,7 +291,8 @@ RTCPSender::SetSSRC( const WebRtc_UWord32 ssrc)
{
// not first SetSSRC, probably due to a collision
// schedule a new RTCP report
_nextTimeToSendRTCP = ModuleRTPUtility::GetTimeInMS() + 100; // make sure that we send a RTP packet
// make sure that we send a RTP packet
_nextTimeToSendRTCP = _clock.GetTimeInMS() + 100;
}
_SSRC = ssrc;
}
@ -457,7 +459,7 @@ From RFC 3550
a value of the RTCP bandwidth below the intended average
*/
WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 now = _clock.GetTimeInMS();
CriticalSectionScoped lock(_criticalSectionRTCPSender);
@ -633,7 +635,7 @@ RTCPSender::BuildSR(WebRtc_UWord8* rtcpbuffer,
if(_audio)
{
freqHz = _rtpRtcp.CurrentSendFrequencyHz();
RTPtime = ModuleRTPUtility::CurrentRTP(freqHz);
RTPtime = ModuleRTPUtility::GetCurrentRTP(&_clock, freqHz);
}
else // video
{
@ -857,7 +859,7 @@ WebRtc_Word32
RTCPSender::BuildFIR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos, const WebRtc_UWord32 RTT)
{
bool firRepeat = false;
WebRtc_UWord32 diff = ModuleRTPUtility::GetTimeInMS() - _lastTimeFIR;
WebRtc_UWord32 diff = _clock.GetTimeInMS() - _lastTimeFIR;
if(diff < RTT + 3) // 3 is processing jitter
{
// we have recently sent a FIR
@ -872,7 +874,7 @@ RTCPSender::BuildFIR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos, const WebRt
firRepeat = true;
}
}
_lastTimeFIR = ModuleRTPUtility::GetTimeInMS();
_lastTimeFIR = _clock.GetTimeInMS();
if(!firRepeat)
{
_sequenceNumberFIR++; // do not increase if repetition
@ -1103,7 +1105,8 @@ RTCPSender::BuildREMB(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos)
WebRtc_UWord32
RTCPSender::CalculateNewTargetBitrate(WebRtc_UWord32 RTT)
{
WebRtc_UWord32 target_bitrate = _remoteRateControl.TargetBitRate(RTT);
WebRtc_UWord32 target_bitrate =
_remoteRateControl.TargetBitRate(RTT, _clock.GetTimeInMS());
_tmmbr_Send = target_bitrate / 1000;
return target_bitrate;
}
@ -1608,7 +1611,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
remoteSR);
// get our NTP as late as possible to avoid a race
ModuleRTPUtility::CurrentNTP(NTPsec, NTPfrac);
_clock.CurrentNTP(NTPsec, NTPfrac);
// Delay since last received report
WebRtc_UWord32 delaySinceLastReceivedSR = 0;
@ -1630,7 +1633,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
} else
{
// we need to send our NTP even if we dont have received any reports
ModuleRTPUtility::CurrentNTP(NTPsec, NTPfrac);
_clock.CurrentNTP(NTPsec, NTPfrac);
}
}
@ -1720,7 +1723,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
}
timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000);
}
_nextTimeToSendRTCP = ModuleRTPUtility::GetTimeInMS() + timeToNext;
_nextTimeToSendRTCP = _clock.GetTimeInMS() + timeToNext;
}
// if the data does not fitt in the packet we fill it as much as possible
@ -2136,6 +2139,7 @@ RateControlRegion
RTCPSender::UpdateOverUseState(const RateControlInput& rateControlInput, bool& firstOverUse)
{
CriticalSectionScoped lock(_criticalSectionRTCPSender);
return _remoteRateControl.Update(rateControlInput, firstOverUse);
return _remoteRateControl.Update(rateControlInput, firstOverUse,
_clock.GetTimeInMS());
}
} // namespace webrtc

View File

@ -25,7 +25,8 @@ class ModuleRtpRtcpImpl;
class RTCPSender
{
public:
RTCPSender(const WebRtc_Word32 id, const bool audio, ModuleRtpRtcpImpl* owner);
RTCPSender(const WebRtc_Word32 id, const bool audio,
RtpRtcpClock* clock, ModuleRtpRtcpImpl* owner);
virtual ~RTCPSender();
void ChangeUniqueId(const WebRtc_Word32 id);
@ -172,6 +173,7 @@ private:
private:
WebRtc_Word32 _id;
const bool _audio;
RtpRtcpClock& _clock;
RTCPMethod _method;
ModuleRtpRtcpImpl& _rtpRtcp;

View File

@ -23,9 +23,11 @@
namespace webrtc {
RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
const bool audio,
RtpRtcpClock* clock,
ModuleRtpRtcpImpl* owner) :
RTPReceiverAudio(id),
RTPReceiverVideo(id, owner),
Bitrate(clock),
_id(id),
_audio(audio),
_rtpRtcp(*owner),
@ -251,7 +253,7 @@ void RTPReceiver::PacketTimeout()
return;
}
WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 now = _clock.GetTimeInMS();
if(now - _lastReceiveTime > _packetTimeOutMS)
{
@ -822,7 +824,8 @@ RTPReceiver::IncomingRTPPacket(WebRtcRTPHeader* rtpHeader,
videoSpecific.videoCodecType,
isRED,
incomingRtpPacket,
incomingRtpPacketLength);
incomingRtpPacketLength,
_clock.GetTimeInMS());
}
if(retVal != -1)
{
@ -836,7 +839,9 @@ RTPReceiver::IncomingRTPPacket(WebRtcRTPHeader* rtpHeader,
// this updates _receivedSeqMax and other members
UpdateStatistics(rtpHeader, payloadDataLength, oldPacket);
_lastReceiveTime = ModuleRTPUtility::GetTimeInMS(); // need to be updated after RetransmitOfOldPacket & RetransmitOfOldPacketUpdateStatistics
// need to be updated after RetransmitOfOldPacket &
// RetransmitOfOldPacketUpdateStatistics
_lastReceiveTime = _clock.GetTimeInMS();
_lastReceivedPayloadLength = payloadDataLength;
if(retVal >= 0 && !oldPacket)
@ -887,14 +892,16 @@ RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtpHeader,
_receivedSeqFirst = rtpHeader->header.sequenceNumber;
_receivedSeqMax = rtpHeader->header.sequenceNumber;
_receivedInorderPacketCount = 1;
_localTimeLastReceivedTimestamp = ModuleRTPUtility::CurrentRTP(freq); //time in samples
_localTimeLastReceivedTimestamp =
ModuleRTPUtility::GetCurrentRTP(&_clock, freq); //time in samples
return;
}
// count only the new packets received
if(InOrderPacket(rtpHeader->header.sequenceNumber))
{
const WebRtc_UWord32 RTPtime = ModuleRTPUtility::CurrentRTP(freq); //time in samples
const WebRtc_UWord32 RTPtime =
ModuleRTPUtility::GetCurrentRTP(&_clock, freq); //time in samples
_receivedInorderPacketCount++;
// wrong if we use RetransmitOfOldPacket
@ -953,7 +960,8 @@ RTPReceiver::RetransmitOfOldPacket(const WebRtc_UWord16 sequenceNumber,
{
return false;
}
WebRtc_UWord32 timeDiffMS = ModuleRTPUtility::GetTimeInMS() - _lastReceiveTime; // last time we received a packet
// last time we received a packet
WebRtc_UWord32 timeDiffMS = _clock.GetTimeInMS() - _lastReceiveTime;
WebRtc_Word32 rtpTimeStampDiffMS = ((WebRtc_Word32)(rtpTimeStamp - _lastReceivedTimestamp))/90; // diff in time stamp since last received in order
WebRtc_UWord16 minRTT = 0;
@ -1058,7 +1066,8 @@ RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const
return -1;
}
//time in samples
WebRtc_UWord32 diff = ModuleRTPUtility::CurrentRTP(freq) - _localTimeLastReceivedTimestamp;
WebRtc_UWord32 diff = ModuleRTPUtility::GetCurrentRTP(&_clock, freq)
- _localTimeLastReceivedTimestamp;
timestamp = _lastReceivedTimestamp + diff;
return 0;

View File

@ -30,6 +30,7 @@ class RTPReceiver : public RTPReceiverAudio, public RTPReceiverVideo, public Bit
public:
RTPReceiver(const WebRtc_Word32 id,
const bool audio,
RtpRtcpClock* clock,
ModuleRtpRtcpImpl* owner);
virtual ~RTPReceiver();

View File

@ -15,7 +15,6 @@
#include <math.h>
#include "critical_section_wrapper.h"
#include "tick_util.h"
#include "receiver_fec.h"
#include "rtp_rtcp_impl.h"
@ -224,19 +223,20 @@ RTPReceiverVideo::ParseVideoCodecSpecific(WebRtcRTPHeader* rtpHeader,
const RtpVideoCodecTypes videoType,
const bool isRED,
const WebRtc_UWord8* incomingRtpPacket,
const WebRtc_UWord16 incomingRtpPacketSize)
const WebRtc_UWord16 incomingRtpPacketSize,
const WebRtc_Word64 nowMS)
{
WebRtc_Word32 retVal = 0;
_criticalSectionReceiverVideo.Enter();
_videoBitRate.Update(payloadDataLength, TickTime::MillisecondTimestamp());
_videoBitRate.Update(payloadDataLength, nowMS);
// Add headers, ideally we would like to include for instance
// Ethernet header here as well.
const WebRtc_UWord16 packetSize = payloadDataLength + _packetOverHead +
rtpHeader->header.headerLength + rtpHeader->header.paddingLength;
_overUseDetector.Update(*rtpHeader, packetSize);
_overUseDetector.Update(*rtpHeader, packetSize, nowMS);
if (isRED)
{
@ -298,8 +298,7 @@ RTPReceiverVideo::ParseVideoCodecSpecific(WebRtcRTPHeader* rtpHeader,
// detector with the current rate control region.
_criticalSectionReceiverVideo.Enter();
const RateControlInput input(_overUseDetector.State(),
_videoBitRate.BitRate(
TickTime::MillisecondTimestamp()),
_videoBitRate.BitRate(nowMS),
_overUseDetector.NoiseVar());
_criticalSectionReceiverVideo.Leave();

View File

@ -57,7 +57,8 @@ public:
const RtpVideoCodecTypes videoType,
const bool isRED,
const WebRtc_UWord8* incomingRtpPacket,
const WebRtc_UWord16 incomingRtpPacketSize);
const WebRtc_UWord16 incomingRtpPacketSize,
const WebRtc_Word64 nowMS);
WebRtc_Word32 SetH263InverseLogic(const bool enable);

View File

@ -37,6 +37,14 @@ using namespace RTCPUtility;
RtpRtcp*
RtpRtcp::CreateRtpRtcp(const WebRtc_Word32 id,
const bool audio)
{
return CreateRtpRtcp(id, audio, ModuleRTPUtility::GetSystemClock());
}
RtpRtcp*
RtpRtcp::CreateRtpRtcp(const WebRtc_Word32 id,
const bool audio,
RtpRtcpClock* clock)
{
if(audio)
{
@ -51,7 +59,7 @@ RtpRtcp::CreateRtpRtcp(const WebRtc_Word32 id,
id,
"CreateRtpRtcp(video)");
}
return new ModuleRtpRtcpImpl(id, audio);
return new ModuleRtpRtcpImpl(id, audio, clock);
}
void RtpRtcp::DestroyRtpRtcp(RtpRtcp* module)
@ -67,16 +75,18 @@ void RtpRtcp::DestroyRtpRtcp(RtpRtcp* module)
}
ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const WebRtc_Word32 id,
const bool audio):
const bool audio,
RtpRtcpClock* clock):
TMMBRHelp(audio),
_rtpSender(id, audio),
_rtpReceiver(id, audio, this),
_rtcpSender(id, audio, this),
_rtcpReceiver(id, this),
_rtpSender(id, audio, clock),
_rtpReceiver(id, audio, clock, this),
_rtcpSender(id, audio, clock, this),
_rtcpReceiver(id, clock, this),
_clock(*clock),
_id(id),
_audio(audio),
_collisionDetected(false),
_lastProcessTime(ModuleRTPUtility::GetTimeInMS()),
_lastProcessTime(clock->GetTimeInMS()),
_packetOverHead(28), // IPV4 UDP
_criticalSectionModulePtrs(*CriticalSectionWrapper::CreateCriticalSection()),
@ -419,7 +429,7 @@ void ModuleRtpRtcpImpl::DeRegisterVideoModule()
// to call Process
WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess()
{
const WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
const WebRtc_UWord32 now = _clock.GetTimeInMS();
return kRtpRtcpMaxIdleTimeProcess - (now -_lastProcessTime);
}
@ -427,7 +437,7 @@ WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess()
// non time critical events
WebRtc_Word32 ModuleRtpRtcpImpl::Process()
{
_lastProcessTime = ModuleRTPUtility::GetTimeInMS();
_lastProcessTime = _clock.GetTimeInMS();
_rtpReceiver.PacketTimeout();
_rtcpReceiver.PacketTimeout();
@ -491,7 +501,7 @@ void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer()
{
if(_deadOrAliveActive)
{
const WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
const WebRtc_UWord32 now = _clock.GetTimeInMS();
if(now > _deadOrAliveTimeoutMS +_deadOrAliveLastTimer)
{
// RTCP is alive if we have received a report the last 12 seconds
@ -532,7 +542,7 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetPeriodicDeadOrAliveStatus(
_deadOrAliveActive = enable;
_deadOrAliveTimeoutMS = sampleTimeSeconds*1000;
// trigger the first after one period
_deadOrAliveLastTimer = ModuleRTPUtility::GetTimeInMS();
_deadOrAliveLastTimer = _clock.GetTimeInMS();
return 0;
}
@ -1703,7 +1713,7 @@ ModuleRtpRtcpImpl::ReportBlockStatistics(WebRtc_UWord8 *fraction_lost,
if (_plot1 == NULL)
{
_plot1 = eng.NewPlot(new MatlabPlot());
_plot1->AddTimeLine(30, "b", "lost", TickTime::MillisecondTimestamp());
_plot1->AddTimeLine(30, "b", "lost", _clock.GetTimeInMS());
}
_plot1->Append("lost", missing);
_plot1->Plot();
@ -1909,7 +1919,7 @@ ModuleRtpRtcpImpl::SendNACK(const WebRtc_UWord16* nackList,
{
waitTime = 100; //During startup we don't have an RTT
}
const WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
const WebRtc_UWord32 now = _clock.GetTimeInMS();
const WebRtc_UWord32 timeLimit = now - waitTime;
if(_nackLastTimeSent < timeLimit)
@ -2690,7 +2700,8 @@ void ModuleRtpRtcpImpl::OnPacketLossStatisticsUpdate(
videoRate + fecRate + nackRate,
roundTripTime,
&loss,
&newBitrate) != 0) {
&newBitrate,
_clock.GetTimeInMS()) != 0) {
// ignore this update
return;
}
@ -2738,7 +2749,8 @@ void ModuleRtpRtcpImpl::OnPacketLossStatisticsUpdate(
videoRate + fecRate + nackRate,
roundTripTime,
&loss,
&newBitrate) != 0) {
&newBitrate,
_clock.GetTimeInMS()) != 0) {
// ignore this update
return;
}

View File

@ -30,7 +30,8 @@ class ModuleRtpRtcpImpl : public RtpRtcp, private TMMBRHelp
{
public:
ModuleRtpRtcpImpl(const WebRtc_Word32 id,
const bool audio);
const bool audio,
RtpRtcpClock* clock);
virtual ~ModuleRtpRtcpImpl();
@ -531,6 +532,8 @@ protected:
RTCPSender _rtcpSender;
RTCPReceiver _rtcpReceiver;
RtpRtcpClock& _clock;
private:
void SendKeyFrame();
void ProcessDefaultModuleBandwidth(bool triggerOnNetworkChanged);

View File

@ -14,13 +14,15 @@
#include "critical_section_wrapper.h"
#include "trace.h"
#include "tick_util.h"
#include "rtp_sender_audio.h"
#include "rtp_sender_video.h"
namespace webrtc {
RTPSender::RTPSender(const WebRtc_Word32 id, const bool audio) :
RTPSender::RTPSender(const WebRtc_Word32 id,
const bool audio,
RtpRtcpClock* clock) :
Bitrate(clock),
_id(id),
_audioConfigured(audio),
_audio(NULL),
@ -56,7 +58,7 @@ RTPSender::RTPSender(const WebRtc_Word32 id, const bool audio) :
// NACK
_nackByteCountTimes(),
_nackByteCount(),
_nackBitrate(),
_nackBitrate(clock),
// statistics
_packetsSent(0),
@ -82,16 +84,16 @@ RTPSender::RTPSender(const WebRtc_Word32 id, const bool audio) :
memset(_CSRC, 0, sizeof(_CSRC));
// we need to seed the random generator, otherwise we get 26500 each time, hardly a random value :)
srand( (WebRtc_UWord32)ModuleRTPUtility::GetTimeInMS() );
srand( (WebRtc_UWord32)_clock.GetTimeInMS() );
_ssrc = _ssrcDB.CreateSSRC(); // can't be 0
if(audio)
{
_audio = new RTPSenderAudio(id, this);
_audio = new RTPSenderAudio(id, &_clock, this);
} else
{
_video = new RTPSenderVideo(id, this); //
_video = new RTPSenderVideo(id, &_clock, this);
}
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
}
@ -403,7 +405,7 @@ RTPSender::EnableRTPKeepalive( const WebRtc_Word8 unknownPayloadType,
_keepAliveIsActive = true;
_keepAlivePayloadType = unknownPayloadType;
_keepAliveLastSent = ModuleRTPUtility::GetTimeInMS();
_keepAliveLastSent = _clock.GetTimeInMS();
_keepAliveDeltaTimeSend = deltaTransmitTimeMS;
return 0;
}
@ -422,7 +424,7 @@ RTPSender::TimeToSendRTPKeepalive() const
bool timeToSend(false);
WebRtc_UWord32 dT = ModuleRTPUtility::GetTimeInMS() - _keepAliveLastSent;
WebRtc_UWord32 dT = _clock.GetTimeInMS() - _keepAliveLastSent;
if (dT > _keepAliveDeltaTimeSend)
{
timeToSend = true;
@ -491,7 +493,7 @@ RTPSender::SendRTPKeepalivePacket()
{
CriticalSectionScoped cs(_sendCritsect);
WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 now = _clock.GetTimeInMS();
WebRtc_UWord32 dT = now -_keepAliveLastSent; // delta time in MS
WebRtc_UWord32 freqKHz = 90; // video
@ -636,7 +638,7 @@ RTPSender::CheckPayloadType(const WebRtc_Word8 payloadType,
// We need to correct the timestamp again,
// since this might happen after we've set it
WebRtc_UWord32 RTPtime =
ModuleRTPUtility::CurrentRTP(payloadFreqHz);
ModuleRTPUtility::GetCurrentRTP(&_clock, payloadFreqHz);
SetStartTimestamp(RTPtime);
// will be ignored if it's already configured via API
}
@ -686,7 +688,7 @@ RTPSender::SendOutgoingData(const FrameType frameType,
return -1;
}
// update keepalive so that we don't trigger keepalive messages while sending data
_keepAliveLastSent = ModuleRTPUtility::GetTimeInMS();
_keepAliveLastSent = _clock.GetTimeInMS();
if(_audioConfigured)
{
@ -830,7 +832,7 @@ RTPSender::ReSendToNetwork(WebRtc_UWord16 packetID,
}
if(seqNum == packetID)
{
WebRtc_UWord32 timeNow= ModuleRTPUtility::GetTimeInMS();
WebRtc_UWord32 timeNow= _clock.GetTimeInMS();
if(minResendTime>0 && (timeNow-_prevSentPacketsResendTime[index]<minResendTime))
{
// No point in sending the packet again yet. Get out of here
@ -889,7 +891,8 @@ RTPSender::ReSendToNetwork(WebRtc_UWord16 packetID,
if(_prevSentPacketsSeqNum[index] == packetID) // Make sure the packet is still in the array
{
_prevSentPacketsResendTime[index]= ModuleRTPUtility::GetTimeInMS(); // Store the time when the frame was last resent.
// Store the time when the frame was last resent.
_prevSentPacketsResendTime[index]= _clock.GetTimeInMS();
}
return i; //bytes sent over network
}
@ -903,7 +906,7 @@ RTPSender::OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength,
const WebRtc_UWord16* nackSequenceNumbers,
const WebRtc_UWord16 avgRTT)
{
const WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS();
const WebRtc_UWord32 now = _clock.GetTimeInMS();
WebRtc_UWord32 bytesReSent = 0;
// Enough bandwith to send NACK?
@ -1245,7 +1248,7 @@ RTPSender::SetSendingStatus(const bool enabled)
{
freq = 90000; // 90 KHz for all video
}
WebRtc_UWord32 RTPtime = ModuleRTPUtility::CurrentRTP(freq);
WebRtc_UWord32 RTPtime = ModuleRTPUtility::GetCurrentRTP(&_clock, freq);
SetStartTimestamp(RTPtime); // will be ignored if it's already configured via API

View File

@ -63,7 +63,7 @@ public:
class RTPSender : public Bitrate, public RTPSenderInterface
{
public:
RTPSender(const WebRtc_Word32 id, const bool audio);
RTPSender(const WebRtc_Word32 id, const bool audio, RtpRtcpClock* clock);
virtual ~RTPSender();
WebRtc_Word32 Init(const WebRtc_UWord32 remoteSSRC);

View File

@ -14,8 +14,10 @@
#include <cassert> //assert
namespace webrtc {
RTPSenderAudio::RTPSenderAudio(const WebRtc_Word32 id, RTPSenderInterface* rtpSender) :
RTPSenderAudio::RTPSenderAudio(const WebRtc_Word32 id, RtpRtcpClock* clock,
RTPSenderInterface* rtpSender) :
_id(id),
_clock(*clock),
_rtpSender(rtpSender),
_audioFeedbackCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
_audioFeedback(NULL),
@ -237,7 +239,7 @@ RTPSenderAudio::SendTelephoneEventActive(WebRtc_Word8& telephoneEvent) const
telephoneEvent = _dtmfKey;
return true;
}
WebRtc_UWord32 delaySinceLastDTMF = (ModuleRTPUtility::GetTimeInMS() - _dtmfTimeLastSent);
WebRtc_UWord32 delaySinceLastDTMF = (_clock.GetTimeInMS() - _dtmfTimeLastSent);
if(delaySinceLastDTMF < 100)
{
telephoneEvent = _dtmfKey;
@ -266,7 +268,7 @@ RTPSenderAudio::SendAudio(const FrameType frameType,
{
CriticalSectionScoped cs(_sendAudioCritsect);
WebRtc_UWord32 delaySinceLastDTMF = (ModuleRTPUtility::GetTimeInMS() - _dtmfTimeLastSent);
WebRtc_UWord32 delaySinceLastDTMF = (_clock.GetTimeInMS() - _dtmfTimeLastSent);
if(delaySinceLastDTMF > 100)
{
@ -328,7 +330,7 @@ RTPSenderAudio::SendAudio(const FrameType frameType,
{
ended = true;
_dtmfEventIsOn = false;
_dtmfTimeLastSent = ModuleRTPUtility::GetTimeInMS();
_dtmfTimeLastSent = _clock.GetTimeInMS();
}
// don't hold the critsect while calling SendTelephoneEventPacket
_sendAudioCritsect.Leave();

View File

@ -25,7 +25,8 @@ namespace webrtc {
class RTPSenderAudio: public DTMFqueue
{
public:
RTPSenderAudio(const WebRtc_Word32 id, RTPSenderInterface* rtpSender);
RTPSenderAudio(const WebRtc_Word32 id, RtpRtcpClock* clock,
RTPSenderInterface* rtpSender);
virtual ~RTPSenderAudio();
void ChangeUniqueId(const WebRtc_Word32 id);
@ -92,6 +93,7 @@ protected:
private:
WebRtc_Word32 _id;
RtpRtcpClock& _clock;
RTPSenderInterface* _rtpSender;
CriticalSectionWrapper& _audioFeedbackCritsect;
RtpAudioFeedback* _audioFeedback;

View File

@ -26,6 +26,7 @@ namespace webrtc {
enum { REDForFECHeaderLength = 1 };
RTPSenderVideo::RTPSenderVideo(const WebRtc_Word32 id,
RtpRtcpClock* clock,
RTPSenderInterface* rtpSender) :
_id(id),
_rtpSender(*rtpSender),
@ -47,7 +48,8 @@ RTPSenderVideo::RTPSenderVideo(const WebRtc_Word32 id,
_fecProtectionFactor(0),
_fecUseUepProtection(false),
_numberFirstPartition(0),
_fecOverheadRate(),
_fecOverheadRate(clock),
_videoBitrate(clock),
// H263
_savedByte(0),

View File

@ -31,7 +31,8 @@ class CriticalSectionWrapper;
class RTPSenderVideo
{
public:
RTPSenderVideo(const WebRtc_Word32 id, RTPSenderInterface* rtpSender);
RTPSenderVideo(const WebRtc_Word32 id, RtpRtcpClock* clock,
RTPSenderInterface* rtpSender);
virtual ~RTPSenderVideo();
WebRtc_Word32 Init();

View File

@ -38,28 +38,15 @@
#define DEBUG_PRINT(exp) ((void)0)
#endif // defined(_DEBUG) && defined(_WIN32)
namespace
{
const float FRAC = 4.294967296E9;
}
namespace webrtc {
// PLATFORM SPECIFIC [BEGIN]
/*
* Time routines.
*/
#if defined(_WIN32)
#include <Windows.h>
namespace ModuleRTPUtility
{
WebRtc_UWord32 GetTimeInMS()
{
return timeGetTime();
}
bool StringCompare(const WebRtc_Word8* str1 , const WebRtc_Word8* str2, const WebRtc_UWord32 length)
{
return (_strnicmp(str1, str2, length) == 0)?true: false;
}
class HelpTimer
namespace ModuleRTPUtility {
class WindowsHelpTimer
{
public:
struct reference_point
@ -68,7 +55,7 @@ namespace webrtc {
LARGE_INTEGER counterMS;
};
HelpTimer()
WindowsHelpTimer()
{
// set timer accuracy to 1 ms
timeBeginPeriod(1);
@ -78,7 +65,7 @@ namespace webrtc {
synchronize();
};
virtual ~HelpTimer()
virtual ~WindowsHelpTimer()
{
timeEndPeriod(1);
};
@ -143,30 +130,186 @@ namespace webrtc {
reference_point _ref_point;
};
static HelpTimer helpTimer;
// A clock reading times from the Windows API.
class WindowsSystemClock : public RtpRtcpClock {
public:
WindowsSystemClock()
: _helpTimer() {}
}; // end namespace
virtual ~WindowsSystemClock() {}
virtual WebRtc_UWord32 GetTimeInMS();
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac);
private:
WindowsHelpTimer _helpTimer;
};
}; // namespace ModuleRTPUtility
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
#include <sys/time.h> // gettimeofday
#include <time.h> // nanosleep, gettimeofday
WebRtc_UWord32
ModuleRTPUtility::GetTimeInMS()
{
struct timeval tv;
struct timezone tz;
WebRtc_UWord32 val;
namespace ModuleRTPUtility {
// A clock reading times from the POSIX API.
class UnixSystemClock : public RtpRtcpClock {
public:
UnixSystemClock() {}
virtual ~UnixSystemClock() {}
gettimeofday(&tv, &tz);
val = (WebRtc_UWord32)(tv.tv_sec*1000 + tv.tv_usec/1000);
return val;
}
bool ModuleRTPUtility::StringCompare(const WebRtc_Word8* str1 , const WebRtc_Word8* str2, const WebRtc_UWord32 length)
virtual WebRtc_UWord32 GetTimeInMS();
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac);
};
}; // namespace ModuleRTPUtility
#endif
namespace ModuleRTPUtility {
#if defined(_WIN32)
WebRtc_UWord32 WindowsSystemClock::GetTimeInMS()
{
return timeGetTime();
}
// Use the system time (roughly synchronised to the tick, and
// extrapolated using the system performance counter.
void WindowsSystemClock::CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac)
{
const WebRtc_UWord64 FILETIME_1970 = 0x019db1ded53e8000;
FILETIME StartTime;
WebRtc_UWord64 Time;
struct timeval tv;
// we can't use query performance counter since they can change depending on speed steping
_helpTimer.get_time(StartTime);
Time = (((WebRtc_UWord64) StartTime.dwHighDateTime) << 32) +
(WebRtc_UWord64) StartTime.dwLowDateTime;
// Convert the hecto-nano second time to tv format
Time -= FILETIME_1970;
tv.tv_sec = (WebRtc_UWord32) ( Time / (WebRtc_UWord64)10000000);
tv.tv_usec = (WebRtc_UWord32) (( Time % (WebRtc_UWord64)10000000) / 10);
double dtemp;
secs = tv.tv_sec + NTP_JAN_1970;
dtemp = tv.tv_usec / 1e6;
if (dtemp >= 1)
{
return (strncasecmp(str1, str2, length) == 0)?true: false;
dtemp -= 1;
secs++;
} else if (dtemp < -1)
{
dtemp += 1;
secs--;
}
#endif // PLATFORM SPECIFIC [END]
dtemp *= NTP_FRAC;
frac = (WebRtc_UWord32)dtemp;
}
#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))
WebRtc_UWord32 UnixSystemClock::GetTimeInMS()
{
struct timeval tv;
struct timezone tz;
WebRtc_UWord32 val;
gettimeofday(&tv, &tz);
val = (WebRtc_UWord32)(tv.tv_sec*1000 + tv.tv_usec/1000);
return val;
}
// Use the system time.
void UnixSystemClock::CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac)
{
double dtemp;
struct timeval tv;
struct timezone tz;
tz.tz_minuteswest = 0;
tz.tz_dsttime = 0;
gettimeofday(&tv,&tz);
secs = tv.tv_sec + NTP_JAN_1970;
dtemp = tv.tv_usec / 1e6;
if (dtemp >= 1)
{
dtemp -= 1;
secs++;
} else if (dtemp < -1)
{
dtemp += 1;
secs--;
}
dtemp *= NTP_FRAC;
frac = (WebRtc_UWord32)dtemp;
}
#endif
#if defined(_WIN32)
static WindowsSystemClock system_clock;
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
static UnixSystemClock system_clock;
#endif
RtpRtcpClock* GetSystemClock()
{
return &system_clock;
}
WebRtc_UWord32 GetCurrentRTP(RtpRtcpClock* clock, WebRtc_UWord32 freq)
{
if (clock == NULL)
clock = GetSystemClock();
WebRtc_UWord32 secs = 0, frac = 0;
clock->CurrentNTP(secs, frac);
return ConvertNTPTimeToRTP(secs, frac, freq);
}
WebRtc_UWord32 ConvertNTPTimeToRTP(WebRtc_UWord32 NTPsec,
WebRtc_UWord32 NTPfrac,
WebRtc_UWord32 freq)
{
float ftemp = (float)NTPfrac/(float)NTP_FRAC;
WebRtc_UWord32 tmp = (WebRtc_UWord32)(ftemp * freq);
return NTPsec*freq + tmp;
}
WebRtc_UWord32 ConvertNTPTimeToMS(WebRtc_UWord32 NTPsec,
WebRtc_UWord32 NTPfrac)
{
int freq = 1000;
float ftemp = (float)NTPfrac/(float)NTP_FRAC;
WebRtc_UWord32 tmp = (WebRtc_UWord32)(ftemp * freq);
WebRtc_UWord32 MStime= NTPsec*freq + tmp;
return MStime;
}
} // namespace ModuleRTPUtility
/*
* Misc utility routines
*/
#if defined(_WIN32)
bool ModuleRTPUtility::StringCompare(const WebRtc_Word8* str1,
const WebRtc_Word8* str2,
const WebRtc_UWord32 length)
{
return (_strnicmp(str1, str2, length) == 0)?true: false;
}
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
bool ModuleRTPUtility::StringCompare(const WebRtc_Word8* str1,
const WebRtc_Word8* str2,
const WebRtc_UWord32 length)
{
return (strncasecmp(str1, str2, length) == 0)?true: false;
}
#endif
#if !defined(WEBRTC_LITTLE_ENDIAN) && !defined(WEBRTC_BIG_ENDIAN)
#error Either WEBRTC_LITTLE_ENDIAN or WEBRTC_BIG_ENDIAN must be defined
@ -249,101 +392,6 @@ ModuleRTPUtility::pow2(WebRtc_UWord8 exp)
return 1 << exp;
}
WebRtc_Word32
ModuleRTPUtility::CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac)
{
/*
* Use the system time (roughly synchronised to the tick, and
* extrapolated using the system performance counter.
*/
const WebRtc_UWord32 JAN_1970 = 2208988800UL; // NTP seconds
#if defined(_WIN32)
const WebRtc_UWord64 FILETIME_1970 = 0x019db1ded53e8000;
FILETIME StartTime;
WebRtc_UWord64 Time;
struct timeval tv;
// we can't use query performance counter since they can change depending on speed steping
helpTimer.get_time(StartTime);
Time = (((WebRtc_UWord64) StartTime.dwHighDateTime) << 32) +
(WebRtc_UWord64) StartTime.dwLowDateTime;
// Convert the hecto-nano second time to tv format
Time -= FILETIME_1970;
tv.tv_sec = (WebRtc_UWord32) ( Time / (WebRtc_UWord64)10000000);
tv.tv_usec = (WebRtc_UWord32) (( Time % (WebRtc_UWord64)10000000) / 10);
double dtemp;
secs = tv.tv_sec + JAN_1970;
dtemp = tv.tv_usec / 1e6;
if (dtemp >= 1)
{
dtemp -= 1;
secs++;
} else if (dtemp < -1)
{
dtemp += 1;
secs--;
}
dtemp *= FRAC;
frac = (WebRtc_UWord32)dtemp;
return 0;
#endif
#if ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))
double dtemp;
struct timeval tv;
struct timezone tz;
tz.tz_minuteswest = 0;
tz.tz_dsttime = 0;
gettimeofday(&tv,&tz);
secs = tv.tv_sec + JAN_1970;
dtemp = tv.tv_usec / 1e6;
if (dtemp >= 1)
{
dtemp -= 1;
secs++;
} else if (dtemp < -1)
{
dtemp += 1;
secs--;
}
dtemp *= FRAC;
frac = (WebRtc_UWord32)dtemp;
return(0);
#endif
}
WebRtc_UWord32
ModuleRTPUtility::ConvertNTPTimeToMS(WebRtc_UWord32 NTPsec, WebRtc_UWord32 NTPfrac)
{
int freq = 1000;
float ftemp = (float)NTPfrac/(float)FRAC;
WebRtc_UWord32 tmp = (WebRtc_UWord32)(ftemp * freq);
WebRtc_UWord32 MStime= NTPsec*freq + tmp;
return MStime;
}
WebRtc_UWord32
ModuleRTPUtility::CurrentRTP(WebRtc_UWord32 freq)
{
WebRtc_UWord32 NTPsec = 0;
WebRtc_UWord32 NTPfrac = 0;
CurrentNTP( NTPsec, NTPfrac);
float ftemp = (float)NTPfrac/(float)FRAC;
WebRtc_UWord32 tmp = (WebRtc_UWord32)(ftemp * freq);
return NTPsec*freq + tmp;
}
void
ModuleRTPUtility::RTPPayload::SetType(RtpVideoCodecTypes videoType)
{

View File

@ -32,6 +32,12 @@ const WebRtc_UWord8 kRtpMarkerBitMask = 0x80;
namespace ModuleRTPUtility
{
// January 1970, in NTP seconds.
const uint32_t NTP_JAN_1970 = 2208988800UL;
// Magic NTP fractional unit.
const double NTP_FRAC = 4.294967296E+9;
struct AudioPayload
{
WebRtc_UWord32 frequency;
@ -56,16 +62,28 @@ namespace ModuleRTPUtility
PayloadUnion typeSpecific;
};
WebRtc_Word32 CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac) ;
// Return a clock that reads the time as reported by the operating
// system. The returned instances are guaranteed to read the same
// times; in particular, they return relative times relative to
// the same base.
RtpRtcpClock* GetSystemClock();
WebRtc_UWord32 CurrentRTP(WebRtc_UWord32 freq);
// Return the current RTP timestamp from the NTP timestamp
// returned by the specified clock.
WebRtc_UWord32 GetCurrentRTP(RtpRtcpClock* clock, WebRtc_UWord32 freq);
// Return the current RTP absolute timestamp.
WebRtc_UWord32 ConvertNTPTimeToRTP(WebRtc_UWord32 NTPsec,
WebRtc_UWord32 NTPfrac,
WebRtc_UWord32 freq);
// Return the time in milliseconds corresponding to the specified
// NTP timestamp.
WebRtc_UWord32 ConvertNTPTimeToMS(WebRtc_UWord32 NTPsec,
WebRtc_UWord32 NTPfrac);
WebRtc_UWord32 pow2(WebRtc_UWord8 exp);
WebRtc_UWord32 GetTimeInMS();
WebRtc_UWord32 ConvertNTPTimeToMS(WebRtc_UWord32 NTPsec, WebRtc_UWord32 NTPfrac);
bool StringCompare(const WebRtc_Word8* str1 , const WebRtc_Word8* str2, const WebRtc_UWord32 length);
void AssignUWord32ToBuffer(WebRtc_UWord8* dataBuffer, WebRtc_UWord32 value);