Break out RtpClock to system_wrappers and make it more generic.

The goal with this new clock interface is to have something which is used all
over WebRTC to make it easier to switch clock implementation depending on where
the components are used. This is a first step in that direction.

Next steps will be to, step by step, move all modules, video engine and voice
engine over to the new interface, effectively deprecating the old clock
interfaces. Long-term my vision is that we should be able to deprecate the clock
of WebRTC and rely on the user providing the implementation.

TEST=vie_auto_test, rtp_rtcp_unittests, trybots

Review URL: https://webrtc-codereview.appspot.com/1041004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3381 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2013-01-17 14:01:20 +00:00
parent 3b7feb2a5d
commit 20ed36dada
31 changed files with 468 additions and 379 deletions

View File

@ -55,7 +55,7 @@ class RtpRtcp : public Module {
*/ */
int32_t id; int32_t id;
bool audio; bool audio;
RtpRtcpClock* clock; Clock* clock;
RtpRtcp* default_module; RtpRtcp* default_module;
RtpData* incoming_data; RtpData* incoming_data;
RtpFeedback* incoming_messages; RtpFeedback* incoming_messages;

View File

@ -13,6 +13,7 @@
#include "typedefs.h" #include "typedefs.h"
#include "module_common_types.h" #include "module_common_types.h"
#include "webrtc/system_wrappers/interface/clock.h"
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
@ -255,20 +256,6 @@ class RtcpRttObserver {
virtual ~RtcpRttObserver() {}; virtual ~RtcpRttObserver() {};
}; };
// A clock interface that allows reading of absolute and relative
// timestamps in an RTP/RTCP module.
class RtpRtcpClock {
public:
virtual ~RtpRtcpClock() {}
// Return a timestamp in milliseconds relative to some arbitrary
// source; the source is fixed for this clock.
virtual WebRtc_Word64 GetTimeInMS() = 0;
// Retrieve an NTP absolute timestamp.
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac) = 0;
};
// Null object version of RtpFeedback. // Null object version of RtpFeedback.
class NullRtpFeedback : public RtpFeedback { class NullRtpFeedback : public RtpFeedback {
public: public:

View File

@ -14,7 +14,7 @@
namespace webrtc { namespace webrtc {
Bitrate::Bitrate(RtpRtcpClock* clock) Bitrate::Bitrate(Clock* clock)
: clock_(*clock), : clock_(*clock),
packet_rate_(0), packet_rate_(0),
bitrate_(0), bitrate_(0),
@ -41,7 +41,7 @@ WebRtc_UWord32 Bitrate::BitrateLast() const {
} }
WebRtc_UWord32 Bitrate::BitrateNow() const { WebRtc_UWord32 Bitrate::BitrateNow() const {
WebRtc_Word64 now = clock_.GetTimeInMS(); WebRtc_Word64 now = clock_.TimeInMilliseconds();
WebRtc_Word64 diff_ms = now - time_last_rate_update_; WebRtc_Word64 diff_ms = now - time_last_rate_update_;
if (diff_ms > 10000) { // 10 seconds. if (diff_ms > 10000) { // 10 seconds.
@ -59,7 +59,7 @@ WebRtc_UWord32 Bitrate::BitrateNow() const {
void Bitrate::Process() { void Bitrate::Process() {
// Triggered by timer. // Triggered by timer.
WebRtc_Word64 now = clock_.GetTimeInMS(); WebRtc_Word64 now = clock_.TimeInMilliseconds();
WebRtc_Word64 diff_ms = now - time_last_rate_update_; WebRtc_Word64 diff_ms = now - time_last_rate_update_;
if (diff_ms < 100) { if (diff_ms < 100) {

View File

@ -20,11 +20,11 @@
namespace webrtc { namespace webrtc {
class RtpRtcpClock; class Clock;
class Bitrate { class Bitrate {
public: public:
explicit Bitrate(RtpRtcpClock* clock); explicit Bitrate(Clock* clock);
// Calculates rates. // Calculates rates.
void Process(); void Process();
@ -42,7 +42,7 @@ class Bitrate {
WebRtc_UWord32 BitrateNow() const; WebRtc_UWord32 BitrateNow() const;
protected: protected:
RtpRtcpClock& clock_; Clock& clock_;
private: private:
WebRtc_UWord32 packet_rate_; WebRtc_UWord32 packet_rate_;

View File

@ -69,7 +69,7 @@ class RtcpFormatRembTest : public ::testing::Test {
virtual void TearDown(); virtual void TearDown();
OverUseDetectorOptions over_use_detector_options_; OverUseDetectorOptions over_use_detector_options_;
RtpRtcpClock* system_clock_; Clock* system_clock_;
ModuleRtpRtcpImpl* dummy_rtp_rtcp_impl_; ModuleRtpRtcpImpl* dummy_rtp_rtcp_impl_;
RTCPSender* rtcp_sender_; RTCPSender* rtcp_sender_;
RTCPReceiver* rtcp_receiver_; RTCPReceiver* rtcp_receiver_;
@ -79,7 +79,7 @@ class RtcpFormatRembTest : public ::testing::Test {
}; };
void RtcpFormatRembTest::SetUp() { void RtcpFormatRembTest::SetUp() {
system_clock_ = ModuleRTPUtility::GetSystemClock(); system_clock_ = Clock::GetRealTimeClock();
RtpRtcp::Configuration configuration; RtpRtcp::Configuration configuration;
configuration.id = 0; configuration.id = 0;
configuration.audio = false; configuration.audio = false;

View File

@ -30,7 +30,7 @@ using namespace RTCPHelp;
// The number of RTCP time intervals needed to trigger a timeout. // The number of RTCP time intervals needed to trigger a timeout.
const int kRrTimeoutIntervals = 3; const int kRrTimeoutIntervals = 3;
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock, RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, Clock* clock,
ModuleRtpRtcpImpl* owner) ModuleRtpRtcpImpl* owner)
: TMMBRHelp(), : TMMBRHelp(),
_id(id), _id(id),
@ -285,7 +285,7 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
{ {
CriticalSectionScoped lock(_criticalSectionRTCPReceiver); CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
_lastReceived = _clock.GetTimeInMS(); _lastReceived = _clock.TimeInMilliseconds();
RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin(); RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
while (pktType != RTCPUtility::kRtcpNotValidCode) while (pktType != RTCPUtility::kRtcpNotValidCode)
@ -406,7 +406,7 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
_remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount; _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
_remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount; _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
_clock.CurrentNTP(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac); _clock.CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
} }
else else
{ {
@ -466,7 +466,7 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
return; return;
} }
_lastReceivedRrMs = _clock.GetTimeInMS(); _lastReceivedRrMs = _clock.TimeInMilliseconds();
const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem; const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC; reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC; reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
@ -496,7 +496,7 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
WebRtc_UWord32 lastReceivedRRNTPsecs = 0; WebRtc_UWord32 lastReceivedRRNTPsecs = 0;
WebRtc_UWord32 lastReceivedRRNTPfrac = 0; WebRtc_UWord32 lastReceivedRRNTPfrac = 0;
_clock.CurrentNTP(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac); _clock.CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
// time when we received this in MS // time when we received this in MS
WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS( WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS(
@ -641,7 +641,7 @@ RTCPReceiver::GetReceiveInformation(WebRtc_UWord32 remoteSSRC) {
void RTCPReceiver::UpdateReceiveInformation( void RTCPReceiver::UpdateReceiveInformation(
RTCPReceiveInformation& receiveInformation) { RTCPReceiveInformation& receiveInformation) {
// Update that this remote is alive // Update that this remote is alive
receiveInformation.lastTimeReceived = _clock.GetTimeInMS(); receiveInformation.lastTimeReceived = _clock.TimeInMilliseconds();
} }
bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) { bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
@ -650,7 +650,7 @@ bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
return false; return false;
int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms; int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
if (_clock.GetTimeInMS() > _lastReceivedRrMs + time_out_ms) { if (_clock.TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
// Reset the timer to only trigger one log. // Reset the timer to only trigger one log.
_lastReceivedRrMs = 0; _lastReceivedRrMs = 0;
return true; return true;
@ -664,7 +664,8 @@ bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
return false; return false;
int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms; int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
if (_clock.GetTimeInMS() > _lastIncreasedSequenceNumberMs + time_out_ms) { if (_clock.TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
time_out_ms) {
// Reset the timer to only trigger one log. // Reset the timer to only trigger one log.
_lastIncreasedSequenceNumberMs = 0; _lastIncreasedSequenceNumberMs = 0;
return true; return true;
@ -676,7 +677,7 @@ bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
CriticalSectionScoped lock(_criticalSectionRTCPReceiver); CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
bool updateBoundingSet = false; bool updateBoundingSet = false;
WebRtc_Word64 timeNow = _clock.GetTimeInMS(); WebRtc_Word64 timeNow = _clock.TimeInMilliseconds();
std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt = std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
_receivedInfoMap.begin(); _receivedInfoMap.begin();
@ -961,7 +962,7 @@ RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
{ {
receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem, receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
_clock.GetTimeInMS()); _clock.TimeInMilliseconds());
rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr; rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
} }
} }
@ -1149,7 +1150,7 @@ void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
// check if we have reported this FIRSequenceNumber before // check if we have reported this FIRSequenceNumber before
if (rtcpPacket.FIRItem.CommandSequenceNumber != if (rtcpPacket.FIRItem.CommandSequenceNumber !=
receiveInfo->lastFIRSequenceNumber) { receiveInfo->lastFIRSequenceNumber) {
WebRtc_Word64 now = _clock.GetTimeInMS(); WebRtc_Word64 now = _clock.TimeInMilliseconds();
// sanity; don't go crazy with the callbacks // sanity; don't go crazy with the callbacks
if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) { if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
receiveInfo->lastFIRRequest = now; receiveInfo->lastFIRRequest = now;
@ -1307,7 +1308,7 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr || if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) && rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
rtcpPacketInformation.reportBlock) { rtcpPacketInformation.reportBlock) {
WebRtc_Word64 now = _clock.GetTimeInMS(); WebRtc_Word64 now = _clock.TimeInMilliseconds();
_cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport( _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
rtcpPacketInformation.remoteSSRC, rtcpPacketInformation.remoteSSRC,
rtcpPacketInformation.fractionLost, rtcpPacketInformation.fractionLost,
@ -1377,7 +1378,7 @@ WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
for (WebRtc_UWord32 i = 0; for (WebRtc_UWord32 i = 0;
(num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) { (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
if (receiveInfo->GetTMMBRSet(i, num, candidateSet, if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
_clock.GetTimeInMS()) == 0) { _clock.TimeInMilliseconds()) == 0) {
num++; num++;
} }
} }
@ -1424,7 +1425,7 @@ void RTCPReceiver::PacketTimeout()
return; return;
} }
WebRtc_Word64 now = _clock.GetTimeInMS(); WebRtc_Word64 now = _clock.TimeInMilliseconds();
if(now - _lastReceived > _packetTimeOutMS) if(now - _lastReceived > _packetTimeOutMS)
{ {
packetTimeOut = true; packetTimeOut = true;

View File

@ -27,7 +27,7 @@ class ModuleRtpRtcpImpl;
class RTCPReceiver : public TMMBRHelp class RTCPReceiver : public TMMBRHelp
{ {
public: public:
RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock, RTCPReceiver(const WebRtc_Word32 id, Clock* clock,
ModuleRtpRtcpImpl* owner); ModuleRtpRtcpImpl* owner);
virtual ~RTCPReceiver(); virtual ~RTCPReceiver();
@ -198,7 +198,7 @@ protected:
private: private:
WebRtc_Word32 _id; WebRtc_Word32 _id;
RtpRtcpClock& _clock; Clock& _clock;
RTCPMethod _method; RTCPMethod _method;
WebRtc_Word64 _lastReceived; WebRtc_Word64 _lastReceived;
ModuleRtpRtcpImpl& _rtpRtcp; ModuleRtpRtcpImpl& _rtpRtcp;

View File

@ -134,34 +134,6 @@ class PacketBuilder {
WebRtc_UWord8 buffer_[kMaxPacketSize]; WebRtc_UWord8 buffer_[kMaxPacketSize];
}; };
// Fake system clock, controllable to the millisecond.
// The Epoch for this clock is Jan 1, 1970, as evidenced
// by the NTP calculation.
class FakeSystemClock : public RtpRtcpClock {
public:
FakeSystemClock()
: time_in_ms_(1335900000) {} // A nonzero, but fake, value.
virtual WebRtc_Word64 GetTimeInMS() {
return time_in_ms_;
}
virtual void CurrentNTP(WebRtc_UWord32& secs,
WebRtc_UWord32& frac) {
secs = (time_in_ms_ / 1000) + ModuleRTPUtility::NTP_JAN_1970;
// NTP_FRAC is 2^32 - number of ticks per second in the NTP fraction.
frac = (WebRtc_UWord32)((time_in_ms_ % 1000)
* ModuleRTPUtility::NTP_FRAC / 1000);
}
void AdvanceClock(int ms_to_advance) {
time_in_ms_ += ms_to_advance;
}
private:
WebRtc_Word64 time_in_ms_;
};
// This test transport verifies that no functions get called. // This test transport verifies that no functions get called.
class TestTransport : public Transport, class TestTransport : public Transport,
public RtpData { public RtpData {
@ -202,8 +174,7 @@ class RtcpReceiverTest : public ::testing::Test {
&remote_bitrate_observer_, &remote_bitrate_observer_,
over_use_detector_options_, over_use_detector_options_,
RemoteBitrateEstimator::kMultiStreamEstimation)) { RemoteBitrateEstimator::kMultiStreamEstimation)) {
// system_clock_ = ModuleRTPUtility::GetSystemClock(); system_clock_ = new SimulatedClock(1335900000);
system_clock_ = new FakeSystemClock();
test_transport_ = new TestTransport(); test_transport_ = new TestTransport();
RtpRtcp::Configuration configuration; RtpRtcp::Configuration configuration;
@ -239,7 +210,7 @@ class RtcpReceiverTest : public ::testing::Test {
} }
OverUseDetectorOptions over_use_detector_options_; OverUseDetectorOptions over_use_detector_options_;
FakeSystemClock* system_clock_; SimulatedClock* system_clock_;
ModuleRtpRtcpImpl* rtp_rtcp_impl_; ModuleRtpRtcpImpl* rtp_rtcp_impl_;
RTCPReceiver* rtcp_receiver_; RTCPReceiver* rtcp_receiver_;
TestTransport* test_transport_; TestTransport* test_transport_;
@ -275,7 +246,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
rtcp_receiver_->SetSSRC(kSourceSsrc); rtcp_receiver_->SetSSRC(kSourceSsrc);
uint32_t sequence_number = 1234; uint32_t sequence_number = 1234;
system_clock_->AdvanceClock(3 * kRtcpIntervalMs); system_clock_->AdvanceTimeMs(3 * kRtcpIntervalMs);
// No RR received, shouldn't trigger a timeout. // No RR received, shouldn't trigger a timeout.
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
@ -285,7 +256,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
PacketBuilder p1; PacketBuilder p1;
p1.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number); p1.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
EXPECT_EQ(0, InjectRtcpPacket(p1.packet(), p1.length())); EXPECT_EQ(0, InjectRtcpPacket(p1.packet(), p1.length()));
system_clock_->AdvanceClock(3 * kRtcpIntervalMs - 1); system_clock_->AdvanceTimeMs(3 * kRtcpIntervalMs - 1);
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
@ -294,12 +265,12 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
PacketBuilder p2; PacketBuilder p2;
p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number); p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length())); EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length()));
system_clock_->AdvanceClock(2); system_clock_->AdvanceTimeMs(2);
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
// Advance clock enough to trigger an RR timeout too. // Advance clock enough to trigger an RR timeout too.
system_clock_->AdvanceClock(3 * kRtcpIntervalMs); system_clock_->AdvanceTimeMs(3 * kRtcpIntervalMs);
EXPECT_TRUE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_TRUE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
// We should only get one timeout even though we still haven't received a new // We should only get one timeout even though we still haven't received a new
@ -316,14 +287,14 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
// Verify we can get a timeout again once we've received new RR. // Verify we can get a timeout again once we've received new RR.
system_clock_->AdvanceClock(2 * kRtcpIntervalMs); system_clock_->AdvanceTimeMs(2 * kRtcpIntervalMs);
PacketBuilder p4; PacketBuilder p4;
p4.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number); p4.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
EXPECT_EQ(0, InjectRtcpPacket(p4.packet(), p4.length())); EXPECT_EQ(0, InjectRtcpPacket(p4.packet(), p4.length()));
system_clock_->AdvanceClock(kRtcpIntervalMs + 1); system_clock_->AdvanceTimeMs(kRtcpIntervalMs + 1);
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs)); EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
system_clock_->AdvanceClock(2 * kRtcpIntervalMs); system_clock_->AdvanceTimeMs(2 * kRtcpIntervalMs);
EXPECT_TRUE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs)); EXPECT_TRUE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
} }
@ -415,7 +386,7 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
p.AddTmmbrBandwidth(30000, 0, 0); // 30 Kbits/sec bandwidth, no overhead. p.AddTmmbrBandwidth(30000, 0, 0); // 30 Kbits/sec bandwidth, no overhead.
EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length())); EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
system_clock_->AdvanceClock(5000); // 5 seconds between each packet. system_clock_->AdvanceTimeMs(5000); // 5 seconds between each packet.
} }
// It is now starttime+15. // It is now starttime+15.
EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
@ -425,7 +396,7 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
EXPECT_LT(0U, candidate_set.Tmmbr(0)); EXPECT_LT(0U, candidate_set.Tmmbr(0));
// We expect the timeout to be 25 seconds. Advance the clock by 12 // We expect the timeout to be 25 seconds. Advance the clock by 12
// seconds, timing out the first packet. // seconds, timing out the first packet.
system_clock_->AdvanceClock(12000); system_clock_->AdvanceTimeMs(12000);
// Odd behaviour: Just counting them does not trigger the timeout. // Odd behaviour: Just counting them does not trigger the timeout.
EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
// Odd behaviour: There's only one left after timeout, not 2. // Odd behaviour: There's only one left after timeout, not 2.

View File

@ -25,7 +25,7 @@ using RTCPUtility::RTCPCnameInformation;
RTCPSender::RTCPSender(const WebRtc_Word32 id, RTCPSender::RTCPSender(const WebRtc_Word32 id,
const bool audio, const bool audio,
RtpRtcpClock* clock, Clock* clock,
ModuleRtpRtcpImpl* owner) : ModuleRtpRtcpImpl* owner) :
_id(id), _id(id),
_audio(audio), _audio(audio),
@ -183,10 +183,12 @@ RTCPSender::SetRTCPStatus(const RTCPMethod method)
{ {
if(_audio) if(_audio)
{ {
_nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_AUDIO_MS/2); _nextTimeToSendRTCP = _clock.TimeInMilliseconds() +
(RTCP_INTERVAL_AUDIO_MS/2);
} else } else
{ {
_nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_VIDEO_MS/2); _nextTimeToSendRTCP = _clock.TimeInMilliseconds() +
(RTCP_INTERVAL_VIDEO_MS/2);
} }
} }
_method = method; _method = method;
@ -302,7 +304,7 @@ void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
last_rtp_timestamp_ = rtp_timestamp; last_rtp_timestamp_ = rtp_timestamp;
if (capture_time_ms < 0) { if (capture_time_ms < 0) {
// We don't currently get a capture time from VoiceEngine. // We don't currently get a capture time from VoiceEngine.
last_frame_capture_time_ms_ = _clock.GetTimeInMS(); last_frame_capture_time_ms_ = _clock.TimeInMilliseconds();
} else { } else {
last_frame_capture_time_ms_ = capture_time_ms; last_frame_capture_time_ms_ = capture_time_ms;
} }
@ -318,7 +320,7 @@ RTCPSender::SetSSRC( const WebRtc_UWord32 ssrc)
// not first SetSSRC, probably due to a collision // not first SetSSRC, probably due to a collision
// schedule a new RTCP report // schedule a new RTCP report
// make sure that we send a RTP packet // make sure that we send a RTP packet
_nextTimeToSendRTCP = _clock.GetTimeInMS() + 100; _nextTimeToSendRTCP = _clock.TimeInMilliseconds() + 100;
} }
_SSRC = ssrc; _SSRC = ssrc;
} }
@ -449,7 +451,7 @@ From RFC 3550
a value of the RTCP bandwidth below the intended average a value of the RTCP bandwidth below the intended average
*/ */
WebRtc_Word64 now = _clock.GetTimeInMS(); WebRtc_Word64 now = _clock.TimeInMilliseconds();
CriticalSectionScoped lock(_criticalSectionRTCPSender); CriticalSectionScoped lock(_criticalSectionRTCPSender);
@ -587,8 +589,9 @@ RTCPSender::BuildSR(WebRtc_UWord8* rtcpbuffer,
// the frame being captured at this moment. We are calculating that // the frame being captured at this moment. We are calculating that
// timestamp as the last frame's timestamp + the time since the last frame // timestamp as the last frame's timestamp + the time since the last frame
// was captured. // was captured.
RTPtime = start_timestamp_ + last_rtp_timestamp_ + (_clock.GetTimeInMS() - RTPtime = start_timestamp_ + last_rtp_timestamp_ + (
last_frame_capture_time_ms_) * (freqHz / 1000); _clock.TimeInMilliseconds() - last_frame_capture_time_ms_) *
(freqHz / 1000);
// Add sender data // Add sender data
// Save for our length field // Save for our length field
@ -1577,7 +1580,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
remoteSR); remoteSR);
// get our NTP as late as possible to avoid a race // get our NTP as late as possible to avoid a race
_clock.CurrentNTP(NTPsec, NTPfrac); _clock.CurrentNtp(NTPsec, NTPfrac);
// Delay since last received report // Delay since last received report
WebRtc_UWord32 delaySinceLastReceivedSR = 0; WebRtc_UWord32 delaySinceLastReceivedSR = 0;
@ -1599,7 +1602,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
} else } else
{ {
// we need to send our NTP even if we dont have received any reports // we need to send our NTP even if we dont have received any reports
_clock.CurrentNTP(NTPsec, NTPfrac); _clock.CurrentNtp(NTPsec, NTPfrac);
} }
} }
@ -1694,7 +1697,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
} }
timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000); timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000);
} }
_nextTimeToSendRTCP = _clock.GetTimeInMS() + timeToNext; _nextTimeToSendRTCP = _clock.TimeInMilliseconds() + timeToNext;
} }
// if the data does not fitt in the packet we fill it as much as possible // if the data does not fitt in the packet we fill it as much as possible

