Fix for sent/received RTCP packet counters returned by GetRtcpPacketTypeCounters. The returned counters are  incorrect: sent_packets returns stats from a sent stream (and received_packets returns stats from a receive stream).

Add separate functions for returning stats from send/receive stream and updated how functions are used.

Add test implementation for histogram methods in system_wrappers/interface/metrics.h.

BUG=4519
R=pbos@webrtc.org, stefan@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#9009}
diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h
index f792456..ee22a42 100644
--- a/talk/media/webrtc/fakewebrtcvideoengine.h
+++ b/talk/media/webrtc/fakewebrtcvideoengine.h
@@ -1176,8 +1176,10 @@
         reserved_transmit_bitrate_bps;
     return 0;
   }
-  WEBRTC_STUB_CONST(GetRtcpPacketTypeCounters, (int,
-      webrtc::RtcpPacketTypeCounter*, webrtc::RtcpPacketTypeCounter*));
+  WEBRTC_STUB_CONST(GetSendRtcpPacketTypeCounter, (int,
+      webrtc::RtcpPacketTypeCounter*));
+  WEBRTC_STUB_CONST(GetReceiveRtcpPacketTypeCounter, (int,
+      webrtc::RtcpPacketTypeCounter*));
   WEBRTC_STUB_CONST(GetReceivedRTCPStatistics, (const int, unsigned short&,
       unsigned int&, unsigned int&, unsigned int&, int64_t&));
   WEBRTC_STUB_CONST(GetSentRTCPStatistics, (const int, unsigned short&,
diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc
index a103cae..24b6bb6 100644
--- a/talk/media/webrtc/webrtcvideoengine.cc
+++ b/talk/media/webrtc/webrtcvideoengine.cc
@@ -2646,13 +2646,12 @@
       sinfo.avg_encode_ms = metrics.avg_encode_time_ms;
       sinfo.encode_usage_percent = metrics.encode_usage_percent;
 
-      webrtc::RtcpPacketTypeCounter rtcp_sent;
-      webrtc::RtcpPacketTypeCounter rtcp_received;
-      if (engine()->vie()->rtp()->GetRtcpPacketTypeCounters(
-          channel_id, &rtcp_sent, &rtcp_received) == 0) {
-        sinfo.firs_rcvd = rtcp_received.fir_packets;
-        sinfo.plis_rcvd = rtcp_received.pli_packets;
-        sinfo.nacks_rcvd = rtcp_received.nack_packets;
+      webrtc::RtcpPacketTypeCounter rtcp_counter;
+      if (engine()->vie()->rtp()->GetSendRtcpPacketTypeCounter(
+          channel_id, &rtcp_counter) == 0) {
+        sinfo.firs_rcvd = rtcp_counter.fir_packets;
+        sinfo.plis_rcvd = rtcp_counter.pli_packets;
+        sinfo.nacks_rcvd = rtcp_counter.nack_packets;
       } else {
         sinfo.firs_rcvd = -1;
         sinfo.plis_rcvd = -1;
@@ -2753,13 +2752,12 @@
         channel->render_adapter()->capture_start_ntp_time_ms();
     channel->decoder_observer()->ExportTo(&rinfo);
 
-    webrtc::RtcpPacketTypeCounter rtcp_sent;
-    webrtc::RtcpPacketTypeCounter rtcp_received;
-    if (engine()->vie()->rtp()->GetRtcpPacketTypeCounters(
-        channel->channel_id(), &rtcp_sent, &rtcp_received) == 0) {
-      rinfo.firs_sent = rtcp_sent.fir_packets;
-      rinfo.plis_sent = rtcp_sent.pli_packets;
-      rinfo.nacks_sent = rtcp_sent.nack_packets;
+    webrtc::RtcpPacketTypeCounter rtcp_counter;
+    if (engine()->vie()->rtp()->GetReceiveRtcpPacketTypeCounter(
+        channel->channel_id(), &rtcp_counter) == 0) {
+      rinfo.firs_sent = rtcp_counter.fir_packets;
+      rinfo.plis_sent = rtcp_counter.pli_packets;
+      rinfo.nacks_sent = rtcp_counter.nack_packets;
     } else {
       rinfo.firs_sent = -1;
       rinfo.plis_sent = -1;
diff --git a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 92cd302..86a792a 100644
--- a/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -178,8 +178,6 @@
       int32_t(const uint32_t SSRC, const RTCPReportBlock* receiveBlock));
   MOCK_METHOD1(RemoveRTCPReportBlock,
       int32_t(const uint32_t SSRC));
-  MOCK_CONST_METHOD2(GetRtcpPacketTypeCounters,
-      void(RtcpPacketTypeCounter*, RtcpPacketTypeCounter*));
   MOCK_METHOD4(SetRTCPApplicationSpecificData,
       int32_t(const uint8_t subType, const uint32_t name, const uint8_t* data, const uint16_t length));
   MOCK_METHOD1(SetRTCPVoIPMetrics,
diff --git a/webrtc/test/BUILD.gn b/webrtc/test/BUILD.gn
index cfb089f..337dcf6 100644
--- a/webrtc/test/BUILD.gn
+++ b/webrtc/test/BUILD.gn
@@ -33,6 +33,21 @@
   public_configs = [ "..:common_inherited_config"]
 }
 
+source_set("histogram") {
+  sources = [
+    "histogram.cc",
+    "histogram.h",
+  ]
+
+  deps = [
+    "..:webrtc_common",
+    "../system_wrappers",
+  ]
+
+  configs += [ "..:common_config" ]
+  public_configs = [ "..:common_inherited_config"]
+}
+
 source_set("test_support") {
   testonly = true
 
@@ -80,8 +95,8 @@
 
   deps = [
     ":field_trial",
+    ":histogram",
     ":test_support",
-    "../system_wrappers:metrics_default",
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/gflags",
diff --git a/webrtc/test/histogram.cc b/webrtc/test/histogram.cc
new file mode 100644
index 0000000..4230715
--- /dev/null
+++ b/webrtc/test/histogram.cc
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/test/histogram.h"
+
+#include <map>
+
+#include "webrtc/system_wrappers/interface/metrics.h"
+
+// Test implementation of histogram methods in
+// webrtc/system_wrappers/interface/metrics.h.
+
+namespace webrtc {
+namespace {
+// Map holding the last added sample to a histogram (mapped by histogram name).
+std::map<std::string, int> histograms_;
+}  // namespace
+
+namespace metrics {
+Histogram* HistogramFactoryGetCounts(const std::string& name, int min, int max,
+    int bucket_count) { return NULL; }
+
+Histogram* HistogramFactoryGetEnumeration(const std::string& name,
+    int boundary) { return NULL; }
+
+void HistogramAdd(
+    Histogram* histogram_pointer, const std::string& name, int sample) {
+  histograms_[name] = sample;
+}
+}  // namespace metrics
+
+namespace test {
+int LastHistogramSample(const std::string& name) {
+  std::map<std::string, int>::const_iterator it = histograms_.find(name);
+  if (it == histograms_.end()) {
+    return -1;
+  }
+  return it->second;
+}
+}  // namespace test
+}  // namespace webrtc
+
diff --git a/webrtc/test/histogram.h b/webrtc/test/histogram.h
new file mode 100644
index 0000000..213fc8c
--- /dev/null
+++ b/webrtc/test/histogram.h
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_TEST_HISTOGRAM_H_
+#define WEBRTC_TEST_HISTOGRAM_H_
+
+#include <string>
+
+namespace webrtc {
+namespace test {
+
+// Returns the last added sample to a histogram (or -1 if the histogram is not
+// found).
+int LastHistogramSample(const std::string& name);
+
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // WEBRTC_TEST_HISTOGRAM_H_
+
diff --git a/webrtc/test/test.gyp b/webrtc/test/test.gyp
index e464aac..ea831a1 100644
--- a/webrtc/test/test.gyp
+++ b/webrtc/test/test.gyp
@@ -83,6 +83,18 @@
       ],
     },
     {
+      'target_name': 'histogram',
+      'type': 'static_library',
+      'sources': [
+        'histogram.cc',
+        'histogram.h',
+      ],
+      'dependencies': [
+        '<(webrtc_root)/common.gyp:webrtc_common',
+        '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers',
+      ],
+    },
+    {
       'target_name': 'test_main',
       'type': 'static_library',
       'sources': [
@@ -90,9 +102,9 @@
       ],
       'dependencies': [
         'field_trial',
+        'histogram',
         '<(DEPTH)/testing/gtest.gyp:gtest',
         '<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
-        '<(webrtc_root)/system_wrappers/system_wrappers.gyp:metrics_default',
       ],
     },
     {
@@ -129,11 +141,11 @@
       'type': 'static_library',
       'dependencies': [
         'field_trial',
+        'histogram',
         'test_support',
         '<(DEPTH)/testing/gmock.gyp:gmock',
         '<(DEPTH)/testing/gtest.gyp:gtest',
         '<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
-        '<(webrtc_root)/system_wrappers/system_wrappers.gyp:metrics_default',
       ],
       'sources': [
         'run_all_unittests.cc',
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 110ab86..956e821 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -24,6 +24,7 @@
 #include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 #include "webrtc/system_wrappers/interface/event_wrapper.h"
+#include "webrtc/system_wrappers/interface/metrics.h"
 #include "webrtc/system_wrappers/interface/sleep.h"
 #include "webrtc/test/call_test.h"
 #include "webrtc/test/direct_transport.h"
@@ -33,6 +34,7 @@
 #include "webrtc/test/fake_encoder.h"
 #include "webrtc/test/frame_generator.h"
 #include "webrtc/test/frame_generator_capturer.h"
+#include "webrtc/test/histogram.h"
 #include "webrtc/test/null_transport.h"
 #include "webrtc/test/rtcp_packet_parser.h"
 #include "webrtc/test/rtp_rtcp_observer.h"
@@ -1376,6 +1378,115 @@
   RunBaseTest(&test);
 }
 
+TEST_F(EndToEndTest, VerifyNackStats) {
+  static const int kPacketNumberToDrop = 200;
+  class NackObserver : public test::EndToEndTest {
+   public:
+    NackObserver()
+        : EndToEndTest(kLongTimeoutMs),
+          sent_rtp_packets_(0),
+          dropped_rtp_packet_(0),
+          dropped_rtp_packet_requested_(false),
+          send_stream_(nullptr),
+          start_runtime_ms_(-1) {}
+
+   private:
+    Action OnSendRtp(const uint8_t* packet, size_t length) override {
+      if (++sent_rtp_packets_ == kPacketNumberToDrop) {
+        rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
+        RTPHeader header;
+        EXPECT_TRUE(parser->Parse(packet, length, &header));
+        dropped_rtp_packet_ = header.sequenceNumber;
+        return DROP_PACKET;
+      }
+      VerifyStats();
+      return SEND_PACKET;
+    }
+
+    Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
+      test::RtcpPacketParser rtcp_parser;
+      rtcp_parser.Parse(packet, length);
+      std::vector<uint16_t> nacks = rtcp_parser.nack_item()->last_nack_list();
+      if (!nacks.empty() && std::find(
+          nacks.begin(), nacks.end(), dropped_rtp_packet_) != nacks.end()) {
+        dropped_rtp_packet_requested_ = true;
+      }
+      return SEND_PACKET;
+    }
+
+    void VerifyStats() {
+      if (!dropped_rtp_packet_requested_)
+        return;
+      int send_stream_nack_packets = 0;
+      int receive_stream_nack_packets = 0;
+      VideoSendStream::Stats stats = send_stream_->GetStats();
+      for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
+           stats.substreams.begin(); it != stats.substreams.end(); ++it) {
+        const VideoSendStream::StreamStats& stream_stats = it->second;
+        send_stream_nack_packets +=
+            stream_stats.rtcp_packet_type_counts.nack_packets;
+      }
+      for (size_t i = 0; i < receive_streams_.size(); ++i) {
+        VideoReceiveStream::Stats stats = receive_streams_[i]->GetStats();
+        receive_stream_nack_packets +=
+            stats.rtcp_packet_type_counts.nack_packets;
+      }
+      if (send_stream_nack_packets >= 1 && receive_stream_nack_packets >= 1) {
+        // NACK packet sent on receive stream and received on sent stream.
+        if (MinMetricRunTimePassed())
+          observation_complete_->Set();
+      }
+    }
+
+    bool MinMetricRunTimePassed() {
+      int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds();
+      if (start_runtime_ms_ == -1) {
+        start_runtime_ms_ = now;
+        return false;
+      }
+      int64_t elapsed_sec = (now - start_runtime_ms_) / 1000;
+      return elapsed_sec > metrics::kMinRunTimeInSeconds;
+    }
+
+    void ModifyConfigs(VideoSendStream::Config* send_config,
+                       std::vector<VideoReceiveStream::Config>* receive_configs,
+                       VideoEncoderConfig* encoder_config) override {
+      send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
+      (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
+    }
+
+    void OnStreamsCreated(
+        VideoSendStream* send_stream,
+        const std::vector<VideoReceiveStream*>& receive_streams) override {
+      send_stream_ = send_stream;
+      receive_streams_ = receive_streams;
+    }
+
+    void PerformTest() override {
+      EXPECT_EQ(kEventSignaled, Wait())
+          << "Timed out waiting for packet to be NACKed.";
+    }
+
+    uint64_t sent_rtp_packets_;
+    uint16_t dropped_rtp_packet_;
+    bool dropped_rtp_packet_requested_;
+    std::vector<VideoReceiveStream*> receive_streams_;
+    VideoSendStream* send_stream_;
+    int64_t start_runtime_ms_;
+  } test;
+
+  RunBaseTest(&test);
+
+  EXPECT_NE(-1, test::LastHistogramSample(
+      "WebRTC.Video.UniqueNackRequestsSentInPercent"));
+  EXPECT_NE(-1, test::LastHistogramSample(
+      "WebRTC.Video.UniqueNackRequestsReceivedInPercent"));
+  EXPECT_GT(test::LastHistogramSample(
+      "WebRTC.Video.NackPacketsSentPerMinute"), 0);
+  EXPECT_GT(test::LastHistogramSample(
+      "WebRTC.Video.NackPacketsReceivedPerMinute"), 0);
+}
+
 void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
   static const int kNumRtcpReportPacketsToObserve = 5;
   class RtcpXrObserver : public test::EndToEndTest {
diff --git a/webrtc/video_engine/include/vie_rtp_rtcp.h b/webrtc/video_engine/include/vie_rtp_rtcp.h
index d9a6a1f..a57e4f3 100644
--- a/webrtc/video_engine/include/vie_rtp_rtcp.h
+++ b/webrtc/video_engine/include/vie_rtp_rtcp.h
@@ -377,12 +377,14 @@
       int video_channel, StreamDataCountersCallback* callback) = 0;
 
 
-  // Gets sent and received RTCP packet types.
-  // TODO(asapersson): Remove default implementation.
-  virtual int GetRtcpPacketTypeCounters(
+  // Gets RTCP packet type statistics from a sent/received stream.
+  virtual int GetSendRtcpPacketTypeCounter(
       int video_channel,
-      RtcpPacketTypeCounter* packets_sent,
-      RtcpPacketTypeCounter* packets_received) const { return -1; }
+      RtcpPacketTypeCounter* packet_counter) const = 0;
+
+  virtual int GetReceiveRtcpPacketTypeCounter(
+      int video_channel,
+      RtcpPacketTypeCounter* packet_counter) const = 0;
 
   // The function gets bandwidth usage statistics from the sent RTP streams in
   // bits/s.
diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc
index 1c7818e..1b78dbd 100644
--- a/webrtc/video_engine/vie_channel.cc
+++ b/webrtc/video_engine/vie_channel.cc
@@ -232,23 +232,22 @@
 
 void ViEChannel::UpdateHistograms() {
   int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds();
-  RtcpPacketTypeCounter rtcp_sent;
-  RtcpPacketTypeCounter rtcp_received;
-  GetRtcpPacketTypeCounters(&rtcp_sent, &rtcp_received);
 
   if (sender_) {
-    int64_t elapsed_sec = rtcp_received.TimeSinceFirstPacketInMs(now) / 1000;
+    RtcpPacketTypeCounter rtcp_counter;
+    GetSendRtcpPacketTypeCounter(&rtcp_counter);
+    int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000;
     if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
       RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute",
-          rtcp_received.nack_packets * 60 / elapsed_sec);
+          rtcp_counter.nack_packets * 60 / elapsed_sec);
       RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute",
-          rtcp_received.fir_packets * 60 / elapsed_sec);
+          rtcp_counter.fir_packets * 60 / elapsed_sec);
       RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute",
-          rtcp_received.pli_packets * 60 / elapsed_sec);
-      if (rtcp_received.nack_requests > 0) {
+          rtcp_counter.pli_packets * 60 / elapsed_sec);
+      if (rtcp_counter.nack_requests > 0) {
         RTC_HISTOGRAM_PERCENTAGE(
             "WebRTC.Video.UniqueNackRequestsReceivedInPercent",
-                rtcp_received.UniqueNackRequestsInPercent());
+                rtcp_counter.UniqueNackRequestsInPercent());
       }
       int fraction_lost = report_block_stats_sender_->FractionLostInPercent();
       if (fraction_lost != -1) {
@@ -259,17 +258,19 @@
   } else if (vie_receiver_.GetRemoteSsrc() > 0) {
     // Get receive stats if we are receiving packets, i.e. there is a remote
     // ssrc.
-    int64_t elapsed_sec = rtcp_sent.TimeSinceFirstPacketInMs(now) / 1000;
+    RtcpPacketTypeCounter rtcp_counter;
+    GetReceiveRtcpPacketTypeCounter(&rtcp_counter);
+    int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000;
     if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
       RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsSentPerMinute",
-          rtcp_sent.nack_packets * 60 / elapsed_sec);
+          rtcp_counter.nack_packets * 60 / elapsed_sec);
       RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsSentPerMinute",
-          rtcp_sent.fir_packets * 60 / elapsed_sec);
+          rtcp_counter.fir_packets * 60 / elapsed_sec);
       RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute",
