diff options
-rw-r--r-- | base/time/time.cc | 24 | ||||
-rw-r--r-- | base/time/time.h | 8 | ||||
-rw-r--r-- | media/cast/audio_receiver/audio_receiver_unittest.cc | 5 | ||||
-rw-r--r-- | media/cast/cast_defines.h | 41 | ||||
-rw-r--r-- | media/cast/rtcp/rtcp.cc | 8 | ||||
-rw-r--r-- | media/cast/rtcp/rtcp_unittest.cc | 70 | ||||
-rw-r--r-- | media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc | 3 | ||||
-rw-r--r-- | media/cast/rtp_sender/rtp_sender.cc | 2 | ||||
-rw-r--r-- | media/cast/test/encode_decode_test.cc | 1 | ||||
-rw-r--r-- | media/cast/test/end2end_unittest.cc | 4 |
10 files changed, 107 insertions, 59 deletions
diff --git a/base/time/time.cc b/base/time/time.cc index a9e4b1c..9f3c53d6 100644 --- a/base/time/time.cc +++ b/base/time/time.cc @@ -8,6 +8,7 @@ #include <ostream> #include "base/float_util.h" +#include "base/lazy_instance.h" #include "base/logging.h" #include "base/third_party/nspr/prtime.h" #include "base/third_party/nspr/prtypes.h" @@ -189,6 +190,29 @@ bool Time::FromStringInternal(const char* time_string, return true; } +// Local helper class to hold the conversion from Time to TickTime at the +// time of the Unix epoch. +class UnixEpochSingleton { + public: + UnixEpochSingleton() + : unix_epoch_(TimeTicks::Now() - (Time::Now() - Time::UnixEpoch())) {} + + TimeTicks unix_epoch() const { return unix_epoch_; } + + private: + const TimeTicks unix_epoch_; + + DISALLOW_COPY_AND_ASSIGN(UnixEpochSingleton); +}; + +static LazyInstance<UnixEpochSingleton>::Leaky + leaky_unix_epoch_singleton_instance = LAZY_INSTANCE_INITIALIZER; + +// Static +TimeTicks TimeTicks::UnixEpoch() { + return leaky_unix_epoch_singleton_instance.Get().unix_epoch(); +} + // Time::Exploded ------------------------------------------------------------- inline bool is_in_range(int value, int lo, int hi) { diff --git a/base/time/time.h b/base/time/time.h index 112c14e..5c2cf6e 100644 --- a/base/time/time.h +++ b/base/time/time.h @@ -604,6 +604,14 @@ class BASE_EXPORT TimeTicks { return TimeTicks(ticks); } + // Get the TimeTick value at the time of the UnixEpoch. This is useful when + // you need to relate the value of TimeTicks to a real time and date. + // Note: Upon first invocation, this function takes a snapshot of the realtime + // clock to establish a reference point. This function will return the same + // value for the duration of the application, but will be different in future + // application runs. + static TimeTicks UnixEpoch(); + // Returns the internal numeric value of the TimeTicks object. // For serializing, use FromInternalValue to reconstitute. int64 ToInternalValue() const { diff --git a/media/cast/audio_receiver/audio_receiver_unittest.cc b/media/cast/audio_receiver/audio_receiver_unittest.cc index bb26cb9..cbd90c1 100644 --- a/media/cast/audio_receiver/audio_receiver_unittest.cc +++ b/media/cast/audio_receiver/audio_receiver_unittest.cc @@ -132,7 +132,8 @@ TEST_F(AudioReceiverTest, GetOnePacketEncodedframe) { TEST_F(AudioReceiverTest, MultiplePendingGetCalls) { Configure(true); - EXPECT_CALL(mock_transport_, SendRtcpPacket(testing::_)).Times(2); + EXPECT_CALL(mock_transport_, SendRtcpPacket(testing::_)).WillRepeatedly( + testing::Return(true)); AudioFrameEncodedCallback frame_encoded_callback = base::Bind(&TestAudioEncoderCallback::DeliverEncodedAudioFrame, @@ -154,7 +155,7 @@ TEST_F(AudioReceiverTest, MultiplePendingGetCalls) { uint32 ntp_high; uint32 ntp_low; - ConvertTimeToNtp(testing_clock_.NowTicks(), &ntp_high, &ntp_low); + ConvertTimeTicksToNtp(testing_clock_.NowTicks(), &ntp_high, &ntp_low); rtcp_packet.AddSrWithNtp(audio_config_.feedback_ssrc, ntp_high, ntp_low, rtp_header_.webrtc.header.timestamp); diff --git a/media/cast/cast_defines.h b/media/cast/cast_defines.h index 0778638..f44e5fb 100644 --- a/media/cast/cast_defines.h +++ b/media/cast/cast_defines.h @@ -54,16 +54,15 @@ typedef std::map<uint8, PacketIdSet> MissingFramesAndPacketsMap; // TODO(pwestin): Re-factor the functions bellow into a class with static // methods. +// January 1970, in NTP seconds. +// Network Time Protocol (NTP), which is in seconds relative to 0h UTC on +// 1 January 1900. +static const int64 kUnixEpochInNtpSeconds = GG_INT64_C(2208988800); + // Magic fractional unit. Used to convert time (in microseconds) to/from // fractional NTP seconds. static const double kMagicFractionalUnit = 4.294967296E3; -// Network Time Protocol (NTP), which is in seconds relative to 0h UTC on -// 1 January 1900. -static const int64 kNtpEpochDeltaSeconds = GG_INT64_C(9435484800); -static const int64 kNtpEpochDeltaMicroseconds = - kNtpEpochDeltaSeconds * base::Time::kMicrosecondsPerSecond; - inline bool IsNewerFrameId(uint8 frame_id, uint8 prev_frame_id) { return (frame_id != prev_frame_id) && static_cast<uint8>(frame_id - prev_frame_id) < 0x80; @@ -107,20 +106,28 @@ inline void ConvertTimeToFractions(int64 time_us, (time_us % base::Time::kMicrosecondsPerSecond) * kMagicFractionalUnit); } -inline void ConvertTimeToNtp(const base::TimeTicks& time, - uint32* ntp_seconds, - uint32* ntp_fractions) { - int64 time_us = time.ToInternalValue() - kNtpEpochDeltaMicroseconds; - ConvertTimeToFractions(time_us, ntp_seconds, ntp_fractions); +inline void ConvertTimeTicksToNtp(const base::TimeTicks& time, + uint32* ntp_seconds, + uint32* ntp_fractions) { + base::TimeDelta elapsed_since_unix_epoch = + time - base::TimeTicks::UnixEpoch(); + + int64 ntp_time_us = elapsed_since_unix_epoch.InMicroseconds() + + (kUnixEpochInNtpSeconds * base::Time::kMicrosecondsPerSecond); + + ConvertTimeToFractions(ntp_time_us, ntp_seconds, ntp_fractions); } -inline base::TimeTicks ConvertNtpToTime(uint32 ntp_seconds, - uint32 ntp_fractions) { +inline base::TimeTicks ConvertNtpToTimeTicks(uint32 ntp_seconds, + uint32 ntp_fractions) { int64 ntp_time_us = static_cast<int64>(ntp_seconds) * - base::Time::kMicrosecondsPerSecond; - ntp_time_us += static_cast<int64>(ntp_fractions) / kMagicFractionalUnit; - return base::TimeTicks::FromInternalValue(ntp_time_us + - kNtpEpochDeltaMicroseconds); + base::Time::kMicrosecondsPerSecond + + static_cast<int64>(ntp_fractions) / kMagicFractionalUnit; + + base::TimeDelta elapsed_since_unix_epoch = + base::TimeDelta::FromMicroseconds(ntp_time_us - + (kUnixEpochInNtpSeconds * base::Time::kMicrosecondsPerSecond)); + return base::TimeTicks::UnixEpoch() + elapsed_since_unix_epoch; } } // namespace cast diff --git a/media/cast/rtcp/rtcp.cc b/media/cast/rtcp/rtcp.cc index 875736b..a1720ffe1 100644 --- a/media/cast/rtcp/rtcp.cc +++ b/media/cast/rtcp/rtcp.cc @@ -273,7 +273,7 @@ void Rtcp::SendRtcp(const base::TimeTicks& now, packet_type_flags |= RtcpSender::kRtcpRrtr; RtcpReceiverReferenceTimeReport rrtr; - ConvertTimeToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); + ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); time_last_report_sent_ = now; last_report_sent_ = ConvertToNtpDiff(rrtr.ntp_seconds, rrtr.ntp_fraction); @@ -335,9 +335,9 @@ bool Rtcp::RtpTimestampInSenderTime(int frequency, uint32 rtp_timestamp, // Sanity check. if (abs(rtp_time_diff_ms) > kMaxDiffSinceReceivedRtcpMs) return false; - *rtp_timestamp_in_ticks = - ConvertNtpToTime(last_received_ntp_seconds_, last_received_ntp_fraction_) + - base::TimeDelta::FromMilliseconds(rtp_time_diff_ms); + *rtp_timestamp_in_ticks = ConvertNtpToTimeTicks(last_received_ntp_seconds_, + last_received_ntp_fraction_) + + base::TimeDelta::FromMilliseconds(rtp_time_diff_ms); return true; } diff --git a/media/cast/rtcp/rtcp_unittest.cc b/media/cast/rtcp/rtcp_unittest.cc index a4213ff..ccbdcac 100644 --- a/media/cast/rtcp/rtcp_unittest.cc +++ b/media/cast/rtcp/rtcp_unittest.cc @@ -113,8 +113,8 @@ class RtcpTest : public ::testing::Test { }; TEST_F(RtcpTest, TimeToSend) { - base::TimeTicks start_time = - base::TimeTicks::FromInternalValue(kStartMillisecond * 1000); + base::TimeTicks start_time; + start_time += base::TimeDelta::FromMilliseconds(kStartMillisecond); Rtcp rtcp(&testing_clock_, &mock_sender_feedback_, &transport_, @@ -293,29 +293,40 @@ TEST_F(RtcpTest, Rtt) { EXPECT_NEAR((2 * kAddedShortDelay + 2 * kAddedDelay) / 2, avg_rtt.InMilliseconds(), 1); - EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 1); + EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 1); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 1); } TEST_F(RtcpTest, NtpAndTime) { - RtcpPeer rtcp_peer(&testing_clock_, - &mock_sender_feedback_, - NULL, - NULL, - NULL, - kRtcpReducedSize, - base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), - false, - kReceiverSsrc, - kCName); - uint32 ntp_seconds = 0; - uint32 ntp_fractions = 0; - base::TimeTicks input_time = base::TimeTicks::FromInternalValue( - 12345678901000LL + kNtpEpochDeltaMicroseconds); - ConvertTimeToNtp(input_time, &ntp_seconds, &ntp_fractions); - EXPECT_EQ(12345678u, ntp_seconds); - EXPECT_EQ(input_time, - ConvertNtpToTime(ntp_seconds, ntp_fractions)); + const int64 kSecondsbetweenYear1900and2010 = GG_INT64_C(40176 * 24 * 60 * 60); + const int64 kSecondsbetweenYear1900and2030 = GG_INT64_C(47481 * 24 * 60 * 60); + + uint32 ntp_seconds_1 = 0; + uint32 ntp_fractions_1 = 0; + base::TimeTicks input_time = base::TimeTicks::Now(); + ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fractions_1); + + // Verify absolute value. + EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010); + EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030); + + base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fractions_1); + EXPECT_EQ(input_time, out_1); // Verify inverse. + + base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1100); + input_time += time_delta; + + uint32 ntp_seconds_2 = 0; + uint32 ntp_fractions_2 = 0; + + ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fractions_2); + base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fractions_2); + EXPECT_EQ(input_time, out_2); // Verify inverse. + + // Verify delta. + EXPECT_EQ((out_2 - out_1), time_delta); + EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), GG_UINT32_C(1)); + EXPECT_NEAR((ntp_fractions_2 - ntp_fractions_1), 0xffffffff / 10, 1); } TEST_F(RtcpTest, WrapAround) { @@ -367,34 +378,35 @@ TEST_F(RtcpTest, RtpTimestampInSenderTime) { uint32 ntp_seconds = 0; uint32 ntp_fractions = 0; - base::TimeTicks input_time = base::TimeTicks::FromInternalValue( - 12345678901000LL + kNtpEpochDeltaMicroseconds); + uint64 input_time_us = 12345678901000LL; + base::TimeTicks input_time; + input_time += base::TimeDelta::FromMicroseconds(input_time_us); // Test exact match. - ConvertTimeToNtp(input_time, &ntp_seconds, &ntp_fractions); + ConvertTimeTicksToNtp(input_time, &ntp_seconds, &ntp_fractions); rtcp_peer.OnReceivedLipSyncInfo(rtp_timestamp, ntp_seconds, ntp_fractions); EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime(frequency, rtp_timestamp, - &rtp_timestamp_in_ticks)); + &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time, rtp_timestamp_in_ticks); // Test older rtp_timestamp. rtp_timestamp = 32000; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime(frequency, rtp_timestamp, - &rtp_timestamp_in_ticks)); + &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time - base::TimeDelta::FromMilliseconds(1000), rtp_timestamp_in_ticks); // Test older rtp_timestamp with wrap. rtp_timestamp = 4294903296u; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime(frequency, rtp_timestamp, - &rtp_timestamp_in_ticks)); + &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time - base::TimeDelta::FromMilliseconds(4000), rtp_timestamp_in_ticks); // Test newer rtp_timestamp. rtp_timestamp = 128000; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime(frequency, rtp_timestamp, - &rtp_timestamp_in_ticks)); + &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time + base::TimeDelta::FromMilliseconds(2000), rtp_timestamp_in_ticks); @@ -403,7 +415,7 @@ TEST_F(RtcpTest, RtpTimestampInSenderTime) { rtcp_peer.OnReceivedLipSyncInfo(rtp_timestamp, ntp_seconds, ntp_fractions); rtp_timestamp = 64000; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime(frequency, rtp_timestamp, - &rtp_timestamp_in_ticks)); + &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time + base::TimeDelta::FromMilliseconds(4000), rtp_timestamp_in_ticks); } diff --git a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc index b5dd4d7..c4cb42e 100644 --- a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc +++ b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc @@ -23,7 +23,6 @@ static const int kMaxPacketLength = 1500; static const int kSsrc = 0x12345; static const unsigned int kFrameSize = 5000; static const int kMaxPacketStorageTimeMs = 300; -static const int64 kStartMillisecond = 0; class TestRtpPacketTransport : public PacedPacketSender { public: @@ -108,8 +107,6 @@ class RtpPacketizerTest : public ::testing::Test { config_.payload_type = kPayload; config_.max_payload_length = kMaxPacketLength; transport_.reset(new TestRtpPacketTransport(config_)); - testing_clock_.Advance( - base::TimeDelta::FromMilliseconds(kStartMillisecond)); rtp_packetizer_.reset( new RtpPacketizer(transport_.get(), &packet_storage_, config_)); } diff --git a/media/cast/rtp_sender/rtp_sender.cc b/media/cast/rtp_sender/rtp_sender.cc index d306c6e..d06a503 100644 --- a/media/cast/rtp_sender/rtp_sender.cc +++ b/media/cast/rtp_sender/rtp_sender.cc @@ -121,7 +121,7 @@ void RtpSender::RtpStatistics(const base::TimeTicks& now, // was captured. uint32 ntp_seconds = 0; uint32 ntp_fraction = 0; - ConvertTimeToNtp(now, &ntp_seconds, &ntp_fraction); + ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction); sender_info->ntp_seconds = ntp_seconds; sender_info->ntp_fraction = ntp_fraction; diff --git a/media/cast/test/encode_decode_test.cc b/media/cast/test/encode_decode_test.cc index 0bcd6c2..bc2c0a1 100644 --- a/media/cast/test/encode_decode_test.cc +++ b/media/cast/test/encode_decode_test.cc @@ -77,6 +77,7 @@ TEST_F(EncodeDecodeTest, BasicEncodeDecode) { I420VideoFrame decoded_frame; // Encode frame. encoder_->Encode(*(video_frame_.get()), &encoded_frame); + EXPECT_GT(encoded_frame.data.size(), GG_UINT64_C(0)); // Decode frame. decoder_->Decode(encoded_frame, &decoded_frame); // Validate data. diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc index 3caa6e7..e9cefaa 100644 --- a/media/cast/test/end2end_unittest.cc +++ b/media/cast/test/end2end_unittest.cc @@ -27,9 +27,7 @@ namespace media { namespace cast { -// Since our time is based on year 1600 and NTP is based on year 1900 we must -// initialize our fake clock to at least 300 year passed year 1600. -static const int64 kStartMillisecond = GG_INT64_C(12345678900000); +static const int64 kStartMillisecond = GG_INT64_C(1245); static const int kAudioChannels = 2; static const int kAudioSamplingFrequency = 48000; static const int kSoundFrequency = 1234; // Frequency of sinusoid wave. |