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:
parent
3b7feb2a5d
commit
20ed36dada
@ -55,7 +55,7 @@ class RtpRtcp : public Module {
|
||||
*/
|
||||
int32_t id;
|
||||
bool audio;
|
||||
RtpRtcpClock* clock;
|
||||
Clock* clock;
|
||||
RtpRtcp* default_module;
|
||||
RtpData* incoming_data;
|
||||
RtpFeedback* incoming_messages;
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "module_common_types.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
@ -255,20 +256,6 @@ class 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.
|
||||
class NullRtpFeedback : public RtpFeedback {
|
||||
public:
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
Bitrate::Bitrate(RtpRtcpClock* clock)
|
||||
Bitrate::Bitrate(Clock* clock)
|
||||
: clock_(*clock),
|
||||
packet_rate_(0),
|
||||
bitrate_(0),
|
||||
@ -41,7 +41,7 @@ WebRtc_UWord32 Bitrate::BitrateLast() 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_;
|
||||
|
||||
if (diff_ms > 10000) { // 10 seconds.
|
||||
@ -59,7 +59,7 @@ WebRtc_UWord32 Bitrate::BitrateNow() const {
|
||||
|
||||
void Bitrate::Process() {
|
||||
// Triggered by timer.
|
||||
WebRtc_Word64 now = clock_.GetTimeInMS();
|
||||
WebRtc_Word64 now = clock_.TimeInMilliseconds();
|
||||
WebRtc_Word64 diff_ms = now - time_last_rate_update_;
|
||||
|
||||
if (diff_ms < 100) {
|
||||
|
@ -20,11 +20,11 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtpRtcpClock;
|
||||
class Clock;
|
||||
|
||||
class Bitrate {
|
||||
public:
|
||||
explicit Bitrate(RtpRtcpClock* clock);
|
||||
explicit Bitrate(Clock* clock);
|
||||
|
||||
// Calculates rates.
|
||||
void Process();
|
||||
@ -42,7 +42,7 @@ class Bitrate {
|
||||
WebRtc_UWord32 BitrateNow() const;
|
||||
|
||||
protected:
|
||||
RtpRtcpClock& clock_;
|
||||
Clock& clock_;
|
||||
|
||||
private:
|
||||
WebRtc_UWord32 packet_rate_;
|
||||
|
@ -69,7 +69,7 @@ class RtcpFormatRembTest : public ::testing::Test {
|
||||
virtual void TearDown();
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
RtpRtcpClock* system_clock_;
|
||||
Clock* system_clock_;
|
||||
ModuleRtpRtcpImpl* dummy_rtp_rtcp_impl_;
|
||||
RTCPSender* rtcp_sender_;
|
||||
RTCPReceiver* rtcp_receiver_;
|
||||
@ -79,7 +79,7 @@ class RtcpFormatRembTest : public ::testing::Test {
|
||||
};
|
||||
|
||||
void RtcpFormatRembTest::SetUp() {
|
||||
system_clock_ = ModuleRTPUtility::GetSystemClock();
|
||||
system_clock_ = Clock::GetRealTimeClock();
|
||||
RtpRtcp::Configuration configuration;
|
||||
configuration.id = 0;
|
||||
configuration.audio = false;
|
||||
|
@ -30,7 +30,7 @@ using namespace RTCPHelp;
|
||||
// The number of RTCP time intervals needed to trigger a timeout.
|
||||
const int kRrTimeoutIntervals = 3;
|
||||
|
||||
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock,
|
||||
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, Clock* clock,
|
||||
ModuleRtpRtcpImpl* owner)
|
||||
: TMMBRHelp(),
|
||||
_id(id),
|
||||
@ -285,7 +285,7 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
|
||||
{
|
||||
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
|
||||
|
||||
_lastReceived = _clock.GetTimeInMS();
|
||||
_lastReceived = _clock.TimeInMilliseconds();
|
||||
|
||||
RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
|
||||
while (pktType != RTCPUtility::kRtcpNotValidCode)
|
||||
@ -406,7 +406,7 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
|
||||
_remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
|
||||
_remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
|
||||
|
||||
_clock.CurrentNTP(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
|
||||
_clock.CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -466,7 +466,7 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
|
||||
return;
|
||||
}
|
||||
|
||||
_lastReceivedRrMs = _clock.GetTimeInMS();
|
||||
_lastReceivedRrMs = _clock.TimeInMilliseconds();
|
||||
const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
|
||||
reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
|
||||
reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
|
||||
@ -496,7 +496,7 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
|
||||
WebRtc_UWord32 lastReceivedRRNTPsecs = 0;
|
||||
WebRtc_UWord32 lastReceivedRRNTPfrac = 0;
|
||||
|
||||
_clock.CurrentNTP(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
|
||||
_clock.CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
|
||||
|
||||
// time when we received this in MS
|
||||
WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS(
|
||||
@ -641,7 +641,7 @@ RTCPReceiver::GetReceiveInformation(WebRtc_UWord32 remoteSSRC) {
|
||||
void RTCPReceiver::UpdateReceiveInformation(
|
||||
RTCPReceiveInformation& receiveInformation) {
|
||||
// Update that this remote is alive
|
||||
receiveInformation.lastTimeReceived = _clock.GetTimeInMS();
|
||||
receiveInformation.lastTimeReceived = _clock.TimeInMilliseconds();
|
||||
}
|
||||
|
||||
bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
|
||||
@ -650,7 +650,7 @@ bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
|
||||
return false;
|
||||
|
||||
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.
|
||||
_lastReceivedRrMs = 0;
|
||||
return true;
|
||||
@ -664,7 +664,8 @@ bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
|
||||
return false;
|
||||
|
||||
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.
|
||||
_lastIncreasedSequenceNumberMs = 0;
|
||||
return true;
|
||||
@ -676,7 +677,7 @@ bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
|
||||
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
|
||||
|
||||
bool updateBoundingSet = false;
|
||||
WebRtc_Word64 timeNow = _clock.GetTimeInMS();
|
||||
WebRtc_Word64 timeNow = _clock.TimeInMilliseconds();
|
||||
|
||||
std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
|
||||
_receivedInfoMap.begin();
|
||||
@ -961,7 +962,7 @@ RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
|
||||
rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
|
||||
{
|
||||
receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
|
||||
_clock.GetTimeInMS());
|
||||
_clock.TimeInMilliseconds());
|
||||
rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
|
||||
}
|
||||
}
|
||||
@ -1149,7 +1150,7 @@ void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
|
||||
// check if we have reported this FIRSequenceNumber before
|
||||
if (rtcpPacket.FIRItem.CommandSequenceNumber !=
|
||||
receiveInfo->lastFIRSequenceNumber) {
|
||||
WebRtc_Word64 now = _clock.GetTimeInMS();
|
||||
WebRtc_Word64 now = _clock.TimeInMilliseconds();
|
||||
// sanity; don't go crazy with the callbacks
|
||||
if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
|
||||
receiveInfo->lastFIRRequest = now;
|
||||
@ -1307,7 +1308,7 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
|
||||
if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
|
||||
rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
|
||||
rtcpPacketInformation.reportBlock) {
|
||||
WebRtc_Word64 now = _clock.GetTimeInMS();
|
||||
WebRtc_Word64 now = _clock.TimeInMilliseconds();
|
||||
_cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
|
||||
rtcpPacketInformation.remoteSSRC,
|
||||
rtcpPacketInformation.fractionLost,
|
||||
@ -1377,7 +1378,7 @@ WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
|
||||
for (WebRtc_UWord32 i = 0;
|
||||
(num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
|
||||
if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
|
||||
_clock.GetTimeInMS()) == 0) {
|
||||
_clock.TimeInMilliseconds()) == 0) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
@ -1424,7 +1425,7 @@ void RTCPReceiver::PacketTimeout()
|
||||
return;
|
||||
}
|
||||
|
||||
WebRtc_Word64 now = _clock.GetTimeInMS();
|
||||
WebRtc_Word64 now = _clock.TimeInMilliseconds();
|
||||
if(now - _lastReceived > _packetTimeOutMS)
|
||||
{
|
||||
packetTimeOut = true;
|
||||
|
@ -27,7 +27,7 @@ class ModuleRtpRtcpImpl;
|
||||
class RTCPReceiver : public TMMBRHelp
|
||||
{
|
||||
public:
|
||||
RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock,
|
||||
RTCPReceiver(const WebRtc_Word32 id, Clock* clock,
|
||||
ModuleRtpRtcpImpl* owner);
|
||||
virtual ~RTCPReceiver();
|
||||
|
||||
@ -198,7 +198,7 @@ protected:
|
||||
|
||||
private:
|
||||
WebRtc_Word32 _id;
|
||||
RtpRtcpClock& _clock;
|
||||
Clock& _clock;
|
||||
RTCPMethod _method;
|
||||
WebRtc_Word64 _lastReceived;
|
||||
ModuleRtpRtcpImpl& _rtpRtcp;
|
||||
|
@ -134,34 +134,6 @@ class PacketBuilder {
|
||||
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.
|
||||
class TestTransport : public Transport,
|
||||
public RtpData {
|
||||
@ -202,8 +174,7 @@ class RtcpReceiverTest : public ::testing::Test {
|
||||
&remote_bitrate_observer_,
|
||||
over_use_detector_options_,
|
||||
RemoteBitrateEstimator::kMultiStreamEstimation)) {
|
||||
// system_clock_ = ModuleRTPUtility::GetSystemClock();
|
||||
system_clock_ = new FakeSystemClock();
|
||||
system_clock_ = new SimulatedClock(1335900000);
|
||||
test_transport_ = new TestTransport();
|
||||
|
||||
RtpRtcp::Configuration configuration;
|
||||
@ -239,7 +210,7 @@ class RtcpReceiverTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
FakeSystemClock* system_clock_;
|
||||
SimulatedClock* system_clock_;
|
||||
ModuleRtpRtcpImpl* rtp_rtcp_impl_;
|
||||
RTCPReceiver* rtcp_receiver_;
|
||||
TestTransport* test_transport_;
|
||||
@ -275,7 +246,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
|
||||
rtcp_receiver_->SetSSRC(kSourceSsrc);
|
||||
|
||||
uint32_t sequence_number = 1234;
|
||||
system_clock_->AdvanceClock(3 * kRtcpIntervalMs);
|
||||
system_clock_->AdvanceTimeMs(3 * kRtcpIntervalMs);
|
||||
|
||||
// No RR received, shouldn't trigger a timeout.
|
||||
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
|
||||
@ -285,7 +256,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
|
||||
PacketBuilder p1;
|
||||
p1.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
|
||||
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_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
|
||||
|
||||
@ -294,12 +265,12 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
|
||||
PacketBuilder p2;
|
||||
p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
|
||||
EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length()));
|
||||
system_clock_->AdvanceClock(2);
|
||||
system_clock_->AdvanceTimeMs(2);
|
||||
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
|
||||
EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
|
||||
|
||||
// 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));
|
||||
|
||||
// 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));
|
||||
|
||||
// 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;
|
||||
p4.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
|
||||
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_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
|
||||
system_clock_->AdvanceClock(2 * kRtcpIntervalMs);
|
||||
system_clock_->AdvanceTimeMs(2 * 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.
|
||||
|
||||
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.
|
||||
EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
|
||||
@ -425,7 +396,7 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
|
||||
EXPECT_LT(0U, candidate_set.Tmmbr(0));
|
||||
// We expect the timeout to be 25 seconds. Advance the clock by 12
|
||||
// seconds, timing out the first packet.
|
||||
system_clock_->AdvanceClock(12000);
|
||||
system_clock_->AdvanceTimeMs(12000);
|
||||
// Odd behaviour: Just counting them does not trigger the timeout.
|
||||
EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
|
||||
// Odd behaviour: There's only one left after timeout, not 2.
|
||||
|
@ -25,7 +25,7 @@ using RTCPUtility::RTCPCnameInformation;
|
||||
|
||||
RTCPSender::RTCPSender(const WebRtc_Word32 id,
|
||||
const bool audio,
|
||||
RtpRtcpClock* clock,
|
||||
Clock* clock,
|
||||
ModuleRtpRtcpImpl* owner) :
|
||||
_id(id),
|
||||
_audio(audio),
|
||||
@ -183,10 +183,12 @@ RTCPSender::SetRTCPStatus(const RTCPMethod method)
|
||||
{
|
||||
if(_audio)
|
||||
{
|
||||
_nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_AUDIO_MS/2);
|
||||
_nextTimeToSendRTCP = _clock.TimeInMilliseconds() +
|
||||
(RTCP_INTERVAL_AUDIO_MS/2);
|
||||
} else
|
||||
{
|
||||
_nextTimeToSendRTCP = _clock.GetTimeInMS() + (RTCP_INTERVAL_VIDEO_MS/2);
|
||||
_nextTimeToSendRTCP = _clock.TimeInMilliseconds() +
|
||||
(RTCP_INTERVAL_VIDEO_MS/2);
|
||||
}
|
||||
}
|
||||
_method = method;
|
||||
@ -302,7 +304,7 @@ void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
|
||||
last_rtp_timestamp_ = rtp_timestamp;
|
||||
if (capture_time_ms < 0) {
|
||||
// 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 {
|
||||
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
|
||||
// schedule a new RTCP report
|
||||
// make sure that we send a RTP packet
|
||||
_nextTimeToSendRTCP = _clock.GetTimeInMS() + 100;
|
||||
_nextTimeToSendRTCP = _clock.TimeInMilliseconds() + 100;
|
||||
}
|
||||
_SSRC = ssrc;
|
||||
}
|
||||
@ -449,7 +451,7 @@ From RFC 3550
|
||||
a value of the RTCP bandwidth below the intended average
|
||||
*/
|
||||
|
||||
WebRtc_Word64 now = _clock.GetTimeInMS();
|
||||
WebRtc_Word64 now = _clock.TimeInMilliseconds();
|
||||
|
||||
CriticalSectionScoped lock(_criticalSectionRTCPSender);
|
||||
|
||||
@ -587,8 +589,9 @@ RTCPSender::BuildSR(WebRtc_UWord8* rtcpbuffer,
|
||||
// the frame being captured at this moment. We are calculating that
|
||||
// timestamp as the last frame's timestamp + the time since the last frame
|
||||
// was captured.
|
||||
RTPtime = start_timestamp_ + last_rtp_timestamp_ + (_clock.GetTimeInMS() -
|
||||
last_frame_capture_time_ms_) * (freqHz / 1000);
|
||||
RTPtime = start_timestamp_ + last_rtp_timestamp_ + (
|
||||
_clock.TimeInMilliseconds() - last_frame_capture_time_ms_) *
|
||||
(freqHz / 1000);
|
||||
|
||||
// Add sender data
|
||||
// Save for our length field
|
||||
@ -1577,7 +1580,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
|
||||
remoteSR);
|
||||
|
||||
// get our NTP as late as possible to avoid a race
|
||||
_clock.CurrentNTP(NTPsec, NTPfrac);
|
||||
_clock.CurrentNtp(NTPsec, NTPfrac);
|
||||
|
||||
// Delay since last received report
|
||||
WebRtc_UWord32 delaySinceLastReceivedSR = 0;
|
||||
@ -1599,7 +1602,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags,
|
||||
} else
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
_nextTimeToSendRTCP = _clock.GetTimeInMS() + timeToNext;
|
||||
_nextTimeToSendRTCP = _clock.TimeInMilliseconds() + timeToNext;
|
||||
}
|
||||
|
||||
// if the data does not fitt in the packet we fill it as much as possible
|
||||
|
@ -30,7 +30,7 @@ class RTCPSender
|
||||
{
|
||||
public:
|
||||
RTCPSender(const WebRtc_Word32 id, const bool audio,
|
||||
RtpRtcpClock* clock, ModuleRtpRtcpImpl* owner);
|
||||
Clock* clock, ModuleRtpRtcpImpl* owner);
|
||||
virtual ~RTCPSender();
|
||||
|
||||
void ChangeUniqueId(const WebRtc_Word32 id);
|
||||
@ -186,7 +186,7 @@ private:
|
||||
private:
|
||||
WebRtc_Word32 _id;
|
||||
const bool _audio;
|
||||
RtpRtcpClock& _clock;
|
||||
Clock& _clock;
|
||||
RTCPMethod _method;
|
||||
|
||||
ModuleRtpRtcpImpl& _rtpRtcp;
|
||||
|
@ -105,7 +105,7 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
&remote_bitrate_observer_,
|
||||
over_use_detector_options_,
|
||||
RemoteBitrateEstimator::kMultiStreamEstimation)) {
|
||||
system_clock_ = ModuleRTPUtility::GetSystemClock();
|
||||
system_clock_ = Clock::GetRealTimeClock();
|
||||
test_transport_ = new TestTransport();
|
||||
|
||||
RtpRtcp::Configuration configuration;
|
||||
@ -139,7 +139,7 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
RtpRtcpClock* system_clock_;
|
||||
Clock* system_clock_;
|
||||
ModuleRtpRtcpImpl* rtp_rtcp_impl_;
|
||||
RTCPSender* rtcp_sender_;
|
||||
RTCPReceiver* rtcp_receiver_;
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
RTPPacketHistory::RTPPacketHistory(RtpRtcpClock* clock)
|
||||
RTPPacketHistory::RTPPacketHistory(Clock* clock)
|
||||
: clock_(*clock),
|
||||
critsect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
store_(false),
|
||||
@ -140,7 +140,7 @@ int32_t RTPPacketHistory::PutRTPPacket(const uint8_t* packet,
|
||||
stored_seq_nums_[prev_index_] = seq_num;
|
||||
stored_lengths_[prev_index_] = packet_length;
|
||||
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_types_[prev_index_] = type;
|
||||
|
||||
@ -244,7 +244,7 @@ bool RTPPacketHistory::GetRTPPacket(uint16_t sequence_number,
|
||||
}
|
||||
|
||||
// Verify elapsed time since last retrieve.
|
||||
int64_t now = clock_.GetTimeInMS();
|
||||
int64_t now = clock_.TimeInMilliseconds();
|
||||
if (min_elapsed_time_ms > 0 &&
|
||||
((now - stored_resend_times_.at(index)) < min_elapsed_time_ms)) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
stored_resend_times_[index] = clock_.GetTimeInMS();
|
||||
stored_resend_times_[index] = clock_.TimeInMilliseconds();
|
||||
}
|
||||
|
||||
// private, lock should already be taken
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RtpRtcpClock;
|
||||
class Clock;
|
||||
class CriticalSectionWrapper;
|
||||
|
||||
class RTPPacketHistory {
|
||||
public:
|
||||
RTPPacketHistory(RtpRtcpClock* clock);
|
||||
RTPPacketHistory(Clock* clock);
|
||||
~RTPPacketHistory();
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
RtpRtcpClock& clock_;
|
||||
Clock& clock_;
|
||||
CriticalSectionWrapper* critsect_;
|
||||
bool store_;
|
||||
uint32_t prev_index_;
|
||||
|
@ -18,18 +18,23 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class FakeClock : public RtpRtcpClock {
|
||||
class FakeClock : public Clock {
|
||||
public:
|
||||
FakeClock() {
|
||||
time_in_ms_ = 123456;
|
||||
}
|
||||
// Return a timestamp in milliseconds relative to some arbitrary
|
||||
// source; the source is fixed for this clock.
|
||||
virtual WebRtc_Word64 GetTimeInMS() {
|
||||
virtual WebRtc_Word64 TimeInMilliseconds() {
|
||||
return time_in_ms_;
|
||||
}
|
||||
|
||||
virtual WebRtc_Word64 TimeInMicroseconds() {
|
||||
return time_in_ms_ * 1000;
|
||||
}
|
||||
|
||||
// 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;
|
||||
frac = (time_in_ms_ % 1000) * 4294967;
|
||||
}
|
||||
@ -87,7 +92,7 @@ TEST_F(RtpPacketHistoryTest, SetStoreStatus) {
|
||||
TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
|
||||
EXPECT_FALSE(hist_->StorePackets());
|
||||
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);
|
||||
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
|
||||
capture_time_ms, kAllowRetransmission));
|
||||
@ -101,7 +106,7 @@ TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
|
||||
TEST_F(RtpPacketHistoryTest, DontStore) {
|
||||
hist_->SetStorePacketsStatus(true, 10);
|
||||
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);
|
||||
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
|
||||
capture_time_ms, kDontStore));
|
||||
@ -115,7 +120,7 @@ TEST_F(RtpPacketHistoryTest, DontStore) {
|
||||
|
||||
TEST_F(RtpPacketHistoryTest, PutRtpPacket_TooLargePacketLength) {
|
||||
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_,
|
||||
kMaxPacketLength + 1,
|
||||
kMaxPacketLength,
|
||||
@ -126,7 +131,7 @@ TEST_F(RtpPacketHistoryTest, PutRtpPacket_TooLargePacketLength) {
|
||||
TEST_F(RtpPacketHistoryTest, GetRtpPacket_TooSmallBuffer) {
|
||||
hist_->SetStorePacketsStatus(true, 10);
|
||||
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);
|
||||
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
|
||||
capture_time_ms, kAllowRetransmission));
|
||||
@ -151,7 +156,7 @@ TEST_F(RtpPacketHistoryTest, PutRtpPacket) {
|
||||
CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
|
||||
|
||||
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,
|
||||
capture_time_ms, kAllowRetransmission));
|
||||
EXPECT_TRUE(hist_->HasRTPPacket(kSeqNum));
|
||||
@ -220,7 +225,7 @@ TEST_F(RtpPacketHistoryTest, NoCaptureTime) {
|
||||
hist_->SetStorePacketsStatus(true, 10);
|
||||
uint16_t len = 0;
|
||||
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);
|
||||
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
|
||||
-1, kAllowRetransmission));
|
||||
@ -241,7 +246,7 @@ TEST_F(RtpPacketHistoryTest, NoCaptureTime) {
|
||||
TEST_F(RtpPacketHistoryTest, DontRetransmit) {
|
||||
hist_->SetStorePacketsStatus(true, 10);
|
||||
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);
|
||||
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
|
||||
capture_time_ms, kDontRetransmit));
|
||||
@ -259,7 +264,7 @@ TEST_F(RtpPacketHistoryTest, DontRetransmit) {
|
||||
TEST_F(RtpPacketHistoryTest, MinResendTime) {
|
||||
hist_->SetStorePacketsStatus(true, 10);
|
||||
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);
|
||||
EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, kMaxPacketLength,
|
||||
capture_time_ms, kAllowRetransmission));
|
||||
|
@ -33,7 +33,7 @@ using ModuleRTPUtility::VideoPayload;
|
||||
|
||||
RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
|
||||
const bool audio,
|
||||
RtpRtcpClock* clock,
|
||||
Clock* clock,
|
||||
ModuleRtpRtcpImpl* owner,
|
||||
RtpAudioFeedback* incoming_audio_messages_callback,
|
||||
RtpData* incoming_payload_callback,
|
||||
@ -178,7 +178,7 @@ void RTPReceiver::PacketTimeout() {
|
||||
return;
|
||||
}
|
||||
|
||||
WebRtc_Word64 now = clock_.GetTimeInMS();
|
||||
WebRtc_Word64 now = clock_.TimeInMilliseconds();
|
||||
|
||||
if (now - last_receive_time_ > packet_timeout_ms_) {
|
||||
packet_time_out = true;
|
||||
@ -628,7 +628,7 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket(
|
||||
|
||||
WebRtc_Word32 ret_val = rtp_media_receiver_->ParseRtpPacket(
|
||||
rtp_header, specific_payload, is_red, packet,
|
||||
packet_length, clock_.GetTimeInMS());
|
||||
packet_length, clock_.TimeInMilliseconds());
|
||||
|
||||
if (ret_val < 0) {
|
||||
return ret_val;
|
||||
@ -646,13 +646,13 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket(
|
||||
|
||||
// Need to be updated after RetransmitOfOldPacket and
|
||||
// RetransmitOfOldPacketUpdateStatistics.
|
||||
last_receive_time_ = clock_.GetTimeInMS();
|
||||
last_receive_time_ = clock_.TimeInMilliseconds();
|
||||
last_received_payload_length_ = payload_data_length;
|
||||
|
||||
if (!old_packet) {
|
||||
if (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_transmission_time_offset_ =
|
||||
@ -760,7 +760,7 @@ bool RTPReceiver::RetransmitOfOldPacket(
|
||||
}
|
||||
|
||||
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.
|
||||
WebRtc_Word32 rtp_time_stamp_diff_ms =
|
||||
|
@ -36,7 +36,7 @@ class RTPReceiver : public Bitrate {
|
||||
// want callbacks to do nothing).
|
||||
RTPReceiver(const WebRtc_Word32 id,
|
||||
const bool audio,
|
||||
RtpRtcpClock* clock,
|
||||
Clock* clock,
|
||||
ModuleRtpRtcpImpl* owner,
|
||||
RtpAudioFeedback* incoming_audio_messages_callback,
|
||||
RtpData* incoming_payload_callback,
|
||||
|
@ -80,7 +80,7 @@ RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
|
||||
RtpRtcp::Configuration configuration_copy;
|
||||
memcpy(&configuration_copy, &configuration,
|
||||
sizeof(RtpRtcp::Configuration));
|
||||
configuration_copy.clock = ModuleRTPUtility::GetSystemClock();
|
||||
configuration_copy.clock = Clock::GetRealTimeClock();
|
||||
ModuleRtpRtcpImpl* rtp_rtcp_instance =
|
||||
new ModuleRtpRtcpImpl(configuration_copy);
|
||||
rtp_rtcp_instance->OwnsClock();
|
||||
@ -107,9 +107,10 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
|
||||
id_(configuration.id),
|
||||
audio_(configuration.audio),
|
||||
collision_detected_(false),
|
||||
last_process_time_(configuration.clock->GetTimeInMS()),
|
||||
last_bitrate_process_time_(configuration.clock->GetTimeInMS()),
|
||||
last_packet_timeout_process_time_(configuration.clock->GetTimeInMS()),
|
||||
last_process_time_(configuration.clock->TimeInMilliseconds()),
|
||||
last_bitrate_process_time_(configuration.clock->TimeInMilliseconds()),
|
||||
last_packet_timeout_process_time_(
|
||||
configuration.clock->TimeInMilliseconds()),
|
||||
packet_overhead_(28), // IPV4 UDP.
|
||||
critical_section_module_ptrs_(
|
||||
CriticalSectionWrapper::CreateCriticalSection()),
|
||||
@ -216,13 +217,13 @@ void ModuleRtpRtcpImpl::DeRegisterChildModule(RtpRtcp* remove_module) {
|
||||
// Returns the number of milliseconds until the module want a worker thread
|
||||
// to call Process.
|
||||
WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess() {
|
||||
const WebRtc_Word64 now = clock_.GetTimeInMS();
|
||||
const WebRtc_Word64 now = clock_.TimeInMilliseconds();
|
||||
return kRtpRtcpMaxIdleTimeProcess - (now - last_process_time_);
|
||||
}
|
||||
|
||||
// Process any pending tasks such as timeouts (non time critical events).
|
||||
WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
|
||||
const WebRtc_Word64 now = clock_.GetTimeInMS();
|
||||
const WebRtc_Word64 now = clock_.TimeInMilliseconds();
|
||||
last_process_time_ = now;
|
||||
|
||||
if (now >=
|
||||
@ -304,7 +305,7 @@ WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
|
||||
|
||||
void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
|
||||
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_) {
|
||||
// RTCP is alive if we have received a report the last 12 seconds.
|
||||
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_timeout_ms_ = sample_time_seconds * 1000;
|
||||
// Trigger the first after one period.
|
||||
dead_or_alive_last_timer_ = clock_.GetTimeInMS();
|
||||
dead_or_alive_last_timer_ = clock_.TimeInMilliseconds();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1519,7 +1520,7 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SendNACK(const WebRtc_UWord16* nack_list,
|
||||
if (wait_time == 5) {
|
||||
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;
|
||||
WebRtc_UWord16 nackLength = size;
|
||||
WebRtc_UWord16 start_id = 0;
|
||||
|
@ -484,7 +484,7 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
|
||||
RTCPReceiver rtcp_receiver_;
|
||||
|
||||
bool owns_clock_;
|
||||
RtpRtcpClock& clock_;
|
||||
Clock& clock_;
|
||||
|
||||
private:
|
||||
int64_t RtcpReportInterval();
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace webrtc {
|
||||
RTPSender::RTPSender(const WebRtc_Word32 id,
|
||||
const bool audio,
|
||||
RtpRtcpClock* clock,
|
||||
Clock* clock,
|
||||
Transport* transport,
|
||||
RtpAudioFeedback* audio_feedback,
|
||||
PacedSender* paced_sender)
|
||||
@ -75,7 +75,7 @@ RTPSender::RTPSender(const WebRtc_Word32 id,
|
||||
memset(_nackByteCount, 0, sizeof(_nackByteCount));
|
||||
memset(_CSRC, 0, sizeof(_CSRC));
|
||||
// We need to seed the random generator.
|
||||
srand( (WebRtc_UWord32)clock_.GetTimeInMS() );
|
||||
srand( (WebRtc_UWord32)clock_.TimeInMilliseconds() );
|
||||
_ssrc = _ssrcDB.CreateSSRC(); // Can't be 0.
|
||||
|
||||
if (audio) {
|
||||
@ -576,7 +576,7 @@ int RTPSender::SetSelectiveRetransmissions(uint8_t settings) {
|
||||
void RTPSender::OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength,
|
||||
const WebRtc_UWord16* nackSequenceNumbers,
|
||||
const WebRtc_UWord16 avgRTT) {
|
||||
const WebRtc_Word64 now = clock_.GetTimeInMS();
|
||||
const WebRtc_Word64 now = clock_.TimeInMilliseconds();
|
||||
WebRtc_UWord32 bytesReSent = 0;
|
||||
|
||||
// Enough bandwidth to send NACK?
|
||||
@ -700,7 +700,7 @@ void RTPSender::TimeToSendPacket(uint16_t sequence_number,
|
||||
WebRtcRTPHeader 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)) {
|
||||
// Update stored packet in case of receiving a re-transmission request.
|
||||
_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
|
||||
// time is consider invalid, while 0 is considered a valid time.
|
||||
if (capture_time_ms > 0) {
|
||||
int64_t time_now = clock_.GetTimeInMS();
|
||||
int64_t time_now = clock_.TimeInMilliseconds();
|
||||
UpdateTransmissionTimeOffset(buffer, payload_length + rtp_header_length,
|
||||
rtp_header, time_now - capture_time_ms);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class RTPSender : public Bitrate, public RTPSenderInterface {
|
||||
public:
|
||||
RTPSender(const WebRtc_Word32 id,
|
||||
const bool audio,
|
||||
RtpRtcpClock* clock,
|
||||
Clock* clock,
|
||||
Transport* transport,
|
||||
RtpAudioFeedback* audio_feedback,
|
||||
PacedSender* paced_sender);
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <cassert> //assert
|
||||
|
||||
namespace webrtc {
|
||||
RTPSenderAudio::RTPSenderAudio(const WebRtc_Word32 id, RtpRtcpClock* clock,
|
||||
RTPSenderAudio::RTPSenderAudio(const WebRtc_Word32 id, Clock* clock,
|
||||
RTPSenderInterface* rtpSender) :
|
||||
_id(id),
|
||||
_clock(*clock),
|
||||
@ -217,7 +217,8 @@ RTPSenderAudio::SendTelephoneEventActive(WebRtc_Word8& telephoneEvent) const
|
||||
telephoneEvent = _dtmfKey;
|
||||
return true;
|
||||
}
|
||||
WebRtc_Word64 delaySinceLastDTMF = _clock.GetTimeInMS() - _dtmfTimeLastSent;
|
||||
WebRtc_Word64 delaySinceLastDTMF = _clock.TimeInMilliseconds() -
|
||||
_dtmfTimeLastSent;
|
||||
if(delaySinceLastDTMF < 100)
|
||||
{
|
||||
telephoneEvent = _dtmfKey;
|
||||
@ -245,7 +246,8 @@ WebRtc_Word32 RTPSenderAudio::SendAudio(
|
||||
if (!_dtmfEventIsOn && PendingDTMF()) {
|
||||
CriticalSectionScoped cs(_sendAudioCritsect);
|
||||
|
||||
WebRtc_Word64 delaySinceLastDTMF = _clock.GetTimeInMS() - _dtmfTimeLastSent;
|
||||
WebRtc_Word64 delaySinceLastDTMF = _clock.TimeInMilliseconds() -
|
||||
_dtmfTimeLastSent;
|
||||
|
||||
if (delaySinceLastDTMF > 100) {
|
||||
// New tone to play
|
||||
@ -295,7 +297,7 @@ WebRtc_Word32 RTPSenderAudio::SendAudio(
|
||||
} else {
|
||||
ended = true;
|
||||
_dtmfEventIsOn = false;
|
||||
_dtmfTimeLastSent = _clock.GetTimeInMS();
|
||||
_dtmfTimeLastSent = _clock.TimeInMilliseconds();
|
||||
}
|
||||
// don't hold the critsect while calling SendTelephoneEventPacket
|
||||
_sendAudioCritsect->Leave();
|
||||
|
@ -24,7 +24,7 @@ namespace webrtc {
|
||||
class RTPSenderAudio: public DTMFqueue
|
||||
{
|
||||
public:
|
||||
RTPSenderAudio(const WebRtc_Word32 id, RtpRtcpClock* clock,
|
||||
RTPSenderAudio(const WebRtc_Word32 id, Clock* clock,
|
||||
RTPSenderInterface* rtpSender);
|
||||
virtual ~RTPSenderAudio();
|
||||
|
||||
@ -89,10 +89,10 @@ protected:
|
||||
|
||||
private:
|
||||
WebRtc_Word32 _id;
|
||||
RtpRtcpClock& _clock;
|
||||
RTPSenderInterface* _rtpSender;
|
||||
CriticalSectionWrapper* _audioFeedbackCritsect;
|
||||
RtpAudioFeedback* _audioFeedback;
|
||||
Clock& _clock;
|
||||
RTPSenderInterface* _rtpSender;
|
||||
CriticalSectionWrapper* _audioFeedbackCritsect;
|
||||
RtpAudioFeedback* _audioFeedback;
|
||||
|
||||
CriticalSectionWrapper* _sendAudioCritsect;
|
||||
|
||||
|
@ -33,18 +33,23 @@ const int kTimeOffset = 22222;
|
||||
const int kMaxPacketLength = 1500;
|
||||
} // namespace
|
||||
|
||||
class FakeClockTest : public RtpRtcpClock {
|
||||
class FakeClockTest : public Clock {
|
||||
public:
|
||||
FakeClockTest() {
|
||||
time_in_ms_ = 123456;
|
||||
}
|
||||
// Return a timestamp in milliseconds relative to some arbitrary
|
||||
// source; the source is fixed for this clock.
|
||||
virtual WebRtc_Word64 GetTimeInMS() {
|
||||
virtual WebRtc_Word64 TimeInMilliseconds() {
|
||||
return time_in_ms_;
|
||||
}
|
||||
|
||||
virtual WebRtc_Word64 TimeInMicroseconds() {
|
||||
return time_in_ms_ * 1000;
|
||||
}
|
||||
|
||||
// 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;
|
||||
frac = (time_in_ms_ % 1000) * 4294967;
|
||||
}
|
||||
@ -223,7 +228,7 @@ TEST_F(RtpSenderTest, DISABLED_TrafficSmoothing) {
|
||||
EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_,
|
||||
0,
|
||||
rtp_length,
|
||||
fake_clock_.GetTimeInMS(),
|
||||
fake_clock_.TimeInMilliseconds(),
|
||||
kAllowRetransmission));
|
||||
EXPECT_EQ(0, transport_.packets_sent_);
|
||||
const int kStoredTimeInMs = 100;
|
||||
|
@ -31,7 +31,7 @@ struct RtpPacket {
|
||||
};
|
||||
|
||||
RTPSenderVideo::RTPSenderVideo(const WebRtc_Word32 id,
|
||||
RtpRtcpClock* clock,
|
||||
Clock* clock,
|
||||
RTPSenderInterface* rtpSender) :
|
||||
_id(id),
|
||||
_rtpSender(*rtpSender),
|
||||
|
@ -33,7 +33,7 @@ struct RtpPacket;
|
||||
class RTPSenderVideo
|
||||
{
|
||||
public:
|
||||
RTPSenderVideo(const WebRtc_Word32 id, RtpRtcpClock* clock,
|
||||
RTPSenderVideo(const WebRtc_Word32 id, Clock* clock,
|
||||
RTPSenderInterface* rtpSender);
|
||||
virtual ~RTPSenderVideo();
|
||||
|
||||
|
@ -49,225 +49,14 @@ namespace ModuleRTPUtility {
|
||||
* Time routines.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
WebRtc_UWord32 GetCurrentRTP(Clock* clock, WebRtc_UWord32 freq) {
|
||||
const bool use_global_clock = (clock == NULL);
|
||||
RtpRtcpClock* local_clock = clock;
|
||||
Clock* local_clock = clock;
|
||||
if (use_global_clock) {
|
||||
local_clock = GetSystemClock();
|
||||
local_clock = Clock::GetRealTimeClock();
|
||||
}
|
||||
WebRtc_UWord32 secs = 0, frac = 0;
|
||||
local_clock->CurrentNTP(secs, frac);
|
||||
local_clock->CurrentNtp(secs, frac);
|
||||
if (use_global_clock) {
|
||||
delete local_clock;
|
||||
}
|
||||
|
@ -61,19 +61,9 @@ namespace ModuleRTPUtility
|
||||
|
||||
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
|
||||
// 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.
|
||||
WebRtc_UWord32 ConvertNTPTimeToRTP(WebRtc_UWord32 NTPsec,
|
||||
|
@ -14,18 +14,21 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class FakeRtpRtcpClock : public RtpRtcpClock {
|
||||
class FakeRtpRtcpClock : public Clock {
|
||||
public:
|
||||
FakeRtpRtcpClock() {
|
||||
time_in_ms_ = 123456;
|
||||
}
|
||||
// Return a timestamp in milliseconds relative to some arbitrary
|
||||
// source; the source is fixed for this clock.
|
||||
virtual WebRtc_Word64 GetTimeInMS() {
|
||||
virtual WebRtc_Word64 TimeInMilliseconds() {
|
||||
return time_in_ms_;
|
||||
}
|
||||
virtual int64_t TimeInMicroseconds() {
|
||||
return time_in_ms_ * 1000;
|
||||
}
|
||||
// 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;
|
||||
frac = (time_in_ms_ % 1000) * 4294967;
|
||||
}
|
||||
|
73
webrtc/system_wrappers/interface/clock.h
Normal file
73
webrtc/system_wrappers/interface/clock.h
Normal 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_
|
257
webrtc/system_wrappers/source/clock.cc
Normal file
257
webrtc/system_wrappers/source/clock.cc
Normal 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
|
@ -24,6 +24,7 @@
|
||||
'sources': [
|
||||
'../interface/aligned_malloc.h',
|
||||
'../interface/atomic32.h',
|
||||
'../interface/clock.h',
|
||||
'../interface/compile_assert.h',
|
||||
'../interface/condition_variable_wrapper.h',
|
||||
'../interface/cpu_info.h',
|
||||
@ -55,6 +56,7 @@
|
||||
'atomic32_mac.cc',
|
||||
'atomic32_posix.cc',
|
||||
'atomic32_win.cc',
|
||||
'clock.cc',
|
||||
'condition_variable.cc',
|
||||
'condition_variable_posix.cc',
|
||||
'condition_variable_posix.h',
|
||||
|
Loading…
Reference in New Issue
Block a user