-          rtcp_sent.pli_packets * 60 / elapsed_sec);
-      if (rtcp_sent.nack_requests > 0) {
+          rtcp_counter.pli_packets * 60 / elapsed_sec);
+      if (rtcp_counter.nack_requests > 0) {
         RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent",
-            rtcp_sent.UniqueNackRequestsInPercent());
+            rtcp_counter.UniqueNackRequestsInPercent());
       }
       int fraction_lost = report_block_stats_receiver_->FractionLostInPercent();
       if (fraction_lost != -1) {
@@ -1357,27 +1358,35 @@
   vie_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(callback);
 }
 
-void ViEChannel::GetRtcpPacketTypeCounters(
-    RtcpPacketTypeCounter* packets_sent,
-    RtcpPacketTypeCounter* packets_received) const {
+void ViEChannel::GetSendRtcpPacketTypeCounter(
+    RtcpPacketTypeCounter* packet_counter) const {
   std::map<uint32_t, RtcpPacketTypeCounter> counter_map =
       rtcp_packet_type_counter_observer_.GetPacketTypeCounterMap();
-  RtcpPacketTypeCounter sent_counter;
-  sent_counter.Add(counter_map[rtp_rtcp_->SSRC()]);
-  RtcpPacketTypeCounter received_counter;
-  received_counter.Add(counter_map[vie_receiver_.GetRemoteSsrc()]);
+
+  RtcpPacketTypeCounter counter;
+  counter.Add(counter_map[rtp_rtcp_->SSRC()]);
 
   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
   for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
        it != simulcast_rtp_rtcp_.end(); ++it) {
-    sent_counter.Add(counter_map[(*it)->SSRC()]);
+    counter.Add(counter_map[(*it)->SSRC()]);
   }
   for (std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
        it != removed_rtp_rtcp_.end(); ++it) {
-    sent_counter.Add(counter_map[(*it)->SSRC()]);
+    counter.Add(counter_map[(*it)->SSRC()]);
   }
-  *packets_sent = sent_counter;
-  *packets_received = received_counter;
+  *packet_counter = counter;
+}
+
+void ViEChannel::GetReceiveRtcpPacketTypeCounter(
+    RtcpPacketTypeCounter* packet_counter) const {
+  std::map<uint32_t, RtcpPacketTypeCounter> counter_map =
+      rtcp_packet_type_counter_observer_.GetPacketTypeCounterMap();
+
+  RtcpPacketTypeCounter counter;
+  counter.Add(counter_map[vie_receiver_.GetRemoteSsrc()]);
+
+  *packet_counter = counter;
 }
 
 void ViEChannel::GetBandwidthUsage(uint32_t* total_bitrate_sent,
diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h
index 47724d1..a3ad722 100644
--- a/webrtc/video_engine/vie_channel.h
+++ b/webrtc/video_engine/vie_channel.h
@@ -219,8 +219,11 @@
   void RegisterReceiveChannelRtpStatisticsCallback(
       StreamDataCountersCallback* callback);
 
-  void GetRtcpPacketTypeCounters(RtcpPacketTypeCounter* packets_sent,
-                                 RtcpPacketTypeCounter* packets_received) const;
+  void GetSendRtcpPacketTypeCounter(
+      RtcpPacketTypeCounter* packet_counter) const;
+
+  void GetReceiveRtcpPacketTypeCounter(
+      RtcpPacketTypeCounter* packet_counter) const;
 
   void GetBandwidthUsage(uint32_t* total_bitrate_sent,
                          uint32_t* video_bitrate_sent,
diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.cc b/webrtc/video_engine/vie_rtp_rtcp_impl.cc
index 5aab8d6..4fbf11b 100644
--- a/webrtc/video_engine/vie_rtp_rtcp_impl.cc
+++ b/webrtc/video_engine/vie_rtp_rtcp_impl.cc
@@ -774,17 +774,29 @@
   return 0;
 }
 
-int ViERTP_RTCPImpl::GetRtcpPacketTypeCounters(
+int ViERTP_RTCPImpl::GetSendRtcpPacketTypeCounter(
     int video_channel,
-    RtcpPacketTypeCounter* packets_sent,
-    RtcpPacketTypeCounter* packets_received) const {
+    RtcpPacketTypeCounter* packet_counter) const {
   ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
   ViEChannel* vie_channel = cs.Channel(video_channel);
   if (!vie_channel) {
     shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
     return -1;
   }
-  vie_channel->GetRtcpPacketTypeCounters(packets_sent, packets_received);
+  vie_channel->GetSendRtcpPacketTypeCounter(packet_counter);
+  return 0;
+}
+
+int ViERTP_RTCPImpl::GetReceiveRtcpPacketTypeCounter(
+    int video_channel,
+    RtcpPacketTypeCounter* packet_counter) const {
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
+    return -1;
+  }
+  vie_channel->GetReceiveRtcpPacketTypeCounter(packet_counter);
   return 0;
 }
 
diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.h b/webrtc/video_engine/vie_rtp_rtcp_impl.h
index b6f3a23..7894f59 100644
--- a/webrtc/video_engine/vie_rtp_rtcp_impl.h
+++ b/webrtc/video_engine/vie_rtp_rtcp_impl.h
@@ -111,10 +111,12 @@
   virtual int GetRtpStatistics(const int video_channel,
                                StreamDataCounters& sent,
                                StreamDataCounters& received) const;
-  virtual int GetRtcpPacketTypeCounters(
+  virtual int GetSendRtcpPacketTypeCounter(
       int video_channel,
-      RtcpPacketTypeCounter* packets_sent,
-      RtcpPacketTypeCounter* packets_received) const;
+      RtcpPacketTypeCounter* packet_counter) const;
+  virtual int GetReceiveRtcpPacketTypeCounter(
+      int video_channel,
+      RtcpPacketTypeCounter* packet_counter) const;
   virtual int GetBandwidthUsage(const int video_channel,
                                 unsigned int& total_bitrate_sent,
                                 unsigned int& video_bitrate_sent,
@@ -141,9 +143,9 @@
   virtual int DeregisterSendChannelRtcpStatisticsCallback(
       int channel, RtcpStatisticsCallback* callback);
   virtual int RegisterReceiveChannelRtcpStatisticsCallback(
-        int channel, RtcpStatisticsCallback* callback);
-    virtual int DeregisterReceiveChannelRtcpStatisticsCallback(
-        int channel, RtcpStatisticsCallback* callback);
+      int channel, RtcpStatisticsCallback* callback);
+  virtual int DeregisterReceiveChannelRtcpStatisticsCallback(
+      int channel, RtcpStatisticsCallback* callback);
   virtual int RegisterSendChannelRtpStatisticsCallback(
       int channel, StreamDataCountersCallback* callback);
   virtual int DeregisterSendChannelRtpStatisticsCallback(