LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/rtp_rtcp/source - receive_statistics_impl.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 258 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h"
      12             : 
      13             : #include <math.h>
      14             : 
      15             : #include <cstdlib>
      16             : 
      17             : #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
      18             : #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
      19             : #include "webrtc/modules/rtp_rtcp/source/time_util.h"
      20             : 
      21             : namespace webrtc {
      22             : 
      23             : const int64_t kStatisticsTimeoutMs = 8000;
      24             : const int64_t kStatisticsProcessIntervalMs = 1000;
      25             : 
      26           0 : StreamStatistician::~StreamStatistician() {}
      27             : 
      28           0 : StreamStatisticianImpl::StreamStatisticianImpl(
      29             :     Clock* clock,
      30             :     RtcpStatisticsCallback* rtcp_callback,
      31           0 :     StreamDataCountersCallback* rtp_callback)
      32             :     : clock_(clock),
      33             :       incoming_bitrate_(kStatisticsProcessIntervalMs,
      34             :                         RateStatistics::kBpsScale),
      35             :       ssrc_(0),
      36             :       max_reordering_threshold_(kDefaultMaxReorderingThreshold),
      37             :       jitter_q4_(0),
      38             :       cumulative_loss_(0),
      39             :       jitter_q4_transmission_time_offset_(0),
      40             :       last_receive_time_ms_(0),
      41             :       last_received_timestamp_(0),
      42             :       last_received_transmission_time_offset_(0),
      43             :       received_seq_first_(0),
      44             :       received_seq_max_(0),
      45             :       received_seq_wraps_(0),
      46             :       received_packet_overhead_(12),
      47             :       last_report_inorder_packets_(0),
      48             :       last_report_old_packets_(0),
      49             :       last_report_seq_max_(0),
      50             :       rtcp_callback_(rtcp_callback),
      51           0 :       rtp_callback_(rtp_callback) {}
      52             : 
      53           0 : void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header,
      54             :                                             size_t packet_length,
      55             :                                             bool retransmitted) {
      56           0 :   UpdateCounters(header, packet_length, retransmitted);
      57           0 :   NotifyRtpCallback();
      58           0 : }
      59             : 
      60           0 : void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
      61             :                                             size_t packet_length,
      62             :                                             bool retransmitted) {
      63           0 :   rtc::CritScope cs(&stream_lock_);
      64           0 :   bool in_order = InOrderPacketInternal(header.sequenceNumber);
      65           0 :   ssrc_ = header.ssrc;
      66           0 :   incoming_bitrate_.Update(packet_length, clock_->TimeInMilliseconds());
      67           0 :   receive_counters_.transmitted.AddPacket(packet_length, header);
      68           0 :   if (!in_order && retransmitted) {
      69           0 :     receive_counters_.retransmitted.AddPacket(packet_length, header);
      70             :   }
      71             : 
      72           0 :   if (receive_counters_.transmitted.packets == 1) {
      73           0 :     received_seq_first_ = header.sequenceNumber;
      74           0 :     receive_counters_.first_packet_time_ms = clock_->TimeInMilliseconds();
      75             :   }
      76             : 
      77             :   // Count only the new packets received. That is, if packets 1, 2, 3, 5, 4, 6
      78             :   // are received, 4 will be ignored.
      79           0 :   if (in_order) {
      80             :     // Current time in samples.
      81           0 :     NtpTime receive_time(*clock_);
      82             : 
      83             :     // Wrong if we use RetransmitOfOldPacket.
      84           0 :     if (receive_counters_.transmitted.packets > 1 &&
      85           0 :         received_seq_max_ > header.sequenceNumber) {
      86             :       // Wrap around detected.
      87           0 :       received_seq_wraps_++;
      88             :     }
      89             :     // New max.
      90           0 :     received_seq_max_ = header.sequenceNumber;
      91             : 
      92             :     // If new time stamp and more than one in-order packet received, calculate
      93             :     // new jitter statistics.
      94           0 :     if (header.timestamp != last_received_timestamp_ &&
      95           0 :         (receive_counters_.transmitted.packets -
      96           0 :          receive_counters_.retransmitted.packets) > 1) {
      97           0 :       UpdateJitter(header, receive_time);
      98             :     }
      99           0 :     last_received_timestamp_ = header.timestamp;
     100           0 :     last_receive_time_ntp_ = receive_time;
     101           0 :     last_receive_time_ms_ = clock_->TimeInMilliseconds();
     102             :   }
     103             : 
     104           0 :   size_t packet_oh = header.headerLength + header.paddingLength;
     105             : 
     106             :   // Our measured overhead. Filter from RFC 5104 4.2.1.2:
     107             :   // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH,
     108           0 :   received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4;
     109           0 : }
     110             : 
     111           0 : void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
     112             :                                           NtpTime receive_time) {
     113             :   uint32_t receive_time_rtp =
     114           0 :       NtpToRtp(receive_time, header.payload_type_frequency);
     115             :   uint32_t last_receive_time_rtp =
     116           0 :       NtpToRtp(last_receive_time_ntp_, header.payload_type_frequency);
     117           0 :   int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) -
     118           0 :       (header.timestamp - last_received_timestamp_);
     119             : 
     120           0 :   time_diff_samples = std::abs(time_diff_samples);
     121             : 
     122             :   // lib_jingle sometimes deliver crazy jumps in TS for the same stream.
     123             :   // If this happens, don't update jitter value. Use 5 secs video frequency
     124             :   // as the threshold.
     125           0 :   if (time_diff_samples < 450000) {
     126             :     // Note we calculate in Q4 to avoid using float.
     127           0 :     int32_t jitter_diff_q4 = (time_diff_samples << 4) - jitter_q4_;
     128           0 :     jitter_q4_ += ((jitter_diff_q4 + 8) >> 4);
     129             :   }
     130             : 
     131             :   // Extended jitter report, RFC 5450.
     132             :   // Actual network jitter, excluding the source-introduced jitter.
     133             :   int32_t time_diff_samples_ext =
     134           0 :     (receive_time_rtp - last_receive_time_rtp) -
     135           0 :     ((header.timestamp +
     136           0 :       header.extension.transmissionTimeOffset) -
     137           0 :      (last_received_timestamp_ +
     138           0 :       last_received_transmission_time_offset_));
     139             : 
     140           0 :   time_diff_samples_ext = std::abs(time_diff_samples_ext);
     141             : 
     142           0 :   if (time_diff_samples_ext < 450000) {
     143             :     int32_t jitter_diffQ4TransmissionTimeOffset =
     144           0 :       (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_;
     145           0 :     jitter_q4_transmission_time_offset_ +=
     146           0 :       ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4);
     147             :   }
     148           0 : }
     149             : 
     150           0 : void StreamStatisticianImpl::NotifyRtpCallback() {
     151           0 :   StreamDataCounters data;
     152             :   uint32_t ssrc;
     153             :   {
     154           0 :     rtc::CritScope cs(&stream_lock_);
     155           0 :     data = receive_counters_;
     156           0 :     ssrc = ssrc_;
     157             :   }
     158           0 :   rtp_callback_->DataCountersUpdated(data, ssrc);
     159           0 : }
     160             : 
     161           0 : void StreamStatisticianImpl::NotifyRtcpCallback() {
     162           0 :   RtcpStatistics data;
     163             :   uint32_t ssrc;
     164             :   {
     165           0 :     rtc::CritScope cs(&stream_lock_);
     166           0 :     data = last_reported_statistics_;
     167           0 :     ssrc = ssrc_;
     168             :   }
     169           0 :   rtcp_callback_->StatisticsUpdated(data, ssrc);
     170           0 : }
     171             : 
     172           0 : void StreamStatisticianImpl::FecPacketReceived(const RTPHeader& header,
     173             :                                                size_t packet_length) {
     174             :   {
     175           0 :     rtc::CritScope cs(&stream_lock_);
     176           0 :     receive_counters_.fec.AddPacket(packet_length, header);
     177             :   }
     178           0 :   NotifyRtpCallback();
     179           0 : }
     180             : 
     181           0 : void StreamStatisticianImpl::SetMaxReorderingThreshold(
     182             :     int max_reordering_threshold) {
     183           0 :   rtc::CritScope cs(&stream_lock_);
     184           0 :   max_reordering_threshold_ = max_reordering_threshold;
     185           0 : }
     186             : 
     187           0 : bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
     188             :                                            bool reset) {
     189             :   {
     190           0 :     rtc::CritScope cs(&stream_lock_);
     191           0 :     if (received_seq_first_ == 0 &&
     192           0 :         receive_counters_.transmitted.payload_bytes == 0) {
     193             :       // We have not received anything.
     194           0 :       return false;
     195             :     }
     196             : 
     197           0 :     if (!reset) {
     198           0 :       if (last_report_inorder_packets_ == 0) {
     199             :         // No report.
     200           0 :         return false;
     201             :       }
     202             :       // Just get last report.
     203           0 :       *statistics = last_reported_statistics_;
     204           0 :       return true;
     205             :     }
     206             : 
     207           0 :     *statistics = CalculateRtcpStatistics();
     208             :   }
     209             : 
     210           0 :   NotifyRtcpCallback();
     211             : 
     212           0 :   return true;
     213             : }
     214             : 
     215           0 : RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
     216           0 :   RtcpStatistics stats;
     217             : 
     218           0 :   if (last_report_inorder_packets_ == 0) {
     219             :     // First time we send a report.
     220           0 :     last_report_seq_max_ = received_seq_first_ - 1;
     221             :   }
     222             : 
     223             :   // Calculate fraction lost.
     224           0 :   uint16_t exp_since_last = (received_seq_max_ - last_report_seq_max_);
     225             : 
     226           0 :   if (last_report_seq_max_ > received_seq_max_) {
     227             :     // Can we assume that the seq_num can't go decrease over a full RTCP period?
     228           0 :     exp_since_last = 0;
     229             :   }
     230             : 
     231             :   // Number of received RTP packets since last report, counts all packets but
     232             :   // not re-transmissions.
     233             :   uint32_t rec_since_last =
     234           0 :       (receive_counters_.transmitted.packets -
     235           0 :        receive_counters_.retransmitted.packets) - last_report_inorder_packets_;
     236             : 
     237             :   // With NACK we don't know the expected retransmissions during the last
     238             :   // second. We know how many "old" packets we have received. We just count
     239             :   // the number of old received to estimate the loss, but it still does not
     240             :   // guarantee an exact number since we run this based on time triggered by
     241             :   // sending of an RTP packet. This should have a minimum effect.
     242             : 
     243             :   // With NACK we don't count old packets as received since they are
     244             :   // re-transmitted. We use RTT to decide if a packet is re-ordered or
     245             :   // re-transmitted.
     246             :   uint32_t retransmitted_packets =
     247           0 :       receive_counters_.retransmitted.packets - last_report_old_packets_;
     248           0 :   rec_since_last += retransmitted_packets;
     249             : 
     250           0 :   int32_t missing = 0;
     251           0 :   if (exp_since_last > rec_since_last) {
     252           0 :     missing = (exp_since_last - rec_since_last);
     253             :   }
     254           0 :   uint8_t local_fraction_lost = 0;
     255           0 :   if (exp_since_last) {
     256             :     // Scale 0 to 255, where 255 is 100% loss.
     257           0 :     local_fraction_lost =
     258           0 :         static_cast<uint8_t>(255 * missing / exp_since_last);
     259             :   }
     260           0 :   stats.fraction_lost = local_fraction_lost;
     261             : 
     262             :   // We need a counter for cumulative loss too.
     263             :   // TODO(danilchap): Ensure cumulative loss is below maximum value of 2^24.
     264           0 :   cumulative_loss_ += missing;
     265           0 :   stats.cumulative_lost = cumulative_loss_;
     266           0 :   stats.extended_max_sequence_number =
     267           0 :       (received_seq_wraps_ << 16) + received_seq_max_;
     268             :   // Note: internal jitter value is in Q4 and needs to be scaled by 1/16.
     269           0 :   stats.jitter = jitter_q4_ >> 4;
     270             : 
     271             :   // Store this report.
     272           0 :   last_reported_statistics_ = stats;
     273             : 
     274             :   // Only for report blocks in RTCP SR and RR.
     275           0 :   last_report_inorder_packets_ =
     276           0 :       receive_counters_.transmitted.packets -
     277           0 :       receive_counters_.retransmitted.packets;
     278           0 :   last_report_old_packets_ = receive_counters_.retransmitted.packets;
     279           0 :   last_report_seq_max_ = received_seq_max_;
     280             :   BWE_TEST_LOGGING_PLOT_WITH_SSRC(1, "cumulative_loss_pkts",
     281             :                                   clock_->TimeInMilliseconds(),
     282             :                                   cumulative_loss_, ssrc_);
     283             :   BWE_TEST_LOGGING_PLOT_WITH_SSRC(
     284             :       1, "received_seq_max_pkts", clock_->TimeInMilliseconds(),
     285             :       (received_seq_max_ - received_seq_first_), ssrc_);
     286             : 
     287           0 :   return stats;
     288             : }
     289             : 
     290           0 : void StreamStatisticianImpl::GetDataCounters(
     291             :     size_t* bytes_received, uint32_t* packets_received) const {
     292           0 :   rtc::CritScope cs(&stream_lock_);
     293           0 :   if (bytes_received) {
     294           0 :     *bytes_received = receive_counters_.transmitted.payload_bytes +
     295           0 :                       receive_counters_.transmitted.header_bytes +
     296           0 :                       receive_counters_.transmitted.padding_bytes;
     297             :   }
     298           0 :   if (packets_received) {
     299           0 :     *packets_received = receive_counters_.transmitted.packets;
     300             :   }
     301           0 : }
     302             : 
     303           0 : void StreamStatisticianImpl::GetReceiveStreamDataCounters(
     304             :     StreamDataCounters* data_counters) const {
     305           0 :   rtc::CritScope cs(&stream_lock_);
     306           0 :   *data_counters = receive_counters_;
     307           0 : }
     308             : 
     309           0 : uint32_t StreamStatisticianImpl::BitrateReceived() const {
     310           0 :   rtc::CritScope cs(&stream_lock_);
     311           0 :   return incoming_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0);
     312             : }
     313             : 
     314           0 : void StreamStatisticianImpl::LastReceiveTimeNtp(uint32_t* secs,
     315             :                                                 uint32_t* frac) const {
     316           0 :   rtc::CritScope cs(&stream_lock_);
     317           0 :   *secs = last_receive_time_ntp_.seconds();
     318           0 :   *frac = last_receive_time_ntp_.fractions();
     319           0 : }
     320             : 
     321           0 : bool StreamStatisticianImpl::IsRetransmitOfOldPacket(
     322             :     const RTPHeader& header, int64_t min_rtt) const {
     323           0 :   rtc::CritScope cs(&stream_lock_);
     324           0 :   if (InOrderPacketInternal(header.sequenceNumber)) {
     325           0 :     return false;
     326             :   }
     327           0 :   uint32_t frequency_khz = header.payload_type_frequency / 1000;
     328           0 :   assert(frequency_khz > 0);
     329             : 
     330           0 :   int64_t time_diff_ms = clock_->TimeInMilliseconds() -
     331           0 :       last_receive_time_ms_;
     332             : 
     333             :   // Diff in time stamp since last received in order.
     334           0 :   uint32_t timestamp_diff = header.timestamp - last_received_timestamp_;
     335           0 :   uint32_t rtp_time_stamp_diff_ms = timestamp_diff / frequency_khz;
     336             : 
     337           0 :   int64_t max_delay_ms = 0;
     338           0 :   if (min_rtt == 0) {
     339             :     // Jitter standard deviation in samples.
     340           0 :     float jitter_std = sqrt(static_cast<float>(jitter_q4_ >> 4));
     341             : 
     342             :     // 2 times the standard deviation => 95% confidence.
     343             :     // And transform to milliseconds by dividing by the frequency in kHz.
     344           0 :     max_delay_ms = static_cast<int64_t>((2 * jitter_std) / frequency_khz);
     345             : 
     346             :     // Min max_delay_ms is 1.
     347           0 :     if (max_delay_ms == 0) {
     348           0 :       max_delay_ms = 1;
     349             :     }
     350             :   } else {
     351           0 :     max_delay_ms = (min_rtt / 3) + 1;
     352             :   }
     353           0 :   return time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms;
     354             : }
     355             : 
     356           0 : bool StreamStatisticianImpl::IsPacketInOrder(uint16_t sequence_number) const {
     357           0 :   rtc::CritScope cs(&stream_lock_);
     358           0 :   return InOrderPacketInternal(sequence_number);
     359             : }
     360             : 
     361           0 : bool StreamStatisticianImpl::InOrderPacketInternal(
     362             :     uint16_t sequence_number) const {
     363             :   // First packet is always in order.
     364           0 :   if (last_receive_time_ms_ == 0)
     365           0 :     return true;
     366             : 
     367           0 :   if (IsNewerSequenceNumber(sequence_number, received_seq_max_)) {
     368           0 :     return true;
     369             :   } else {
     370             :     // If we have a restart of the remote side this packet is still in order.
     371           0 :     return !IsNewerSequenceNumber(sequence_number, received_seq_max_ -
     372           0 :                                   max_reordering_threshold_);
     373             :   }
     374             : }
     375             : 
     376           0 : ReceiveStatistics* ReceiveStatistics::Create(Clock* clock) {
     377           0 :   return new ReceiveStatisticsImpl(clock);
     378             : }
     379             : 
     380           0 : ReceiveStatisticsImpl::ReceiveStatisticsImpl(Clock* clock)
     381             :     : clock_(clock),
     382             :       rtcp_stats_callback_(NULL),
     383           0 :       rtp_stats_callback_(NULL) {}
     384             : 
     385           0 : ReceiveStatisticsImpl::~ReceiveStatisticsImpl() {
     386           0 :   while (!statisticians_.empty()) {
     387           0 :     delete statisticians_.begin()->second;
     388           0 :     statisticians_.erase(statisticians_.begin());
     389             :   }
     390           0 : }
     391             : 
     392           0 : void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
     393             :                                            size_t packet_length,
     394             :                                            bool retransmitted) {
     395             :   StreamStatisticianImpl* impl;
     396             :   {
     397           0 :     rtc::CritScope cs(&receive_statistics_lock_);
     398           0 :     StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
     399           0 :     if (it != statisticians_.end()) {
     400           0 :       impl = it->second;
     401             :     } else {
     402           0 :       impl = new StreamStatisticianImpl(clock_, this, this);
     403           0 :       statisticians_[header.ssrc] = impl;
     404             :     }
     405             :   }
     406             :   // StreamStatisticianImpl instance is created once and only destroyed when
     407             :   // this whole ReceiveStatisticsImpl is destroyed. StreamStatisticianImpl has
     408             :   // it's own locking so don't hold receive_statistics_lock_ (potential
     409             :   // deadlock).
     410           0 :   impl->IncomingPacket(header, packet_length, retransmitted);
     411           0 : }
     412             : 
     413           0 : void ReceiveStatisticsImpl::FecPacketReceived(const RTPHeader& header,
     414             :                                               size_t packet_length) {
     415           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     416           0 :   StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
     417             :   // Ignore FEC if it is the first packet.
     418           0 :   if (it != statisticians_.end()) {
     419           0 :     it->second->FecPacketReceived(header, packet_length);
     420             :   }
     421           0 : }
     422             : 
     423           0 : StatisticianMap ReceiveStatisticsImpl::GetActiveStatisticians() const {
     424           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     425           0 :   StatisticianMap active_statisticians;
     426           0 :   for (StatisticianImplMap::const_iterator it = statisticians_.begin();
     427           0 :        it != statisticians_.end(); ++it) {
     428             :     uint32_t secs;
     429             :     uint32_t frac;
     430           0 :     it->second->LastReceiveTimeNtp(&secs, &frac);
     431           0 :     if (clock_->CurrentNtpInMilliseconds() -
     432           0 :         Clock::NtpToMs(secs, frac) < kStatisticsTimeoutMs) {
     433           0 :       active_statisticians[it->first] = it->second;
     434             :     }
     435             :   }
     436           0 :   return active_statisticians;
     437             : }
     438             : 
     439           0 : StreamStatistician* ReceiveStatisticsImpl::GetStatistician(
     440             :     uint32_t ssrc) const {
     441           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     442           0 :   StatisticianImplMap::const_iterator it = statisticians_.find(ssrc);
     443           0 :   if (it == statisticians_.end())
     444           0 :     return NULL;
     445           0 :   return it->second;
     446             : }
     447             : 
     448           0 : void ReceiveStatisticsImpl::SetMaxReorderingThreshold(
     449             :     int max_reordering_threshold) {
     450           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     451           0 :   for (StatisticianImplMap::iterator it = statisticians_.begin();
     452           0 :        it != statisticians_.end(); ++it) {
     453           0 :     it->second->SetMaxReorderingThreshold(max_reordering_threshold);
     454             :   }
     455           0 : }
     456             : 
     457           0 : void ReceiveStatisticsImpl::RegisterRtcpStatisticsCallback(
     458             :     RtcpStatisticsCallback* callback) {
     459           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     460           0 :   if (callback != NULL)
     461           0 :     assert(rtcp_stats_callback_ == NULL);
     462           0 :   rtcp_stats_callback_ = callback;
     463           0 : }
     464             : 
     465           0 : void ReceiveStatisticsImpl::StatisticsUpdated(const RtcpStatistics& statistics,
     466             :                                               uint32_t ssrc) {
     467           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     468           0 :   if (rtcp_stats_callback_)
     469           0 :     rtcp_stats_callback_->StatisticsUpdated(statistics, ssrc);
     470           0 : }
     471             : 
     472           0 : void ReceiveStatisticsImpl::CNameChanged(const char* cname, uint32_t ssrc) {
     473           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     474           0 :   if (rtcp_stats_callback_)
     475           0 :     rtcp_stats_callback_->CNameChanged(cname, ssrc);
     476           0 : }
     477             : 
     478           0 : void ReceiveStatisticsImpl::RegisterRtpStatisticsCallback(
     479             :     StreamDataCountersCallback* callback) {
     480           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     481           0 :   if (callback != NULL)
     482           0 :     assert(rtp_stats_callback_ == NULL);
     483           0 :   rtp_stats_callback_ = callback;
     484           0 : }
     485             : 
     486           0 : void ReceiveStatisticsImpl::DataCountersUpdated(const StreamDataCounters& stats,
     487             :                                                 uint32_t ssrc) {
     488           0 :   rtc::CritScope cs(&receive_statistics_lock_);
     489           0 :   if (rtp_stats_callback_) {
     490           0 :     rtp_stats_callback_->DataCountersUpdated(stats, ssrc);
     491             :   }
     492           0 : }
     493             : 
     494           0 : void NullReceiveStatistics::IncomingPacket(const RTPHeader& rtp_header,
     495             :                                            size_t packet_length,
     496           0 :                                            bool retransmitted) {}
     497             : 
     498           0 : void NullReceiveStatistics::FecPacketReceived(const RTPHeader& header,
     499           0 :                                               size_t packet_length) {}
     500             : 
     501           0 : StatisticianMap NullReceiveStatistics::GetActiveStatisticians() const {
     502           0 :   return StatisticianMap();
     503             : }
     504             : 
     505           0 : StreamStatistician* NullReceiveStatistics::GetStatistician(
     506             :     uint32_t ssrc) const {
     507           0 :   return NULL;
     508             : }
     509             : 
     510           0 : void NullReceiveStatistics::SetMaxReorderingThreshold(
     511           0 :     int max_reordering_threshold) {}
     512             : 
     513           0 : void NullReceiveStatistics::RegisterRtcpStatisticsCallback(
     514           0 :     RtcpStatisticsCallback* callback) {}
     515             : 
     516           0 : void NullReceiveStatistics::RegisterRtpStatisticsCallback(
     517           0 :     StreamDataCountersCallback* callback) {}
     518             : 
     519             : }  // namespace webrtc

Generated by: LCOV version 1.13