diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc index 0514277f5b..5e580a34b5 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc @@ -121,7 +121,8 @@ TEST_F(RtcpFormatRembTest, TestNonCompund) { uint32_t SSRC = 456789; EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpNonCompound)); EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 1, &SSRC)); - RTCPSender::FeedbackState feedback_state(dummy_rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = + dummy_rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRemb)); } @@ -129,7 +130,8 @@ TEST_F(RtcpFormatRembTest, TestCompund) { uint32_t SSRCs[2] = {456789, 98765}; EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 2, SSRCs)); - RTCPSender::FeedbackState feedback_state(dummy_rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = + dummy_rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRemb)); } } // namespace diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index b38ae1f0d5..54b991bf33 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -224,12 +224,12 @@ bool RTCPReceiver::GetAndResetXrRrRtt(uint16_t* rtt_ms) { return true; } -int32_t -RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs, - uint32_t *ReceivedNTPfrac, - uint32_t *RTCPArrivalTimeSecs, - uint32_t *RTCPArrivalTimeFrac, - uint32_t *rtcp_timestamp) const +// TODO(pbos): Make this fail when we haven't received NTP. +bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs, + uint32_t* ReceivedNTPfrac, + uint32_t* RTCPArrivalTimeSecs, + uint32_t* RTCPArrivalTimeFrac, + uint32_t* rtcp_timestamp) const { CriticalSectionScoped lock(_criticalSectionRTCPReceiver); if(ReceivedNTPsecs) @@ -251,7 +251,7 @@ RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs, if (rtcp_timestamp) { *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp; } - return 0; + return true; } bool RTCPReceiver::LastReceivedXrReferenceTimeInfo( diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h index ebffb7cfc9..84eb24c7bd 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h @@ -63,11 +63,11 @@ public: char cName[RTCP_CNAME_SIZE]) const; // get received NTP - int32_t NTP(uint32_t *ReceivedNTPsecs, - uint32_t *ReceivedNTPfrac, - uint32_t *RTCPArrivalTimeSecs, - uint32_t *RTCPArrivalTimeFrac, - uint32_t *rtcp_timestamp) const; + bool NTP(uint32_t* ReceivedNTPsecs, + uint32_t* ReceivedNTPfrac, + uint32_t* RTCPArrivalTimeSecs, + uint32_t* RTCPArrivalTimeFrac, + uint32_t* rtcp_timestamp) const; bool LastReceivedXrReferenceTimeInfo(RtcpReceiveTimeInfo* info) const; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index 2cf7e1cbc8..1edbee4334 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -65,30 +65,11 @@ std::string NACKStringBuilder::GetResult() return _stream.str(); } -RTCPSender::FeedbackState::FeedbackState(ModuleRtpRtcpImpl* module) - : send_payload_type(module->SendPayloadType()), - frequency_hz(module->CurrentSendFrequencyHz()), - packet_count_sent(module->PacketCountSent()), - byte_count_sent(module->ByteCountSent()), - module(module) { - uint32_t last_ntp_secs = 0, last_ntp_frac = 0, last_remote_sr = 0; - module->LastReceivedNTP(last_ntp_secs, last_ntp_frac, last_remote_sr); - last_rr_ntp_secs = last_ntp_secs; - last_rr_ntp_frac = last_ntp_frac; - remote_sr = last_remote_sr; - - has_last_xr_rr = module->LastReceivedXrReferenceTimeInfo(&last_xr_rr); - - uint32_t send_bitrate = 0, tmp; - module->BitrateSent(&send_bitrate, &tmp, &tmp, &tmp); - this->send_bitrate = send_bitrate; -} - RTCPSender::FeedbackState::FeedbackState() : send_payload_type(0), frequency_hz(0), - packet_count_sent(0), - byte_count_sent(0), + packets_sent(0), + media_bytes_sent(0), send_bitrate(0), last_rr_ntp_secs(0), last_rr_ntp_frac(0), @@ -654,12 +635,12 @@ int32_t RTCPSender::BuildSR(const FeedbackState& feedback_state, //sender's packet count RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, - feedback_state.packet_count_sent); + feedback_state.packets_sent); pos += 4; //sender's octet count RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, - feedback_state.byte_count_sent); + feedback_state.media_bytes_sent); pos += 4; uint8_t numberOfReportBlocks = 0; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h index fad3b5e332..26c44b0464 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h @@ -51,13 +51,12 @@ class RTCPSender { public: struct FeedbackState { - explicit FeedbackState(ModuleRtpRtcpImpl* module); FeedbackState(); uint8_t send_payload_type; uint32_t frequency_hz; - uint32_t packet_count_sent; - uint32_t byte_count_sent; + uint32_t packets_sent; + uint32_t media_bytes_sent; uint32_t send_bitrate; uint32_t last_rr_ntp_secs; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc index cba1c34638..b8d53953a1 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc @@ -337,7 +337,7 @@ class RtcpSenderTest : public ::testing::Test { TEST_F(RtcpSenderTest, RtcpOff) { EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpOff)); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); } @@ -381,7 +381,7 @@ TEST_F(RtcpSenderTest, TestCompound) { EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true)); EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr)); // Transmission time offset packet should be received. @@ -392,7 +392,7 @@ TEST_F(RtcpSenderTest, TestCompound) { TEST_F(RtcpSenderTest, TestCompound_NoRtpReceived) { EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true)); EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr)); // Transmission time offset packet should not be received. @@ -402,7 +402,7 @@ TEST_F(RtcpSenderTest, TestCompound_NoRtpReceived) { TEST_F(RtcpSenderTest, TestXrReceiverReferenceTime) { EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); @@ -413,7 +413,7 @@ TEST_F(RtcpSenderTest, TestXrReceiverReferenceTime) { TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfSending) { EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, true)); rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); @@ -424,7 +424,7 @@ TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfSending) { TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfNotEnabled) { EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); rtcp_sender_->SendRtcpXrReceiverReferenceTime(false); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); @@ -435,7 +435,7 @@ TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfNotEnabled) { TEST_F(RtcpSenderTest, TestSendTimeOfXrRrReport) { EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); uint32_t ntp_sec; @@ -475,7 +475,7 @@ TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) { TMMBRSet bounding_set; EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3)); ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state,kRtcpSr)); // We now expect the packet to show up in the rtcp_packet_info_ of // test_transport_. @@ -498,7 +498,7 @@ TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndValid) { EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3)); ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); - RTCPSender::FeedbackState feedback_state(rtp_rtcp_impl_); + RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); // We now expect the packet to show up in the rtcp_packet_info_ of // test_transport_. diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 349340f5f5..1fb0c5d271 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -230,8 +230,7 @@ int32_t ModuleRtpRtcpImpl::Process() { } if (rtcp_sender_.TimeToSendRTCPReport()) { - RTCPSender::FeedbackState feedback_state(this); - rtcp_sender_.SendRTCP(feedback_state, kRtcpReport); + rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport); } } @@ -418,12 +417,29 @@ int32_t ModuleRtpRtcpImpl::SetCSRCs( return 0; // TODO(pwestin): change to void. } -uint32_t ModuleRtpRtcpImpl::PacketCountSent() const { - return rtp_sender_.Packets(); -} +// TODO(pbos): Handle media and RTX streams separately (separate RTCP +// feedbacks). +RTCPSender::FeedbackState ModuleRtpRtcpImpl::GetFeedbackState() { + StreamDataCounters rtp_stats; + StreamDataCounters rtx_stats; + rtp_sender_.GetDataCounters(&rtp_stats, &rtx_stats); -uint32_t ModuleRtpRtcpImpl::ByteCountSent() const { - return rtp_sender_.Bytes(); + RTCPSender::FeedbackState state; + state.send_payload_type = SendPayloadType(); + state.frequency_hz = CurrentSendFrequencyHz(); + state.packets_sent = rtp_stats.packets + rtx_stats.packets; + state.media_bytes_sent = rtp_stats.bytes + rtx_stats.bytes; + state.module = this; + + LastReceivedNTP(&state.last_rr_ntp_secs, + &state.last_rr_ntp_frac, + &state.remote_sr); + + state.has_last_xr_rr = LastReceivedXrReferenceTimeInfo(&state.last_xr_rr); + + uint32_t tmp; + BitrateSent(&state.send_bitrate, &tmp, &tmp, &tmp); + return state; } int ModuleRtpRtcpImpl::CurrentSendFrequencyHz() const { @@ -433,8 +449,7 @@ int ModuleRtpRtcpImpl::CurrentSendFrequencyHz() const { int32_t ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) { if (rtcp_sender_.Sending() != sending) { // Sends RTCP BYE when going from true to false - RTCPSender::FeedbackState feedback_state(this); - if (rtcp_sender_.SetSendingStatus(feedback_state, sending) != 0) { + if (rtcp_sender_.SetSendingStatus(GetFeedbackState(), sending) != 0) { LOG(LS_WARNING) << "Failed to send RTCP BYE"; } @@ -499,8 +514,7 @@ int32_t ModuleRtpRtcpImpl::SendOutgoingData( if (!IsDefaultModule()) { // Don't send RTCP from default module. if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) { - RTCPSender::FeedbackState feedback_state(this); - rtcp_sender_.SendRTCP(feedback_state, kRtcpReport); + rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport); } return rtp_sender_.SendOutgoingData(frame_type, payload_type, @@ -782,8 +796,7 @@ int32_t ModuleRtpRtcpImpl::ResetSendDataCountersRTP() { // Force a send of an RTCP packet. // Normal SR and RR are triggered via the process function. int32_t ModuleRtpRtcpImpl::SendRTCP(uint32_t rtcp_packet_type) { - RTCPSender::FeedbackState feedback_state(this); - return rtcp_sender_.SendRTCP(feedback_state, rtcp_packet_type); + return rtcp_sender_.SendRTCP(GetFeedbackState(), rtcp_packet_type); } int32_t ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData( @@ -811,11 +824,17 @@ bool ModuleRtpRtcpImpl::RtcpXrRrtrStatus() const { int32_t ModuleRtpRtcpImpl::DataCountersRTP( uint32_t* bytes_sent, uint32_t* packets_sent) const { + StreamDataCounters rtp_stats; + StreamDataCounters rtx_stats; + rtp_sender_.GetDataCounters(&rtp_stats, &rtx_stats); + if (bytes_sent) { - *bytes_sent = rtp_sender_.Bytes(); + *bytes_sent = rtp_stats.bytes + rtp_stats.padding_bytes + + rtp_stats.header_bytes + rtx_stats.bytes + + rtx_stats.padding_bytes + rtx_stats.header_bytes; } if (packets_sent) { - *packets_sent = rtp_sender_.Packets(); + *packets_sent = rtp_stats.packets + rtx_stats.packets; } return 0; } @@ -955,9 +974,8 @@ int32_t ModuleRtpRtcpImpl::SendNACK(const uint16_t* nack_list, } nack_last_seq_number_sent_ = nack_list[start_id + nackLength - 1]; - RTCPSender::FeedbackState feedback_state(this); return rtcp_sender_.SendRTCP( - feedback_state, kRtcpNack, nackLength, &nack_list[start_id]); + GetFeedbackState(), kRtcpNack, nackLength, &nack_list[start_id]); } // Store the sent packets, needed to answer to a Negative acknowledgment @@ -1074,9 +1092,8 @@ int32_t ModuleRtpRtcpImpl::RequestKeyFrame() { int32_t ModuleRtpRtcpImpl::SendRTCPSliceLossIndication( const uint8_t picture_id) { - RTCPSender::FeedbackState feedback_state(this); return rtcp_sender_.SendRTCP( - feedback_state, kRtcpSli, 0, 0, false, picture_id); + GetFeedbackState(), kRtcpSli, 0, 0, false, picture_id); } int32_t ModuleRtpRtcpImpl::SetCameraDelay(const int32_t delay_ms) { @@ -1245,9 +1262,8 @@ void ModuleRtpRtcpImpl::OnRequestSendReport() { int32_t ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection( const uint64_t picture_id) { - RTCPSender::FeedbackState feedback_state(this); return rtcp_sender_.SendRTCP( - feedback_state, kRtcpRpsi, 0, 0, false, picture_id); + GetFeedbackState(), kRtcpRpsi, 0, 0, false, picture_id); } uint32_t ModuleRtpRtcpImpl::SendTimeOfSendReport( @@ -1274,23 +1290,24 @@ void ModuleRtpRtcpImpl::OnReceivedNACK( rtp_sender_.OnReceivedNACK(nack_sequence_numbers, rtt); } -int32_t ModuleRtpRtcpImpl::LastReceivedNTP( - uint32_t& rtcp_arrival_time_secs, // When we got the last report. - uint32_t& rtcp_arrival_time_frac, - uint32_t& remote_sr) { +bool ModuleRtpRtcpImpl::LastReceivedNTP( + uint32_t* rtcp_arrival_time_secs, // When we got the last report. + uint32_t* rtcp_arrival_time_frac, + uint32_t* remote_sr) const { // Remote SR: NTP inside the last received (mid 16 bits from sec and frac). uint32_t ntp_secs = 0; uint32_t ntp_frac = 0; - if (-1 == rtcp_receiver_.NTP(&ntp_secs, - &ntp_frac, - &rtcp_arrival_time_secs, - &rtcp_arrival_time_frac, - NULL)) { - return -1; + if (!rtcp_receiver_.NTP(&ntp_secs, + &ntp_frac, + rtcp_arrival_time_secs, + rtcp_arrival_time_frac, + NULL)) { + return false; } - remote_sr = ((ntp_secs & 0x0000ffff) << 16) + ((ntp_frac & 0xffff0000) >> 16); - return 0; + *remote_sr = + ((ntp_secs & 0x0000ffff) << 16) + ((ntp_frac & 0xffff0000) >> 16); + return true; } bool ModuleRtpRtcpImpl::LastReceivedXrReferenceTimeInfo( diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index 7e7ea02770..4a23dd4011 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -89,12 +89,10 @@ class ModuleRtpRtcpImpl : public RtpRtcp { virtual int32_t SetCSRCStatus(const bool include) OVERRIDE; - virtual uint32_t PacketCountSent() const; + virtual RTCPSender::FeedbackState GetFeedbackState(); virtual int CurrentSendFrequencyHz() const; - virtual uint32_t ByteCountSent() const; - virtual void SetRTXSendStatus(const int mode) OVERRIDE; virtual void RTXSendStatus(int* mode, uint32_t* ssrc, @@ -328,9 +326,9 @@ class ModuleRtpRtcpImpl : public RtpRtcp { const FecProtectionParams* delta_params, const FecProtectionParams* key_params) OVERRIDE; - virtual int32_t LastReceivedNTP(uint32_t& NTPsecs, - uint32_t& NTPfrac, - uint32_t& remote_sr); + virtual bool LastReceivedNTP(uint32_t* NTPsecs, + uint32_t* NTPfrac, + uint32_t* remote_sr) const; virtual bool LastReceivedXrReferenceTimeInfo(RtcpReceiveTimeInfo* info) const; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index c24b15a360..340caa34f2 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -1061,17 +1061,11 @@ void RTPSender::ResetDataCounters() { } } -uint32_t RTPSender::Packets() const { +void RTPSender::GetDataCounters(StreamDataCounters* rtp_stats, + StreamDataCounters* rtx_stats) const { CriticalSectionScoped lock(statistics_crit_.get()); - return rtp_stats_.packets + rtx_rtp_stats_.packets; -} - -// Number of sent RTP bytes. -uint32_t RTPSender::Bytes() const { - CriticalSectionScoped lock(statistics_crit_.get()); - return rtp_stats_.bytes + rtp_stats_.header_bytes + rtp_stats_.padding_bytes + - rtx_rtp_stats_.bytes + rtx_rtp_stats_.header_bytes + - rtx_rtp_stats_.padding_bytes; + *rtp_stats = rtp_stats_; + *rtx_stats = rtx_rtp_stats_; } int RTPSender::CreateRTPHeader( diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h index 4a9e10edf9..f6b7c6eaa5 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -109,11 +109,8 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer { void SetSendingMediaStatus(const bool enabled); bool SendingMedia() const; - // Number of sent RTP packets. - uint32_t Packets() const; - - // Number of sent RTP bytes. - uint32_t Bytes() const; + void GetDataCounters(StreamDataCounters* rtp_stats, + StreamDataCounters* rtx_stats) const; void ResetDataCounters(); diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc index 40b105485d..e9b01def4e 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -39,6 +39,7 @@ const uint8_t kAudioLevel = 0x5a; const uint8_t kAudioLevelExtensionId = 9; const int kAudioPayload = 103; const uint64_t kStartTime = 123456789; +const size_t kMaxPaddingSize = 224u; } // namespace using testing::_; @@ -700,7 +701,7 @@ TEST_F(RtpSenderTest, SendRedundantPayloads) { kAbsoluteSendTimeExtensionId); rtp_sender_->SetTargetBitrate(300000); const size_t kNumPayloadSizes = 10; - const int kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700, 750, + const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700, 750, 800, 850, 900, 950}; // Send 10 packets of increasing size. for (size_t i = 0; i < kNumPayloadSizes; ++i) { @@ -711,25 +712,27 @@ TEST_F(RtpSenderTest, SendRedundantPayloads) { rtp_sender_->TimeToSendPacket(seq_num++, capture_time_ms, false); fake_clock_.AdvanceTimeMilliseconds(33); } - const int kPaddingPayloadSize = 224; // The amount of padding to send it too small to send a payload packet. - EXPECT_CALL(transport, SendPacket(_, _, kPaddingPayloadSize + rtp_header_len)) + EXPECT_CALL(transport, + SendPacket(_, _, kMaxPaddingSize + rtp_header_len)) .WillOnce(testing::ReturnArg<2>()); - EXPECT_EQ(kPaddingPayloadSize, rtp_sender_->TimeToSendPadding(49)); + EXPECT_EQ(kMaxPaddingSize, + static_cast(rtp_sender_->TimeToSendPadding(49))); const int kRtxHeaderSize = 2; EXPECT_CALL(transport, SendPacket(_, _, kPayloadSizes[0] + rtp_header_len + kRtxHeaderSize)) .WillOnce(testing::ReturnArg<2>()); - EXPECT_EQ(kPayloadSizes[0], rtp_sender_->TimeToSendPadding(500)); + EXPECT_EQ(kPayloadSizes[0], + static_cast(rtp_sender_->TimeToSendPadding(500))); EXPECT_CALL(transport, SendPacket(_, _, kPayloadSizes[kNumPayloadSizes - 1] + rtp_header_len + kRtxHeaderSize)) .WillOnce(testing::ReturnArg<2>()); - EXPECT_CALL(transport, SendPacket(_, _, kPaddingPayloadSize + rtp_header_len)) + EXPECT_CALL(transport, SendPacket(_, _, kMaxPaddingSize + rtp_header_len)) .WillOnce(testing::ReturnArg<2>()); - EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kPaddingPayloadSize, - rtp_sender_->TimeToSendPadding(999)); + EXPECT_EQ(kPayloadSizes[kNumPayloadSizes - 1] + kMaxPaddingSize, + static_cast(rtp_sender_->TimeToSendPadding(999))); } TEST_F(RtpSenderTest, SendGenericVideo) { @@ -959,7 +962,6 @@ TEST_F(RtpSenderTest, StreamDataCountersCallbacks) { const uint8_t kRedPayloadType = 96; const uint8_t kUlpfecPayloadType = 97; - const uint32_t kMaxPaddingSize = 224; char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC"; const uint8_t payload_type = 127; ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000, @@ -988,7 +990,7 @@ TEST_F(RtpSenderTest, StreamDataCountersCallbacks) { // Send padding. rtp_sender_->TimeToSendPadding(kMaxPaddingSize); // {bytes = 6, header = 24, padding = 224, packets = 3, retrans = 1, fec = 0} - EXPECT_TRUE(callback.Matches(ssrc, 6, 24, 224, 3, 1, 0)); + EXPECT_TRUE(callback.Matches(ssrc, 6, 24, kMaxPaddingSize, 3, 1, 0)); // Send FEC. rtp_sender_->SetGenericFECStatus(true, kRedPayloadType, kUlpfecPayloadType); @@ -1003,7 +1005,7 @@ TEST_F(RtpSenderTest, StreamDataCountersCallbacks) { sizeof(payload), NULL)); // {bytes = 34, header = 48, padding = 224, packets = 5, retrans = 1, fec = 1} - EXPECT_TRUE(callback.Matches(ssrc, 34, 48, 224, 5, 1, 1)); + EXPECT_TRUE(callback.Matches(ssrc, 34, 48, kMaxPaddingSize, 5, 1, 1)); rtp_sender_->RegisterRtpStatisticsCallback(NULL); } @@ -1093,13 +1095,25 @@ TEST_F(RtpSenderTest, BytesReportedCorrectly) { sizeof(payload), 0)); - EXPECT_GT(transport_.total_bytes_sent_, 0u); - EXPECT_EQ(transport_.total_bytes_sent_, rtp_sender_->Bytes()); - size_t last_bytes_sent = transport_.total_bytes_sent_; + // Will send 2 full-size padding packets. + rtp_sender_->TimeToSendPadding(1); + rtp_sender_->TimeToSendPadding(1); - rtp_sender_->TimeToSendPadding(42); + StreamDataCounters rtp_stats; + StreamDataCounters rtx_stats; + rtp_sender_->GetDataCounters(&rtp_stats, &rtx_stats); - EXPECT_GT(transport_.total_bytes_sent_, last_bytes_sent); - EXPECT_EQ(transport_.total_bytes_sent_, rtp_sender_->Bytes()); + // Payload + 1-byte generic header. + EXPECT_EQ(rtp_stats.bytes, sizeof(payload) + 1); + EXPECT_EQ(rtp_stats.header_bytes, 12u); + EXPECT_EQ(rtp_stats.padding_bytes, 0u); + EXPECT_EQ(rtx_stats.bytes, 0u); + EXPECT_EQ(rtx_stats.header_bytes, 24u); + EXPECT_EQ(rtx_stats.padding_bytes, 2 * kMaxPaddingSize); + + EXPECT_EQ(transport_.total_bytes_sent_, + rtp_stats.bytes + rtp_stats.header_bytes + rtp_stats.padding_bytes + + rtx_stats.bytes + rtx_stats.header_bytes + + rtx_stats.padding_bytes); } } // namespace webrtc diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc index a11a54cd02..76739a3d84 100644 --- a/webrtc/video/video_send_stream_tests.cc +++ b/webrtc/video/video_send_stream_tests.cc @@ -1436,4 +1436,48 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) { RunBaseTest(&test); } +TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) { + class RtcpByeTest : public test::SendTest { + public: + RtcpByeTest() : SendTest(kDefaultTimeoutMs), media_bytes_sent_(0) {} + + private: + virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { + RTPHeader header; + EXPECT_TRUE(parser_->Parse(packet, length, &header)); + media_bytes_sent_ += length - header.headerLength - header.paddingLength; + return SEND_PACKET; + } + + virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { + RTCPUtility::RTCPParserV2 parser(packet, length, true); + EXPECT_TRUE(parser.IsValid()); + + RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); + uint32_t sender_octet_count = 0; + while (packet_type != RTCPUtility::kRtcpNotValidCode) { + if (packet_type == RTCPUtility::kRtcpSrCode) { + sender_octet_count = parser.Packet().SR.SenderOctetCount; + EXPECT_EQ(sender_octet_count, media_bytes_sent_); + if (sender_octet_count > 0) + observation_complete_->Set(); + } + + packet_type = parser.Iterate(); + } + + return SEND_PACKET; + } + + virtual void PerformTest() OVERRIDE { + EXPECT_EQ(kEventSignaled, Wait()) + << "Timed out while waiting for RTCP sender report."; + } + + size_t media_bytes_sent_; + } test; + + RunBaseTest(&test); +} + } // namespace webrtc