summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/time/time.cc24
-rw-r--r--base/time/time.h8
-rw-r--r--media/cast/audio_receiver/audio_receiver_unittest.cc5
-rw-r--r--media/cast/cast_defines.h41
-rw-r--r--media/cast/rtcp/rtcp.cc8
-rw-r--r--media/cast/rtcp/rtcp_unittest.cc70
-rw-r--r--media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc3
-rw-r--r--media/cast/rtp_sender/rtp_sender.cc2
-rw-r--r--media/cast/test/encode_decode_test.cc1
-rw-r--r--media/cast/test/end2end_unittest.cc4
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.