View File

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

View File

@ -105,7 +105,7 @@ class RtcpSenderTest : public ::testing::Test {
&remote_bitrate_observer_, &remote_bitrate_observer_,
over_use_detector_options_, over_use_detector_options_,
RemoteBitrateEstimator::kMultiStreamEstimation)) { RemoteBitrateEstimator::kMultiStreamEstimation)) {
system_clock_ = ModuleRTPUtility::GetSystemClock(); system_clock_ = Clock::GetRealTimeClock();
test_transport_ = new TestTransport(); test_transport_ = new TestTransport();
RtpRtcp::Configuration configuration; RtpRtcp::Configuration configuration;
@ -139,7 +139,7 @@ class RtcpSenderTest : public ::testing::Test {
} }
OverUseDetectorOptions over_use_detector_options_; OverUseDetectorOptions over_use_detector_options_;
RtpRtcpClock* system_clock_; Clock* system_clock_;
ModuleRtpRtcpImpl* rtp_rtcp_impl_; ModuleRtpRtcpImpl* rtp_rtcp_impl_;
RTCPSender* rtcp_sender_; RTCPSender* rtcp_sender_;
RTCPReceiver* rtcp_receiver_; RTCPReceiver* rtcp_receiver_;

View File

@ -19,7 +19,7 @@
namespace webrtc { namespace webrtc {
RTPPacketHistory::RTPPacketHistory(RtpRtcpClock* clock) RTPPacketHistory::RTPPacketHistory(Clock* clock)
: clock_(*clock), : clock_(*clock),
critsect_(CriticalSectionWrapper::CreateCriticalSection()), critsect_(CriticalSectionWrapper::CreateCriticalSection()),
store_(false), store_(false),
@ -140,7 +140,7 @@ int32_t RTPPacketHistory::PutRTPPacket(const uint8_t* packet,
stored_seq_nums_[prev_index_] = seq_num; stored_seq_nums_[prev_index_] = seq_num;
stored_lengths_[prev_index_] = packet_length; stored_lengths_[prev_index_] = packet_length;
stored_times_[prev_index_] = stored_times_[prev_index_] =
(capture_time_ms > 0) ? capture_time_ms : clock_.GetTimeInMS(); (capture_time_ms > 0) ? capture_time_ms : clock_.TimeInMilliseconds();
stored_resend_times_[prev_index_] = 0; // packet not resent stored_resend_times_[prev_index_] = 0; // packet not resent
stored_types_[prev_index_] = type; stored_types_[prev_index_] = type;
@ -244,7 +244,7 @@ bool RTPPacketHistory::GetRTPPacket(uint16_t sequence_number,
} }
// Verify elapsed time since last retrieve. // Verify elapsed time since last retrieve.
int64_t now = clock_.GetTimeInMS(); int64_t now = clock_.TimeInMilliseconds();
if (min_elapsed_time_ms > 0 && if (min_elapsed_time_ms > 0 &&
((now - stored_resend_times_.at(index)) < min_elapsed_time_ms)) { ((now - stored_resend_times_.at(index)) < min_elapsed_time_ms)) {
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1,
@ -276,7 +276,7 @@ void RTPPacketHistory::UpdateResendTime(uint16_t sequence_number) {
"Failed to update resend time, seq num: %u.", sequence_number); "Failed to update resend time, seq num: %u.", sequence_number);
return; return;
} }
stored_resend_times_[index] = clock_.GetTimeInMS(); stored_resend_times_[index] = clock_.TimeInMilliseconds();
} }
// private, lock should already be taken // private, lock should already be taken

