diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h index 8e2893a3d3..2578523d4d 100644 --- a/api/peer_connection_interface.h +++ b/api/peer_connection_interface.h @@ -351,6 +351,13 @@ class RTC_EXPORT PeerConnectionInterface : public webrtc::RefCountInterface { bool dscp() const { return media_config.enable_dscp; } void set_dscp(bool enable) { media_config.enable_dscp = enable; } + bool stats_timestamp_with_environment_clock() const { + return media_config.stats_timestamp_with_environment_clock; + } + void set_stats_timestamp_with_environment_clock(bool enable) { + media_config.stats_timestamp_with_environment_clock = enable; + } + bool cpu_adaptation() const { return media_config.video.enable_cpu_adaptation; } diff --git a/media/base/media_config.h b/media/base/media_config.h index 782770569c..45fd903eaa 100644 --- a/media/base/media_config.h +++ b/media/base/media_config.h @@ -22,6 +22,17 @@ struct MediaConfig { // and delete this flag. bool enable_dscp = true; + // If true, RTCStats timestamps are sourced from the monotonically increasing + // environment Clock, where the epoch is unspecified (i.e. up to the Clock + // implementation). If false, RTCStats timestamps are either sourced from + // system clock via rtc::TimeUTCMicros() which is relative to 1970 but not + // necessarily monotonically increasing, or from a monotonic clock that is + // set to rtc::TimeUTCMicros() at first call, and then procceeds to increase + // monotonically. + // TODO(webrtc:370535296): Change default value to true and delete this flag + // once downstream projects have migrated. + bool stats_timestamp_with_environment_clock = false; + // Video-specific config. struct Video { // Enable WebRTC CPU Overuse Detection. This flag comes from the diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index 50917c1ffa..cc92fcd470 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -6035,7 +6035,8 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) { report_block.SetCumulativeLost(17); report_block.SetFractionLost(18); webrtc::ReportBlockData report_block_data; - report_block_data.SetReportBlock(0, report_block, webrtc::Timestamp::Zero()); + report_block_data.SetReportBlock(0, report_block, webrtc::Timestamp::Zero(), + webrtc::Timestamp::Zero()); report_block_data.AddRoundTripTimeSample(webrtc::TimeDelta::Millis(19)); substream.report_block_data = report_block_data; substream.encode_frame_rate = 20.0; @@ -6159,7 +6160,8 @@ TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) { report_block.SetCumulativeLost(17); report_block.SetFractionLost(18); webrtc::ReportBlockData report_block_data; - report_block_data.SetReportBlock(0, report_block, webrtc::Timestamp::Zero()); + report_block_data.SetReportBlock(0, report_block, webrtc::Timestamp::Zero(), + webrtc::Timestamp::Zero()); report_block_data.AddRoundTripTimeSample(webrtc::TimeDelta::Millis(19)); substream.report_block_data = report_block_data; substream.encode_frame_rate = 20.0; diff --git a/modules/rtp_rtcp/include/report_block_data.cc b/modules/rtp_rtcp/include/report_block_data.cc index 0d4fed043f..84fbea3df9 100644 --- a/modules/rtp_rtcp/include/report_block_data.cc +++ b/modules/rtp_rtcp/include/report_block_data.cc @@ -21,9 +21,12 @@ TimeDelta ReportBlockData::jitter(int rtp_clock_rate_hz) const { return TimeDelta::Seconds(jitter()) / rtp_clock_rate_hz; } +// TODO(webrtc:370535296): When (webrtc:370535296) is fixed, we don't need the +// utc timestamp. void ReportBlockData::SetReportBlock(uint32_t sender_ssrc, const rtcp::ReportBlock& report_block, - Timestamp report_block_timestamp_utc) { + Timestamp report_block_timestamp_utc, + Timestamp report_block_timestamp) { sender_ssrc_ = sender_ssrc; source_ssrc_ = report_block.source_ssrc(); fraction_lost_raw_ = report_block.fraction_lost(); @@ -31,6 +34,7 @@ void ReportBlockData::SetReportBlock(uint32_t sender_ssrc, extended_highest_sequence_number_ = report_block.extended_high_seq_num(); jitter_ = report_block.jitter(); report_block_timestamp_utc_ = report_block_timestamp_utc; + report_block_timestamp_ = report_block_timestamp; } void ReportBlockData::AddRoundTripTimeSample(TimeDelta rtt) { diff --git a/modules/rtp_rtcp/include/report_block_data.h b/modules/rtp_rtcp/include/report_block_data.h index f6a23b1bb2..5861f21851 100644 --- a/modules/rtp_rtcp/include/report_block_data.h +++ b/modules/rtp_rtcp/include/report_block_data.h @@ -72,10 +72,15 @@ class ReportBlockData { TimeDelta jitter(int rtp_clock_rate_hz) const; // Time in utc epoch (Jan 1st, 1970) the report block was received. + // TODO(webrtc:370535296): When (webrtc:370535296) is fixed, we don't need the + // utc timestamp. Timestamp report_block_timestamp_utc() const { return report_block_timestamp_utc_; } + // Monotonic time when the report block was received. + Timestamp report_block_timestamp() const { return report_block_timestamp_; } + // Round Trip Time measurments for given (sender_ssrc, source_ssrc) pair. // Min, max, sum, number of measurements are since beginning of the call. TimeDelta last_rtt() const { return last_rtt_; } @@ -91,13 +96,19 @@ class ReportBlockData { extended_highest_sequence_number_ = sn; } void set_jitter(uint32_t jitter) { jitter_ = jitter; } + // TODO(webrtc:370535296): When (webrtc:370535296) is fixed, we don't need the + // utc timestamp. void set_report_block_timestamp_utc(Timestamp arrival_time) { report_block_timestamp_utc_ = arrival_time; } + void set_report_block_timestamp(Timestamp arrival_time) { + report_block_timestamp_ = arrival_time; + } void SetReportBlock(uint32_t sender_ssrc, const rtcp::ReportBlock& report_block, - Timestamp report_block_timestamp_utc); + Timestamp report_block_timestamp_utc, + Timestamp report_block_timestamp); void AddRoundTripTimeSample(TimeDelta rtt); private: @@ -107,7 +118,10 @@ class ReportBlockData { int32_t cumulative_lost_ = 0; uint32_t extended_highest_sequence_number_ = 0; uint32_t jitter_ = 0; + // TODO(webrtc:370535296): When (webrtc:370535296) is fixed, we don't need the + // utc timestamp. Timestamp report_block_timestamp_utc_ = Timestamp::Zero(); + Timestamp report_block_timestamp_ = Timestamp::Zero(); TimeDelta last_rtt_ = TimeDelta::Zero(); TimeDelta sum_rtt_ = TimeDelta::Zero(); size_t num_rtts_ = 0; diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc index 6116470735..9e5a2e144e 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -624,7 +624,7 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block, // https://tools.ietf.org/html/rfc868). report_block_data->SetReportBlock( remote_ssrc, report_block, - Timestamp::Millis(now_ntp.ToMs() - rtc::kNtpJan1970Millisecs)); + Timestamp::Millis(now_ntp.ToMs() - rtc::kNtpJan1970Millisecs), now); uint32_t send_time_ntp = report_block.last_sr(); // RFC3550, section 6.4.1, LSR field discription states: diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc index f07d7655d9..858b580795 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc @@ -375,7 +375,7 @@ void RtcpTransceiverImpl::HandleReportBlocks( auto sender_it = local_senders_by_ssrc_.find(block.source_ssrc()); if (sender_it != local_senders_by_ssrc_.end()) { LocalSenderState& state = *sender_it->second; - state.report_block.SetReportBlock(sender_ssrc, block, now_utc); + state.report_block.SetReportBlock(sender_ssrc, block, now_utc, now); if (rtt.has_value()) { state.report_block.AddRoundTripTimeSample(*rtt); } @@ -385,7 +385,7 @@ void RtcpTransceiverImpl::HandleReportBlocks( // No registered sender for this report block, still report it to the // network link. ReportBlockData report_block; - report_block.SetReportBlock(sender_ssrc, block, now_utc); + report_block.SetReportBlock(sender_ssrc, block, now_utc, now); if (rtt.has_value()) { report_block.AddRoundTripTimeSample(*rtt); } diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index c4546a9e94..1171bc8929 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -762,7 +762,7 @@ RTCError PeerConnection::Initialize( configuration_ = configuration; legacy_stats_ = std::make_unique(this); - stats_collector_ = RTCStatsCollector::Create(this); + stats_collector_ = RTCStatsCollector::Create(this, env_); sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration, dependencies, diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index 2375dadddc..29598e0ddb 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -843,14 +843,18 @@ ProduceRemoteInboundRtpStreamStatsFromReportBlockData( const ReportBlockData& report_block, cricket::MediaType media_type, const std::map& outbound_rtps, - const RTCStatsReport& report) { + const RTCStatsReport& report, + const bool stats_timestamp_with_environment_clock) { // RTCStats' timestamp generally refers to when the metric was sampled, but // for "remote-[outbound/inbound]-rtp" it refers to the local time when the // Report Block was received. + Timestamp arrival_timestamp = stats_timestamp_with_environment_clock + ? report_block.report_block_timestamp() + : report_block.report_block_timestamp_utc(); auto remote_inbound = std::make_unique( RTCRemoteInboundRtpStreamStatsIdFromSourceSsrc( media_type, report_block.source_ssrc()), - report_block.report_block_timestamp_utc()); + arrival_timestamp); remote_inbound->ssrc = report_block.source_ssrc(); remote_inbound->kind = media_type == cricket::MEDIA_TYPE_AUDIO ? "audio" : "video"; @@ -1114,13 +1118,18 @@ RTCStatsCollector::RequestInfo::RequestInfo( rtc::scoped_refptr RTCStatsCollector::Create( PeerConnectionInternal* pc, + const Environment& env, int64_t cache_lifetime_us) { - return rtc::make_ref_counted(pc, cache_lifetime_us); + return rtc::make_ref_counted(pc, env, cache_lifetime_us); } RTCStatsCollector::RTCStatsCollector(PeerConnectionInternal* pc, + const Environment& env, int64_t cache_lifetime_us) : pc_(pc), + env_(env), + stats_timestamp_with_environment_clock_( + pc->GetConfiguration().stats_timestamp_with_environment_clock()), signaling_thread_(pc->signaling_thread()), worker_thread_(pc->worker_thread()), network_thread_(pc->network_thread()), @@ -1179,10 +1188,16 @@ void RTCStatsCollector::GetStatsReportInternal( // case of already gathering stats, `callback_` will be invoked when there // are no more pending partial reports. - // "Now" using a system clock, relative to the UNIX epoch (Jan 1, 1970, - // UTC), in microseconds. The system clock could be modified and is not - // necessarily monotonically increasing. - Timestamp timestamp = Timestamp::Micros(rtc::TimeUTCMicros()); + Timestamp timestamp = + stats_timestamp_with_environment_clock_ + ? + // "Now" using a monotonically increasing timer. + env_.clock().CurrentTime() + : + // "Now" using a system clock, relative to the UNIX epoch (Jan 1, + // 1970, UTC), in microseconds. The system clock could be modified + // and is not necessarily monotonically increasing. + Timestamp::Micros(rtc::TimeUTCMicros()); num_pending_partial_reports_ = 2; partial_report_timestamp_us_ = cache_now_us; @@ -1767,7 +1782,8 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( for (const auto& report_block_data : voice_sender_info.report_block_datas) { report->AddStats(ProduceRemoteInboundRtpStreamStatsFromReportBlockData( transport_id, report_block_data, cricket::MEDIA_TYPE_AUDIO, - audio_outbound_rtps, *report)); + audio_outbound_rtps, *report, + stats_timestamp_with_environment_clock_)); } } } @@ -1861,7 +1877,8 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( for (const auto& report_block_data : video_sender_info.report_block_datas) { report->AddStats(ProduceRemoteInboundRtpStreamStatsFromReportBlockData( transport_id, report_block_data, cricket::MEDIA_TYPE_VIDEO, - video_outbound_rtps, *report)); + video_outbound_rtps, *report, + stats_timestamp_with_environment_clock_)); } } } diff --git a/pc/rtc_stats_collector.h b/pc/rtc_stats_collector.h index 1beef4c575..30203609eb 100644 --- a/pc/rtc_stats_collector.h +++ b/pc/rtc_stats_collector.h @@ -60,6 +60,7 @@ class RTCStatsCollector : public RefCountInterface { public: static rtc::scoped_refptr Create( PeerConnectionInternal* pc, + const Environment& env, int64_t cache_lifetime_us = 50 * rtc::kNumMicrosecsPerMillisec); // Gets a recent stats report. If there is a report cached that is still fresh @@ -95,7 +96,9 @@ class RTCStatsCollector : public RefCountInterface { DataChannelInterface::DataState state); protected: - RTCStatsCollector(PeerConnectionInternal* pc, int64_t cache_lifetime_us); + RTCStatsCollector(PeerConnectionInternal* pc, + const Environment& env, + int64_t cache_lifetime_us); ~RTCStatsCollector(); struct CertificateStatsPair { @@ -252,6 +255,8 @@ class RTCStatsCollector : public RefCountInterface { rtc::scoped_refptr receiver_selector); PeerConnectionInternal* const pc_; + const Environment env_; + const bool stats_timestamp_with_environment_clock_; rtc::Thread* const signaling_thread_; rtc::Thread* const worker_thread_; rtc::Thread* const network_thread_; diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc index 23c5e8f759..cdbddf2635 100644 --- a/pc/rtc_stats_collector_unittest.cc +++ b/pc/rtc_stats_collector_unittest.cc @@ -427,10 +427,12 @@ rtc::scoped_refptr CreateMockReceiver( class RTCStatsCollectorWrapper { public: explicit RTCStatsCollectorWrapper( - rtc::scoped_refptr pc) + rtc::scoped_refptr pc, + const Environment& env) : pc_(pc), stats_collector_( RTCStatsCollector::Create(pc.get(), + env, 50 * rtc::kNumMicrosecsPerMillisec)) {} rtc::scoped_refptr stats_collector() { @@ -662,7 +664,7 @@ class RTCStatsCollectorTest : public ::testing::Test { public: RTCStatsCollectorTest() : pc_(rtc::make_ref_counted()), - stats_(new RTCStatsCollectorWrapper(pc_)), + stats_(new RTCStatsCollectorWrapper(pc_, CreateEnvironment())), data_channel_controller_( new FakeDataChannelController(pc_->network_thread())) {} @@ -3294,6 +3296,7 @@ class RTCStatsCollectorTestWithParamKind TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsCollectedFromReportBlock) { const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + const Timestamp kReportBlockTimestamp = Timestamp::Micros(12345678); const uint8_t kFractionLost = 12; const TimeDelta kRoundTripTimeSample1 = TimeDelta::Millis(1'234); const TimeDelta kRoundTripTimeSample2 = TimeDelta::Seconds(13); @@ -3311,7 +3314,8 @@ TEST_P(RTCStatsCollectorTestWithParamKind, report_block.SetCumulativeLost(7); report_block.SetFractionLost(kFractionLost); ReportBlockData report_block_data; - report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc, + kReportBlockTimestamp); report_block_data.AddRoundTripTimeSample(kRoundTripTimeSample1); // Only the last sample should be exposed as the // `RTCRemoteInboundRtpStreamStats::round_trip_time`. @@ -3361,13 +3365,15 @@ TEST_P(RTCStatsCollectorTestWithParamKind, TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsRttMissingBeforeMeasurement) { constexpr Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + const Timestamp kReportBlockTimestamp = Timestamp::Micros(12345678); rtcp::ReportBlock report_block; // The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the // `source_ssrc`, "SSRC of the RTP packet sender". report_block.SetMediaSsrc(12); ReportBlockData report_block_data; // AddRoundTripTimeSample() not called. - report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc, + kReportBlockTimestamp); AddSenderInfoAndMediaChannel("TransportName", {report_block_data}, std::nullopt); @@ -3387,6 +3393,7 @@ TEST_P(RTCStatsCollectorTestWithParamKind, TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsWithTimestampFromReportBlock) { const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + const Timestamp kReportBlockTimestamp = Timestamp::Micros(12345678); fake_clock_.SetTime(kReportBlockTimestampUtc); rtcp::ReportBlock report_block; @@ -3394,7 +3401,8 @@ TEST_P(RTCStatsCollectorTestWithParamKind, // `source_ssrc`, "SSRC of the RTP packet sender". report_block.SetMediaSsrc(12); ReportBlockData report_block_data; - report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc, + kReportBlockTimestamp); AddSenderInfoAndMediaChannel("TransportName", {report_block_data}, std::nullopt); @@ -3419,6 +3427,7 @@ TEST_P(RTCStatsCollectorTestWithParamKind, TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsWithCodecBasedMembers) { const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + const Timestamp kReportBlockTimestamp = Timestamp::Micros(12345678); fake_clock_.SetTime(kReportBlockTimestampUtc); rtcp::ReportBlock report_block; @@ -3427,7 +3436,8 @@ TEST_P(RTCStatsCollectorTestWithParamKind, report_block.SetMediaSsrc(12); report_block.SetJitter(5000); ReportBlockData report_block_data; - report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc, + kReportBlockTimestamp); RtpCodecParameters codec; codec.payload_type = 3; @@ -3455,6 +3465,7 @@ TEST_P(RTCStatsCollectorTestWithParamKind, TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsWithRtcpTransport) { const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + const Timestamp kReportBlockTimestamp = Timestamp::Micros(12345678); fake_clock_.SetTime(kReportBlockTimestampUtc); rtcp::ReportBlock report_block; @@ -3462,7 +3473,8 @@ TEST_P(RTCStatsCollectorTestWithParamKind, // `source_ssrc`, "SSRC of the RTP packet sender". report_block.SetMediaSsrc(12); ReportBlockData report_block_data; - report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc, + kReportBlockTimestamp); cricket::TransportChannelStats rtp_transport_channel_stats; rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP; @@ -3747,9 +3759,10 @@ class FakeRTCStatsCollector : public RTCStatsCollector, public: static rtc::scoped_refptr Create( PeerConnectionInternal* pc, + const Environment& env, int64_t cache_lifetime_us) { return rtc::scoped_refptr( - new rtc::RefCountedObject(pc, + new rtc::RefCountedObject(pc, env, cache_lifetime_us)); } @@ -3794,8 +3807,10 @@ class FakeRTCStatsCollector : public RTCStatsCollector, } protected: - FakeRTCStatsCollector(PeerConnectionInternal* pc, int64_t cache_lifetime) - : RTCStatsCollector(pc, cache_lifetime), + FakeRTCStatsCollector(PeerConnectionInternal* pc, + const Environment& env, + int64_t cache_lifetime) + : RTCStatsCollector(pc, env, cache_lifetime), signaling_thread_(pc->signaling_thread()), worker_thread_(pc->worker_thread()), network_thread_(pc->network_thread()) {} @@ -3845,7 +3860,7 @@ TEST(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) { rtc::AutoThread main_thread_; auto pc = rtc::make_ref_counted(); rtc::scoped_refptr stats_collector( - FakeRTCStatsCollector::Create(pc.get(), + FakeRTCStatsCollector::Create(pc.get(), CreateEnvironment(), 50 * rtc::kNumMicrosecsPerMillisec)); stats_collector->VerifyThreadUsageAndResultsMerging(); } diff --git a/video/send_statistics_proxy_unittest.cc b/video/send_statistics_proxy_unittest.cc index 01b0349ed1..0d022c7b20 100644 --- a/video/send_statistics_proxy_unittest.cc +++ b/video/send_statistics_proxy_unittest.cc @@ -199,7 +199,8 @@ TEST_F(SendStatisticsProxyTest, ReportBlockDataObserver) { report_block.SetFractionLost(offset + 2); report_block.SetJitter(offset + 3); ReportBlockData data; - data.SetReportBlock(/*sender_ssrc=*/0, report_block, Timestamp::Zero()); + data.SetReportBlock(/*sender_ssrc=*/0, report_block, Timestamp::Zero(), + Timestamp::Zero()); expected_.substreams[ssrc].report_block_data = data; callback->OnReportBlockDataUpdated(data); @@ -214,7 +215,8 @@ TEST_F(SendStatisticsProxyTest, ReportBlockDataObserver) { report_block.SetFractionLost(offset + 2); report_block.SetJitter(offset + 3); ReportBlockData data; - data.SetReportBlock(/*sender_ssrc=*/0, report_block, Timestamp::Zero()); + data.SetReportBlock(/*sender_ssrc=*/0, report_block, Timestamp::Zero(), + Timestamp::Zero()); expected_.substreams[ssrc].report_block_data = data; callback->OnReportBlockDataUpdated(data); @@ -2319,7 +2321,7 @@ TEST_F(SendStatisticsProxyTest, NoSubstreams) { rtcp::ReportBlock report_block; report_block.SetMediaSsrc(excluded_ssrc); ReportBlockData data; - data.SetReportBlock(0, report_block, Timestamp::Zero()); + data.SetReportBlock(0, report_block, Timestamp::Zero(), Timestamp::Zero()); rtcp_callback->OnReportBlockDataUpdated(data); // From BitrateStatisticsObserver. @@ -2372,7 +2374,7 @@ TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) { rtcp::ReportBlock report_block; report_block.SetMediaSsrc(config_.rtp.ssrcs[0]); ReportBlockData data; - data.SetReportBlock(0, report_block, Timestamp::Zero()); + data.SetReportBlock(0, report_block, Timestamp::Zero(), Timestamp::Zero()); rtcp_callback->OnReportBlockDataUpdated(data); // Report stats for second SSRC to make sure it's not outdated along with the