Make RTCP sender report send media bytes.

r6654 changed RtpSender::Bytes() to return the number of bytes sent
instead of number of media bytes. This is used by VideoEngine for stats.
This change broke RTCP which sends this same count as the number of
payload bytes sent (excluding headers and padding).

BUG=
R=stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/14959004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6691 4adac7df-926f-26a2-2b94-8c16560cd09d
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 0514277..5e580a3 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 @@
   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 @@
   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 b38ae1f..54b991b 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -224,12 +224,12 @@
   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 @@
     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 ebffb7c..84eb24c 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -63,11 +63,11 @@
                   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 2cf7e1c..1edbee4 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -65,30 +65,11 @@
     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 @@
 
     //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 fad3b5e..26c44b0 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
@@ -51,13 +51,12 @@
 {
 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 cba1c34..b8d5395 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 @@
 
 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 @@
 
   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_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, 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, 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, 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, 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 @@
   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 @@
 
   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 349340f..1fb0c5d 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 @@
     }
 
     if (rtcp_sender_.TimeToSendRTCPReport()) {
-      RTCPSender::FeedbackState feedback_state(this);
-      rtcp_sender_.SendRTCP(feedback_state, kRtcpReport);
+      rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
     }
   }
 
@@ -418,12 +417,29 @@
   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 @@
 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 @@
   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 @@
 // 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 @@
 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 @@
   }
   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::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 @@
 
 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 @@
   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 7e7ea02..4a23dd4 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 @@
 
   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 @@
       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 c24b15a..340caa3 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -1061,17 +1061,11 @@
   }
 }
 
-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 4a9e10e..f6b7c6e 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
@@ -109,11 +109,8 @@
   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 40b1054..e9b01de 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 kAudioLevelExtensionId = 9;
 const int kAudioPayload = 103;
 const uint64_t kStartTime = 123456789;
+const size_t kMaxPaddingSize = 224u;
 }  // namespace
 
 using testing::_;
@@ -700,7 +701,7 @@
                                          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 @@
     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<size_t>(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<size_t>(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<size_t>(rtp_sender_->TimeToSendPadding(999)));
 }
 
 TEST_F(RtpSenderTest, SendGenericVideo) {
@@ -959,7 +962,6 @@
 
   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 @@
   // 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 @@
                                              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 @@
                                           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 a11a54c..76739a3 100644
--- a/webrtc/video/video_send_stream_tests.cc
+++ b/webrtc/video/video_send_stream_tests.cc
@@ -1436,4 +1436,48 @@
   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