View File

@ -21,12 +21,12 @@
namespace webrtc { namespace webrtc {
class RtpRtcpClock; class Clock;
class CriticalSectionWrapper; class CriticalSectionWrapper;
class RTPPacketHistory { class RTPPacketHistory {
public: public:
RTPPacketHistory(RtpRtcpClock* clock); RTPPacketHistory(Clock* clock);
~RTPPacketHistory(); ~RTPPacketHistory();
void SetStorePacketsStatus(bool enable, uint16_t number_to_store); void SetStorePacketsStatus(bool enable, uint16_t number_to_store);
@ -77,7 +77,7 @@ class RTPPacketHistory {
bool FindSeqNum(uint16_t sequence_number, int32_t* index) const; bool FindSeqNum(uint16_t sequence_number, int32_t* index) const;
private: private:
RtpRtcpClock& clock_; Clock& clock_;
CriticalSectionWrapper* critsect_; CriticalSectionWrapper* critsect_;
bool store_; bool store_;
uint32_t prev_index_; uint32_t prev_index_;

View File

@ -18,18 +18,23 @@
namespace webrtc { namespace webrtc {
class FakeClock : public RtpRtcpClock { class FakeClock : public Clock {
public: public:
FakeClock() { FakeClock() {
time_in_ms_ = 123456; time_in_ms_ = 123456;
} }
// Return a timestamp in milliseconds relative to some arbitrary // Return a timestamp in milliseconds relative to some arbitrary
// source; the source is fixed for this clock. // source; the source is fixed for this clock.
virtual WebRtc_Word64 GetTimeInMS() { virtual WebRtc_Word64 TimeInMilliseconds() {
return time_in_ms_; return time_in_ms_;
} }
virtual WebRtc_Word64 TimeInMicroseconds() {
return time_in_ms_ * 1000;
}
// Retrieve an NTP absolute timestamp. // Retrieve an NTP absolute timestamp.
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac) { virtual void CurrentNtp(WebRtc_UWord32& secs, WebRtc_UWord32& frac) {
secs = time_in_ms_ / 1000; secs = time_in_ms_ / 1000;
frac = (time_in_ms_ % 1000) * 4294967; frac = (time_in_ms_ % 1000) * 4294967;
} }
@ -87,7 +92,7 @@ TEST_F(RtpPacketHistoryTest, SetStoreStatus) {
TEST_F(RtpPacketHistoryTest, NoStoreStatus) { TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
EXPECT_FALSE(hist_->StorePackets()); EXPECT_FALSE(hist_->StorePackets());
uint16_t len = 0; uint16_t len = 0;
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength, EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
capture_time_ms, kAllowRetransmission)); capture_time_ms, kAllowRetransmission));
@ -101,7 +106,7 @@ TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
TEST_F(RtpPacketHistoryTest, DontStore) { TEST_F(RtpPacketHistoryTest, DontStore) {
hist_->SetStorePacketsStatus(true, 10); hist_->SetStorePacketsStatus(true, 10);
uint16_t len = 0; uint16_t len = 0;
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength, EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
capture_time_ms, kDontStore)); capture_time_ms, kDontStore));
@ -115,7 +120,7 @@ TEST_F(RtpPacketHistoryTest, DontStore) {
TEST_F(RtpPacketHistoryTest, PutRtpPacket_TooLargePacketLength) { TEST_F(RtpPacketHistoryTest, PutRtpPacket_TooLargePacketLength) {
hist_->SetStorePacketsStatus(true, 10); hist_->SetStorePacketsStatus(true, 10);
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
EXPECT_EQ(-1, hist_->PutRTPPacket(packet_, EXPECT_EQ(-1, hist_->PutRTPPacket(packet_,
kMaxPacketLength + 1, kMaxPacketLength + 1,
kMaxPacketLength, kMaxPacketLength,
@ -126,7 +131,7 @@ TEST_F(RtpPacketHistoryTest, PutRtpPacket_TooLargePacketLength) {
TEST_F(RtpPacketHistoryTest, GetRtpPacket_TooSmallBuffer) { TEST_F(RtpPacketHistoryTest, GetRtpPacket_TooSmallBuffer) {
hist_->SetStorePacketsStatus(true, 10); hist_->SetStorePacketsStatus(true, 10);
uint16_t len = 0; uint16_t len = 0;
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength, EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
capture_time_ms, kAllowRetransmission)); capture_time_ms, kAllowRetransmission));
@ -151,7 +156,7 @@ TEST_F(RtpPacketHistoryTest, PutRtpPacket) {
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
EXPECT_FALSE(hist_->HasRTPPacket(kSeqNum)); EXPECT_FALSE(hist_->HasRTPPacket(kSeqNum));
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength, EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
capture_time_ms, kAllowRetransmission)); capture_time_ms, kAllowRetransmission));
EXPECT_TRUE(hist_->HasRTPPacket(kSeqNum)); EXPECT_TRUE(hist_->HasRTPPacket(kSeqNum));
@ -220,7 +225,7 @@ TEST_F(RtpPacketHistoryTest, NoCaptureTime) {
hist_->SetStorePacketsStatus(true, 10); hist_->SetStorePacketsStatus(true, 10);
uint16_t len = 0; uint16_t len = 0;
fake_clock_.IncrementTime(1); fake_clock_.IncrementTime(1);
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength, EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
-1, kAllowRetransmission)); -1, kAllowRetransmission));
@ -241,7 +246,7 @@ TEST_F(RtpPacketHistoryTest, NoCaptureTime) {
TEST_F(RtpPacketHistoryTest, DontRetransmit) { TEST_F(RtpPacketHistoryTest, DontRetransmit) {
hist_->SetStorePacketsStatus(true, 10); hist_->SetStorePacketsStatus(true, 10);
uint16_t len = 0; uint16_t len = 0;
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength, EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
capture_time_ms, kDontRetransmit)); capture_time_ms, kDontRetransmit));
@ -259,7 +264,7 @@ TEST_F(RtpPacketHistoryTest, DontRetransmit) {
TEST_F(RtpPacketHistoryTest, MinResendTime) { TEST_F(RtpPacketHistoryTest, MinResendTime) {
hist_->SetStorePacketsStatus(true, 10); hist_->SetStorePacketsStatus(true, 10);
uint16_t len = 0; uint16_t len = 0;
int64_t capture_time_ms = fake_clock_.GetTimeInMS(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength, EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
capture_time_ms, kAllowRetransmission)); capture_time_ms, kAllowRetransmission));

View File

@ -33,7 +33,7 @@ using ModuleRTPUtility::VideoPayload;
RTPReceiver::RTPReceiver(const WebRtc_Word32 id, RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
const bool audio, const bool audio,
RtpRtcpClock* clock, Clock* clock,
ModuleRtpRtcpImpl* owner, ModuleRtpRtcpImpl* owner,
RtpAudioFeedback* incoming_audio_messages_callback, RtpAudioFeedback* incoming_audio_messages_callback,
RtpData* incoming_payload_callback, RtpData* incoming_payload_callback,
@ -178,7 +178,7 @@ void RTPReceiver::PacketTimeout() {
return; return;
} }
WebRtc_Word64 now = clock_.GetTimeInMS(); WebRtc_Word64 now = clock_.TimeInMilliseconds();
if (now - last_receive_time_ > packet_timeout_ms_) { if (now - last_receive_time_ > packet_timeout_ms_) {
packet_time_out = true; packet_time_out = true;
@ -628,7 +628,7 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket(
WebRtc_Word32 ret_val = rtp_media_receiver_->ParseRtpPacket( WebRtc_Word32 ret_val = rtp_media_receiver_->ParseRtpPacket(
rtp_header, specific_payload, is_red, packet, rtp_header, specific_payload, is_red, packet,
packet_length, clock_.GetTimeInMS()); packet_length, clock_.TimeInMilliseconds());
if (ret_val < 0) { if (ret_val < 0) {
return ret_val; return ret_val;
@ -646,13 +646,13 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket(
// Need to be updated after RetransmitOfOldPacket and // Need to be updated after RetransmitOfOldPacket and
// RetransmitOfOldPacketUpdateStatistics. // RetransmitOfOldPacketUpdateStatistics.
last_receive_time_ = clock_.GetTimeInMS(); last_receive_time_ = clock_.TimeInMilliseconds();
last_received_payload_length_ = payload_data_length; last_received_payload_length_ = payload_data_length;
if (!old_packet) { if (!old_packet) {
if (last_received_timestamp_ != rtp_header->header.timestamp) { if (last_received_timestamp_ != rtp_header->header.timestamp) {
last_received_timestamp_ = rtp_header->header.timestamp; last_received_timestamp_ = rtp_header->header.timestamp;
last_received_frame_time_ms_ = clock_.GetTimeInMS(); last_received_frame_time_ms_ = clock_.TimeInMilliseconds();
} }
last_received_sequence_number_ = rtp_header->header.sequenceNumber; last_received_sequence_number_ = rtp_header->header.sequenceNumber;
last_received_transmission_time_offset_ = last_received_transmission_time_offset_ =
@ -760,7 +760,7 @@ bool RTPReceiver::RetransmitOfOldPacket(
} }
WebRtc_UWord32 frequency_khz = rtp_media_receiver_->GetFrequencyHz() / 1000; WebRtc_UWord32 frequency_khz = rtp_media_receiver_->GetFrequencyHz() / 1000;
WebRtc_Word64 time_diff_ms = clock_.GetTimeInMS() - last_receive_time_; WebRtc_Word64 time_diff_ms = clock_.TimeInMilliseconds() - last_receive_time_;
// Diff in time stamp since last received in order. // Diff in time stamp since last received in order.
WebRtc_Word32 rtp_time_stamp_diff_ms = WebRtc_Word32 rtp_time_stamp_diff_ms =

View File

@ -36,7 +36,7 @@ class RTPReceiver : public Bitrate {
// want callbacks to do nothing). // want callbacks to do nothing).
RTPReceiver(const WebRtc_Word32 id, RTPReceiver(const WebRtc_Word32 id,
const bool audio, const bool audio,
RtpRtcpClock* clock, Clock* clock,
ModuleRtpRtcpImpl* owner, ModuleRtpRtcpImpl* owner,
RtpAudioFeedback* incoming_audio_messages_callback, RtpAudioFeedback* incoming_audio_messages_callback,
RtpData* incoming_payload_callback, RtpData* incoming_payload_callback,

View File

@ -80,7 +80,7 @@ RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
RtpRtcp::Configuration configuration_copy; RtpRtcp::Configuration configuration_copy;
memcpy(&configuration_copy, &configuration, memcpy(&configuration_copy, &configuration,
sizeof(RtpRtcp::Configuration)); sizeof(RtpRtcp::Configuration));
configuration_copy.clock = ModuleRTPUtility::GetSystemClock(); configuration_copy.clock = Clock::GetRealTimeClock();
ModuleRtpRtcpImpl* rtp_rtcp_instance = ModuleRtpRtcpImpl* rtp_rtcp_instance =
new ModuleRtpRtcpImpl(configuration_copy); new ModuleRtpRtcpImpl(configuration_copy);
rtp_rtcp_instance->OwnsClock(); rtp_rtcp_instance->OwnsClock();
@ -107,9 +107,10 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
id_(configuration.id), id_(configuration.id),
audio_(configuration.audio), audio_(configuration.audio),
collision_detected_(false), collision_detected_(false),
last_process_time_(configuration.clock->GetTimeInMS()), last_process_time_(configuration.clock->TimeInMilliseconds()),
last_bitrate_process_time_(configuration.clock->GetTimeInMS()), last_bitrate_process_time_(configuration.clock->TimeInMilliseconds()),
last_packet_timeout_process_time_(configuration.clock->GetTimeInMS()), last_packet_timeout_process_time_(
configuration.clock->TimeInMilliseconds()),
packet_overhead_(28), // IPV4 UDP. packet_overhead_(28), // IPV4 UDP.
critical_section_module_ptrs_( critical_section_module_ptrs_(
CriticalSectionWrapper::CreateCriticalSection()), CriticalSectionWrapper::CreateCriticalSection()),
@ -216,13 +217,13 @@ void ModuleRtpRtcpImpl::DeRegisterChildModule(RtpRtcp* remove_module) {
// Returns the number of milliseconds until the module want a worker thread // Returns the number of milliseconds until the module want a worker thread
// to call Process. // to call Process.
WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess() { WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess() {
const WebRtc_Word64 now = clock_.GetTimeInMS(); const WebRtc_Word64 now = clock_.TimeInMilliseconds();
return kRtpRtcpMaxIdleTimeProcess - (now - last_process_time_); return kRtpRtcpMaxIdleTimeProcess - (now - last_process_time_);
} }
// Process any pending tasks such as timeouts (non time critical events). // Process any pending tasks such as timeouts (non time critical events).
WebRtc_Word32 ModuleRtpRtcpImpl::Process() { WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
const WebRtc_Word64 now = clock_.GetTimeInMS(); const WebRtc_Word64 now = clock_.TimeInMilliseconds();
last_process_time_ = now; last_process_time_ = now;
if (now >= if (now >=
@ -304,7 +305,7 @@ WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() { void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
if (dead_or_alive_active_) { if (dead_or_alive_active_) {
const WebRtc_Word64 now = clock_.GetTimeInMS(); const WebRtc_Word64 now = clock_.TimeInMilliseconds();
if (now > dead_or_alive_timeout_ms_ + dead_or_alive_last_timer_) { if (now > dead_or_alive_timeout_ms_ + dead_or_alive_last_timer_) {
// RTCP is alive if we have received a report the last 12 seconds. // RTCP is alive if we have received a report the last 12 seconds.
dead_or_alive_last_timer_ += dead_or_alive_timeout_ms_; dead_or_alive_last_timer_ += dead_or_alive_timeout_ms_;
@ -339,7 +340,7 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetPeriodicDeadOrAliveStatus(
dead_or_alive_active_ = enable; dead_or_alive_active_ = enable;
dead_or_alive_timeout_ms_ = sample_time_seconds * 1000; dead_or_alive_timeout_ms_ = sample_time_seconds * 1000;
// Trigger the first after one period. // Trigger the first after one period.
dead_or_alive_last_timer_ = clock_.GetTimeInMS(); dead_or_alive_last_timer_ = clock_.TimeInMilliseconds();
return 0; return 0;
} }
@ -1519,7 +1520,7 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SendNACK(const WebRtc_UWord16* nack_list,
if (wait_time == 5) { if (wait_time == 5) {
wait_time = 100; // During startup we don't have an RTT. wait_time = 100; // During startup we don't have an RTT.
} }
const WebRtc_Word64 now = clock_.GetTimeInMS(); const WebRtc_Word64 now = clock_.TimeInMilliseconds();
const WebRtc_Word64 time_limit = now - wait_time; const WebRtc_Word64 time_limit = now - wait_time;
WebRtc_UWord16 nackLength = size; WebRtc_UWord16 nackLength = size;
WebRtc_UWord16 start_id = 0; WebRtc_UWord16 start_id = 0;

View File

@ -484,7 +484,7 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
RTCPReceiver rtcp_receiver_; RTCPReceiver rtcp_receiver_;
bool owns_clock_; bool owns_clock_;
RtpRtcpClock& clock_; Clock& clock_;
private: private:
int64_t RtcpReportInterval(); int64_t RtcpReportInterval();

View File

@ -22,7 +22,7 @@
namespace webrtc { namespace webrtc {
RTPSender::RTPSender(const WebRtc_Word32 id, RTPSender::RTPSender(const WebRtc_Word32 id,
const bool audio, const bool audio,
RtpRtcpClock* clock, Clock* clock,
Transport* transport, Transport* transport,
RtpAudioFeedback* audio_feedback, RtpAudioFeedback* audio_feedback,
PacedSender* paced_sender) PacedSender* paced_sender)
@ -75,7 +75,7 @@ RTPSender::RTPSender(const WebRtc_Word32 id,
memset(_nackByteCount, 0, sizeof(_nackByteCount)); memset(_nackByteCount, 0, sizeof(_nackByteCount));
memset(_CSRC, 0, sizeof(_CSRC)); memset(_CSRC, 0, sizeof(_CSRC));
// We need to seed the random generator. // We need to seed the random generator.
srand( (WebRtc_UWord32)clock_.GetTimeInMS() ); srand( (WebRtc_UWord32)clock_.TimeInMilliseconds() );
_ssrc = _ssrcDB.CreateSSRC(); // Can't be 0. _ssrc = _ssrcDB.CreateSSRC(); // Can't be 0.
if (audio) { if (audio) {
@ -576,7 +576,7 @@ int RTPSender::SetSelectiveRetransmissions(uint8_t settings) {
void RTPSender::OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength, void RTPSender::OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength,
const WebRtc_UWord16* nackSequenceNumbers, const WebRtc_UWord16* nackSequenceNumbers,
const WebRtc_UWord16 avgRTT) { const WebRtc_UWord16 avgRTT) {
const WebRtc_Word64 now = clock_.GetTimeInMS(); const WebRtc_Word64 now = clock_.TimeInMilliseconds();
WebRtc_UWord32 bytesReSent = 0; WebRtc_UWord32 bytesReSent = 0;
// Enough bandwidth to send NACK? // Enough bandwidth to send NACK?
@ -700,7 +700,7 @@ void RTPSender::TimeToSendPacket(uint16_t sequence_number,
WebRtcRTPHeader rtp_header; WebRtcRTPHeader rtp_header;
rtpParser.Parse(rtp_header); rtpParser.Parse(rtp_header);
int64_t diff_ms = clock_.GetTimeInMS() - capture_time_ms; int64_t diff_ms = clock_.TimeInMilliseconds() - capture_time_ms;
if (UpdateTransmissionTimeOffset(data_buffer, length, rtp_header, diff_ms)) { if (UpdateTransmissionTimeOffset(data_buffer, length, rtp_header, diff_ms)) {
// Update stored packet in case of receiving a re-transmission request. // Update stored packet in case of receiving a re-transmission request.
_packetHistory->ReplaceRTPHeader(data_buffer, _packetHistory->ReplaceRTPHeader(data_buffer,
@ -738,7 +738,7 @@ WebRtc_Word32 RTPSender::SendToNetwork(uint8_t* buffer,
// TODO(holmer): This should be changed all over Video Engine so that negative // TODO(holmer): This should be changed all over Video Engine so that negative
// time is consider invalid, while 0 is considered a valid time. // time is consider invalid, while 0 is considered a valid time.
if (capture_time_ms > 0) { if (capture_time_ms > 0) {
int64_t time_now = clock_.GetTimeInMS(); int64_t time_now = clock_.TimeInMilliseconds();
UpdateTransmissionTimeOffset(buffer, payload_length + rtp_header_length, UpdateTransmissionTimeOffset(buffer, payload_length + rtp_header_length,
rtp_header, time_now - capture_time_ms); rtp_header, time_now - capture_time_ms);
} }

View File

@ -66,7 +66,7 @@ class RTPSender : public Bitrate, public RTPSenderInterface {
public: public:
RTPSender(const WebRtc_Word32 id, RTPSender(const WebRtc_Word32 id,
const bool audio, const bool audio,
RtpRtcpClock* clock, Clock* clock,
Transport* transport, Transport* transport,
RtpAudioFeedback* audio_feedback, RtpAudioFeedback* audio_feedback,
PacedSender* paced_sender); PacedSender* paced_sender);

View File

@ -14,7 +14,7 @@
#include <cassert> //assert #include <cassert> //assert
namespace webrtc { namespace webrtc {
RTPSenderAudio::RTPSenderAudio(const WebRtc_Word32 id, RtpRtcpClock* clock, RTPSenderAudio::RTPSenderAudio(const WebRtc_Word32 id, Clock* clock,
RTPSenderInterface* rtpSender) : RTPSenderInterface* rtpSender) :
_id(id), _id(id),
_clock(*clock), _clock(*clock),
@ -217,7 +217,8 @@ RTPSenderAudio::SendTelephoneEventActive(WebRtc_Word8& telephoneEvent) const
telephoneEvent = _dtmfKey; telephoneEvent = _dtmfKey;
return true; return true;
} }
WebRtc_Word64 delaySinceLastDTMF = _clock.GetTimeInMS() - _dtmfTimeLastSent; WebRtc_Word64 delaySinceLastDTMF = _clock.TimeInMilliseconds() -
_dtmfTimeLastSent;
if(delaySinceLastDTMF < 100) if(delaySinceLastDTMF < 100)
{ {
telephoneEvent = _dtmfKey; telephoneEvent = _dtmfKey;
@ -245,7 +246,8 @@ WebRtc_Word32 RTPSenderAudio::SendAudio(
if (!_dtmfEventIsOn && PendingDTMF()) { if (!_dtmfEventIsOn && PendingDTMF()) {
CriticalSectionScoped cs(_sendAudioCritsect); CriticalSectionScoped cs(_sendAudioCritsect);
WebRtc_Word64 delaySinceLastDTMF = _clock.GetTimeInMS() - _dtmfTimeLastSent; WebRtc_Word64 delaySinceLastDTMF = _clock.TimeInMilliseconds() -
_dtmfTimeLastSent;
if (delaySinceLastDTMF > 100) { if (delaySinceLastDTMF > 100) {
// New tone to play // New tone to play
@ -295,7 +297,7 @@ WebRtc_Word32 RTPSenderAudio::SendAudio(
} else { } else {
ended = true; ended = true;
_dtmfEventIsOn = false; _dtmfEventIsOn = false;
_dtmfTimeLastSent = _clock.GetTimeInMS(); _dtmfTimeLastSent = _clock.TimeInMilliseconds();
} }
// don't hold the critsect while calling SendTelephoneEventPacket // don't hold the critsect while calling SendTelephoneEventPacket
_sendAudioCritsect->Leave(); _sendAudioCritsect->Leave();

View File

@ -24,7 +24,7 @@ namespace webrtc {
class RTPSenderAudio: public DTMFqueue class RTPSenderAudio: public DTMFqueue
{ {
public: public:
RTPSenderAudio(const WebRtc_Word32 id, RtpRtcpClock* clock, RTPSenderAudio(const WebRtc_Word32 id, Clock* clock,
RTPSenderInterface* rtpSender); RTPSenderInterface* rtpSender);
virtual ~RTPSenderAudio(); virtual ~RTPSenderAudio();
@ -89,10 +89,10 @@ protected:
private: private:
WebRtc_Word32 _id; WebRtc_Word32 _id;
RtpRtcpClock& _clock; Clock& _clock;
RTPSenderInterface* _rtpSender; RTPSenderInterface* _rtpSender;
CriticalSectionWrapper* _audioFeedbackCritsect; CriticalSectionWrapper* _audioFeedbackCritsect;
RtpAudioFeedback* _audioFeedback; RtpAudioFeedback* _audioFeedback;
CriticalSectionWrapper* _sendAudioCritsect; CriticalSectionWrapper* _sendAudioCritsect;

View File

@ -33,18 +33,23 @@ const int kTimeOffset = 22222;
const int kMaxPacketLength = 1500; const int kMaxPacketLength = 1500;
} // namespace } // namespace
class FakeClockTest : public RtpRtcpClock { class FakeClockTest : public Clock {
public: public:
FakeClockTest() { FakeClockTest() {
time_in_ms_ = 123456; time_in_ms_ = 123456;
} }
// Return a timestamp in milliseconds relative to some arbitrary // Return a timestamp in milliseconds relative to some arbitrary
// source; the source is fixed for this clock. // source; the source is fixed for this clock.
virtual WebRtc_Word64 GetTimeInMS() { virtual WebRtc_Word64 TimeInMilliseconds() {
return time_in_ms_; return time_in_ms_;
} }
virtual WebRtc_Word64 TimeInMicroseconds() {
return time_in_ms_ * 1000;
}
// Retrieve an NTP absolute timestamp. // Retrieve an NTP absolute timestamp.
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac) { virtual void CurrentNtp(WebRtc_UWord32& secs, WebRtc_UWord32& frac) {
secs = time_in_ms_ / 1000; secs = time_in_ms_ / 1000;
frac = (time_in_ms_ % 1000) * 4294967; frac = (time_in_ms_ % 1000) * 4294967;
} }
@ -223,7 +228,7 @@ TEST_F(RtpSenderTest, DISABLED_TrafficSmoothing) {
EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_, EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_,
0, 0,
rtp_length, rtp_length,
fake_clock_.GetTimeInMS(), fake_clock_.TimeInMilliseconds(),
kAllowRetransmission)); kAllowRetransmission));
EXPECT_EQ(0, transport_.packets_sent_); EXPECT_EQ(0, transport_.packets_sent_);
const int kStoredTimeInMs = 100; const int kStoredTimeInMs = 100;

View File

@ -31,7 +31,7 @@ struct RtpPacket {
}; };
RTPSenderVideo::RTPSenderVideo(const WebRtc_Word32 id, RTPSenderVideo::RTPSenderVideo(const WebRtc_Word32 id,
RtpRtcpClock* clock, Clock* clock,
RTPSenderInterface* rtpSender) : RTPSenderInterface* rtpSender) :
_id(id), _id(id),
_rtpSender(*rtpSender), _rtpSender(*rtpSender),

View File

@ -33,7 +33,7 @@ struct RtpPacket;
class RTPSenderVideo class RTPSenderVideo
{ {
public: public:
RTPSenderVideo(const WebRtc_Word32 id, RtpRtcpClock* clock, RTPSenderVideo(const WebRtc_Word32 id, Clock* clock,
RTPSenderInterface* rtpSender); RTPSenderInterface* rtpSender);
virtual ~RTPSenderVideo(); virtual ~RTPSenderVideo();

View File

@ -49,225 +49,14 @@ namespace ModuleRTPUtility {
* Time routines. * Time routines.
*/ */
#if defined(_WIN32) WebRtc_UWord32 GetCurrentRTP(Clock* clock, WebRtc_UWord32 freq) {
struct reference_point {
FILETIME file_time;
LARGE_INTEGER counterMS;
};
struct WindowsHelpTimer {
volatile LONG _timeInMs;
volatile LONG _numWrapTimeInMs;
reference_point _ref_point;
volatile LONG _sync_flag;
};
void Synchronize(WindowsHelpTimer* help_timer) {
const LONG start_value = 0;
const LONG new_value = 1;
const LONG synchronized_value = 2;
LONG compare_flag = new_value;
while (help_timer->_sync_flag == start_value) {
const LONG new_value = 1;
compare_flag = InterlockedCompareExchange(
&help_timer->_sync_flag, new_value, start_value);
}
if (compare_flag != start_value) {
// This thread was not the one that incremented the sync flag.
// Block until synchronization finishes.
while (compare_flag != synchronized_value) {
::Sleep(0);
}
return;
}
// Only the synchronizing thread gets here so this part can be
// considered single threaded.
// set timer accuracy to 1 ms
timeBeginPeriod(1);
FILETIME ft0 = { 0, 0 },
ft1 = { 0, 0 };
//
// Spin waiting for a change in system time. Get the matching
// performance counter value for that time.
//
::GetSystemTimeAsFileTime(&ft0);
do {
::GetSystemTimeAsFileTime(&ft1);
help_timer->_ref_point.counterMS.QuadPart = ::timeGetTime();
::Sleep(0);
} while ((ft0.dwHighDateTime == ft1.dwHighDateTime) &&
(ft0.dwLowDateTime == ft1.dwLowDateTime));
help_timer->_ref_point.file_time = ft1;
}
void get_time(WindowsHelpTimer* help_timer, FILETIME& current_time) {
// we can't use query performance counter due to speed stepping
DWORD t = timeGetTime();
// NOTE: we have a missmatch in sign between _timeInMs(LONG) and
// (DWORD) however we only use it here without +- etc
volatile LONG* timeInMsPtr = &help_timer->_timeInMs;
// Make sure that we only inc wrapper once.
DWORD old = InterlockedExchange(timeInMsPtr, t);
if(old > t) {
// wrap
help_timer->_numWrapTimeInMs++;
}
LARGE_INTEGER elapsedMS;
elapsedMS.HighPart = help_timer->_numWrapTimeInMs;
elapsedMS.LowPart = t;
elapsedMS.QuadPart = elapsedMS.QuadPart -
help_timer->_ref_point.counterMS.QuadPart;
// Translate to 100-nanoseconds intervals (FILETIME resolution)
// and add to reference FILETIME to get current FILETIME.
ULARGE_INTEGER filetime_ref_as_ul;
filetime_ref_as_ul.HighPart =
help_timer->_ref_point.file_time.dwHighDateTime;
filetime_ref_as_ul.LowPart =
help_timer->_ref_point.file_time.dwLowDateTime;
filetime_ref_as_ul.QuadPart +=
(ULONGLONG)((elapsedMS.QuadPart)*1000*10);
// Copy to result
current_time.dwHighDateTime = filetime_ref_as_ul.HighPart;
current_time.dwLowDateTime = filetime_ref_as_ul.LowPart;
}
// A clock reading times from the Windows API.
class WindowsSystemClock : public RtpRtcpClock {
public:
WindowsSystemClock(WindowsHelpTimer* helpTimer)
: _helpTimer(helpTimer) {}
virtual ~WindowsSystemClock() {}
virtual WebRtc_Word64 GetTimeInMS();
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac);
private:
WindowsHelpTimer* _helpTimer;
};
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
// A clock reading times from the POSIX API.
class UnixSystemClock : public RtpRtcpClock {
public:
UnixSystemClock() {}
virtual ~UnixSystemClock() {}
virtual WebRtc_Word64 GetTimeInMS();
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac);
};
#endif
#if defined(_WIN32)
WebRtc_Word64 WindowsSystemClock::GetTimeInMS() {
return TickTime::MillisecondTimestamp();
}
// 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
get_time(_helpTimer, 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) {
dtemp -= 1;
secs++;
} else if (dtemp < -1) {
dtemp += 1;
secs--;
}
dtemp *= NTP_FRAC;
frac = (WebRtc_UWord32)dtemp;
}
#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))
WebRtc_Word64 UnixSystemClock::GetTimeInMS() {
return TickTime::MillisecondTimestamp();
}
// 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)
// Keeps the global state for the Windows implementation of RtpRtcpClock.
// Note that this is a POD. Only PODs are allowed to have static storage
// duration according to the Google Style guide.
static WindowsHelpTimer global_help_timer = {0, 0, {{ 0, 0}, 0}, 0};
#endif
RtpRtcpClock* GetSystemClock() {
#if defined(_WIN32)
return new WindowsSystemClock(&global_help_timer);
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
return new UnixSystemClock();
#else
return NULL;
#endif
}
WebRtc_UWord32 GetCurrentRTP(RtpRtcpClock* clock, WebRtc_UWord32 freq) {
const bool use_global_clock = (clock == NULL); const bool use_global_clock = (clock == NULL);
RtpRtcpClock* local_clock = clock; Clock* local_clock = clock;
if (use_global_clock) { if (use_global_clock) {
local_clock = GetSystemClock(); local_clock = Clock::GetRealTimeClock();
} }
WebRtc_UWord32 secs = 0, frac = 0; WebRtc_UWord32 secs = 0, frac = 0;
local_clock->CurrentNTP(secs, frac); local_clock->CurrentNtp(secs, frac);
if (use_global_clock) { if (use_global_clock) {
delete local_clock; delete local_clock;
} }

View File

@ -61,19 +61,9 @@ namespace ModuleRTPUtility
typedef std::map<WebRtc_Word8, Payload*> PayloadTypeMap; typedef std::map<WebRtc_Word8, Payload*> PayloadTypeMap;
// 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.
// Note that even though the instances returned by this function
// read the same times a new object is created every time this
// API is called. The ownership of this object belongs to the
// caller.
RtpRtcpClock* GetSystemClock();
// Return the current RTP timestamp from the NTP timestamp // Return the current RTP timestamp from the NTP timestamp
// returned by the specified clock. // returned by the specified clock.
WebRtc_UWord32 GetCurrentRTP(RtpRtcpClock* clock, WebRtc_UWord32 freq); WebRtc_UWord32 GetCurrentRTP(Clock* clock, WebRtc_UWord32 freq);
// Return the current RTP absolute timestamp. // Return the current RTP absolute timestamp.
WebRtc_UWord32 ConvertNTPTimeToRTP(WebRtc_UWord32 NTPsec, WebRtc_UWord32 ConvertNTPTimeToRTP(WebRtc_UWord32 NTPsec,

View File

@ -14,18 +14,21 @@
namespace webrtc { namespace webrtc {
class FakeRtpRtcpClock : public RtpRtcpClock { class FakeRtpRtcpClock : public Clock {
public: public:
FakeRtpRtcpClock() { FakeRtpRtcpClock() {
time_in_ms_ = 123456; time_in_ms_ = 123456;
} }
// Return a timestamp in milliseconds relative to some arbitrary // Return a timestamp in milliseconds relative to some arbitrary
// source; the source is fixed for this clock. // source; the source is fixed for this clock.
virtual WebRtc_Word64 GetTimeInMS() { virtual WebRtc_Word64 TimeInMilliseconds() {
return time_in_ms_; return time_in_ms_;
} }
virtual int64_t TimeInMicroseconds() {
return time_in_ms_ * 1000;
}
// Retrieve an NTP absolute timestamp. // Retrieve an NTP absolute timestamp.
virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac) { virtual void CurrentNtp(WebRtc_UWord32& secs, WebRtc_UWord32& frac) {
secs = time_in_ms_ / 1000; secs = time_in_ms_ / 1000;
frac = (time_in_ms_ % 1000) * 4294967; frac = (time_in_ms_ % 1000) * 4294967;
} }

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2013 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.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_
#include "webrtc/typedefs.h"
namespace webrtc {
// January 1970, in NTP seconds.
const uint32_t kNtpJan1970 = 2208988800UL;
// Magic NTP fractional unit.
const double kMagicNtpFractionalUnit = 4.294967296E+9;
// A clock interface that allows reading of absolute and relative timestamps.
class Clock {
public:
virtual ~Clock() {}
// Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMilliseconds() = 0;
// Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMicroseconds() = 0;
// Retrieve an NTP absolute timestamp.
virtual void CurrentNtp(uint32_t& seconds, uint32_t& fractions) = 0;
// Returns an instance of the real-time system clock implementation.
static Clock* GetRealTimeClock();
};
class SimulatedClock : public Clock {
public:
SimulatedClock();
explicit SimulatedClock(int64_t initial_time_us);
virtual ~SimulatedClock() {}
// Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMilliseconds();
// Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMicroseconds();
// Retrieve an NTP absolute timestamp.
virtual void CurrentNtp(uint32_t& seconds, uint32_t& fractions);
// Advance the simulated clock with a given number of milliseconds or
// microseconds.
void AdvanceTimeMs(int64_t milliseconds);
void AdvanceTimeUs(int64_t microseconds);
private:
int64_t time_us_;
};
}; // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_

View File

@ -0,0 +1,257 @@
/*
* Copyright (c) 2013 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/system_wrappers/interface/clock.h"
#if defined(_WIN32)
#include <Windows.h>
#include <WinSock.h>
#include <MMSystem.h>
#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))
#include <sys/time.h>
#include <time.h>
#endif
#include "webrtc/system_wrappers/interface/tick_util.h"
namespace webrtc {
#if defined(_WIN32)
struct reference_point {
FILETIME file_time;
LARGE_INTEGER counterMS;
};
struct WindowsHelpTimer {
volatile LONG _timeInMs;
volatile LONG _numWrapTimeInMs;
reference_point _ref_point;
volatile LONG _sync_flag;
};
void Synchronize(WindowsHelpTimer* help_timer) {
const LONG start_value = 0;
const LONG new_value = 1;
const LONG synchronized_value = 2;
LONG compare_flag = new_value;
while (help_timer->_sync_flag == start_value) {
const LONG new_value = 1;
compare_flag = InterlockedCompareExchange(
&help_timer->_sync_flag, new_value, start_value);
}
if (compare_flag != start_value) {
// This thread was not the one that incremented the sync flag.
// Block until synchronization finishes.
while (compare_flag != synchronized_value) {
::Sleep(0);
}
return;
}
// Only the synchronizing thread gets here so this part can be
// considered single threaded.
// set timer accuracy to 1 ms
timeBeginPeriod(1);
FILETIME ft0 = { 0, 0 },
ft1 = { 0, 0 };
//
// Spin waiting for a change in system time. Get the matching
// performance counter value for that time.
//
::GetSystemTimeAsFileTime(&ft0);
do {
::GetSystemTimeAsFileTime(&ft1);
help_timer->_ref_point.counterMS.QuadPart = ::timeGetTime();
::Sleep(0);
} while ((ft0.dwHighDateTime == ft1.dwHighDateTime) &&
(ft0.dwLowDateTime == ft1.dwLowDateTime));
help_timer->_ref_point.file_time = ft1;
}
void get_time(WindowsHelpTimer* help_timer, FILETIME& current_time) {
// we can't use query performance counter due to speed stepping
DWORD t = timeGetTime();
// NOTE: we have a missmatch in sign between _timeInMs(LONG) and
// (DWORD) however we only use it here without +- etc
volatile LONG* timeInMsPtr = &help_timer->_timeInMs;
// Make sure that we only inc wrapper once.
DWORD old = InterlockedExchange(timeInMsPtr, t);
if(old > t) {
// wrap
help_timer->_numWrapTimeInMs++;
}
LARGE_INTEGER elapsedMS;
elapsedMS.HighPart = help_timer->_numWrapTimeInMs;
elapsedMS.LowPart = t;
elapsedMS.QuadPart = elapsedMS.QuadPart -
help_timer->_ref_point.counterMS.QuadPart;
// Translate to 100-nanoseconds intervals (FILETIME resolution)
// and add to reference FILETIME to get current FILETIME.
ULARGE_INTEGER filetime_ref_as_ul;
filetime_ref_as_ul.HighPart =
help_timer->_ref_point.file_time.dwHighDateTime;
filetime_ref_as_ul.LowPart =
help_timer->_ref_point.file_time.dwLowDateTime;
filetime_ref_as_ul.QuadPart +=
(ULONGLONG)((elapsedMS.QuadPart)*1000*10);
// Copy to result
current_time.dwHighDateTime = filetime_ref_as_ul.HighPart;
current_time.dwLowDateTime = filetime_ref_as_ul.LowPart;
}
#endif
class RealTimeClock : public Clock {
// Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMilliseconds() {
return TickTime::MillisecondTimestamp();
}
// Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMicroseconds() {
return TickTime::MicrosecondTimestamp();
}
};
#if defined(_WIN32)
class WindowsRealTimeClock : public RealTimeClock {
public:
WindowsRealTimeClock(WindowsHelpTimer* helpTimer)
: _helpTimer(helpTimer) {}
virtual ~WindowsRealTimeClock() {}
// Retrieve an NTP absolute timestamp.
virtual void CurrentNtp(uint32_t& seconds, uint32_t& fractions) {
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
get_time(_helpTimer, 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;
seconds = tv.tv_sec + kNtpJan1970;
dtemp = tv.tv_usec / 1e6;
if (dtemp >= 1) {
dtemp -= 1;
seconds++;
} else if (dtemp < -1) {
dtemp += 1;
seconds--;
}
dtemp *= kMagicNtpFractionalUnit;
fractions = (WebRtc_UWord32)dtemp;
}
private:
WindowsHelpTimer* _helpTimer;
};
#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))
class UnixRealTimeClock : public RealTimeClock {
public:
UnixRealTimeClock() {}
virtual ~UnixRealTimeClock() {}
// Retrieve an NTP absolute timestamp.
virtual void CurrentNtp(uint32_t& seconds, uint32_t& fractions) {
double dtemp;
struct timeval tv;
struct timezone tz;
tz.tz_minuteswest = 0;
tz.tz_dsttime = 0;
gettimeofday(&tv, &tz);
seconds = tv.tv_sec + kNtpJan1970;
dtemp = tv.tv_usec / 1e6;
if (dtemp >= 1) {
dtemp -= 1;
seconds++;
} else if (dtemp < -1) {
dtemp += 1;
seconds--;
}
dtemp *= kMagicNtpFractionalUnit;
fractions = (WebRtc_UWord32)dtemp;
}
};
#endif
#if defined(_WIN32)
// Keeps the global state for the Windows implementation of RtpRtcpClock.
// Note that this is a POD. Only PODs are allowed to have static storage
// duration according to the Google Style guide.
static WindowsHelpTimer global_help_timer = {0, 0, {{ 0, 0}, 0}, 0};
#endif
Clock* Clock::GetRealTimeClock() {
#if defined(_WIN32)
return new WindowsRealTimeClock(&global_help_timer);
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
return new UnixRealTimeClock();
#else
return NULL;
#endif
}
SimulatedClock::SimulatedClock() : time_us_(0) {}
SimulatedClock::SimulatedClock(int64_t initial_time_us)
: time_us_(initial_time_us) {}
int64_t SimulatedClock::TimeInMilliseconds() {
return (time_us_ + 500) / 1000;
}
int64_t SimulatedClock::TimeInMicroseconds() {
return time_us_;
}
void SimulatedClock::CurrentNtp(uint32_t& seconds, uint32_t& fractions) {
seconds = (TimeInMilliseconds() / 1000) + kNtpJan1970;
fractions = (uint32_t)((TimeInMilliseconds() % 1000) *
kMagicNtpFractionalUnit / 1000);
}
void SimulatedClock::AdvanceTimeMs(int64_t milliseconds) {
AdvanceTimeUs(1000 * milliseconds);
}
void SimulatedClock::AdvanceTimeUs(int64_t microseconds) {
time_us_ += microseconds;
}
}; // namespace webrtc

View File

@ -24,6 +24,7 @@
'sources': [ 'sources': [
'../interface/aligned_malloc.h', '../interface/aligned_malloc.h',
'../interface/atomic32.h', '../interface/atomic32.h',
'../interface/clock.h',
'../interface/compile_assert.h', '../interface/compile_assert.h',
'../interface/condition_variable_wrapper.h', '../interface/condition_variable_wrapper.h',
'../interface/cpu_info.h', '../interface/cpu_info.h',
@ -55,6 +56,7 @@
'atomic32_mac.cc', 'atomic32_mac.cc',
'atomic32_posix.cc', 'atomic32_posix.cc',
'atomic32_win.cc', 'atomic32_win.cc',
'clock.cc',
'condition_variable.cc', 'condition_variable.cc',
'condition_variable_posix.cc', 'condition_variable_posix.cc',
'condition_variable_posix.h', 'condition_variable_posix.h',