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

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2015 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/packet_loss_stats.h"
      12             : 
      13             : #include <vector>
      14             : 
      15             : #include "webrtc/base/checks.h"
      16             : 
      17             : // After this many packets are added, adding additional packets will cause the
      18             : // oldest packets to be pruned from the buffer.
      19             : static const int kBufferSize = 100;
      20             : 
      21             : namespace webrtc {
      22             : 
      23           0 : PacketLossStats::PacketLossStats()
      24             :     : single_loss_historic_count_(0),
      25             :       multiple_loss_historic_event_count_(0),
      26           0 :       multiple_loss_historic_packet_count_(0) {
      27           0 : }
      28             : 
      29           0 : void PacketLossStats::AddLostPacket(uint16_t sequence_number) {
      30             :   // Detect sequence number wrap around.
      31           0 :   if (!lost_packets_buffer_.empty() &&
      32           0 :       static_cast<int>(*(lost_packets_buffer_.rbegin())) - sequence_number
      33             :       > 0x8000) {
      34             :     // The buffer contains large numbers and this is a small number.
      35           0 :     lost_packets_wrapped_buffer_.insert(sequence_number);
      36             :   } else {
      37           0 :     lost_packets_buffer_.insert(sequence_number);
      38             :   }
      39           0 :   if (lost_packets_wrapped_buffer_.size() + lost_packets_buffer_.size()
      40           0 :       > kBufferSize || (!lost_packets_wrapped_buffer_.empty() &&
      41           0 :                         *(lost_packets_wrapped_buffer_.rbegin()) > 0x4000)) {
      42           0 :     PruneBuffer();
      43             :   }
      44           0 : }
      45             : 
      46           0 : int PacketLossStats::GetSingleLossCount() const {
      47             :   int single_loss_count, unused1, unused2;
      48           0 :   ComputeLossCounts(&single_loss_count, &unused1, &unused2);
      49           0 :   return single_loss_count;
      50             : }
      51             : 
      52           0 : int PacketLossStats::GetMultipleLossEventCount() const {
      53             :   int event_count, unused1, unused2;
      54           0 :   ComputeLossCounts(&unused1, &event_count, &unused2);
      55           0 :   return event_count;
      56             : }
      57             : 
      58           0 : int PacketLossStats::GetMultipleLossPacketCount() const {
      59             :   int packet_count, unused1, unused2;
      60           0 :   ComputeLossCounts(&unused1, &unused2, &packet_count);
      61           0 :   return packet_count;
      62             : }
      63             : 
      64           0 : void PacketLossStats::ComputeLossCounts(
      65             :     int* out_single_loss_count,
      66             :     int* out_multiple_loss_event_count,
      67             :     int* out_multiple_loss_packet_count) const {
      68           0 :   *out_single_loss_count = single_loss_historic_count_;
      69           0 :   *out_multiple_loss_event_count = multiple_loss_historic_event_count_;
      70           0 :   *out_multiple_loss_packet_count = multiple_loss_historic_packet_count_;
      71           0 :   if (lost_packets_buffer_.empty()) {
      72           0 :     RTC_DCHECK(lost_packets_wrapped_buffer_.empty());
      73           0 :     return;
      74             :   }
      75           0 :   uint16_t last_num = 0;
      76           0 :   int sequential_count = 0;
      77           0 :   std::vector<const std::set<uint16_t>*> buffers;
      78           0 :   buffers.push_back(&lost_packets_buffer_);
      79           0 :   buffers.push_back(&lost_packets_wrapped_buffer_);
      80           0 :   for (auto buffer : buffers) {
      81           0 :     for (auto it = buffer->begin(); it != buffer->end(); ++it) {
      82           0 :       uint16_t current_num = *it;
      83           0 :       if (sequential_count > 0 && current_num != ((last_num + 1) & 0xFFFF)) {
      84           0 :         if (sequential_count == 1) {
      85           0 :           (*out_single_loss_count)++;
      86             :         } else {
      87           0 :           (*out_multiple_loss_event_count)++;
      88           0 :           *out_multiple_loss_packet_count += sequential_count;
      89             :         }
      90           0 :         sequential_count = 0;
      91             :       }
      92           0 :       sequential_count++;
      93           0 :       last_num = current_num;
      94             :     }
      95             :   }
      96           0 :   if (sequential_count == 1) {
      97           0 :     (*out_single_loss_count)++;
      98           0 :   } else if (sequential_count > 1) {
      99           0 :     (*out_multiple_loss_event_count)++;
     100           0 :     *out_multiple_loss_packet_count += sequential_count;
     101             :   }
     102             : }
     103             : 
     104           0 : void PacketLossStats::PruneBuffer() {
     105             :   // Remove the oldest lost packet and any contiguous packets and move them
     106             :   // into the historic counts.
     107           0 :   auto it = lost_packets_buffer_.begin();
     108           0 :   uint16_t last_removed = 0;
     109           0 :   int remove_count = 0;
     110             :   // Count adjacent packets and continue counting if it is wrap around by
     111             :   // swapping in the wrapped buffer and letting our value wrap as well.
     112           0 :   while (remove_count == 0 || (!lost_packets_buffer_.empty() &&
     113           0 :                                *it == ((last_removed + 1) & 0xFFFF))) {
     114           0 :     last_removed = *it;
     115           0 :     remove_count++;
     116           0 :     auto to_erase = it++;
     117           0 :     lost_packets_buffer_.erase(to_erase);
     118           0 :     if (lost_packets_buffer_.empty()) {
     119           0 :       lost_packets_buffer_.swap(lost_packets_wrapped_buffer_);
     120           0 :       it = lost_packets_buffer_.begin();
     121             :     }
     122             :   }
     123           0 :   if (remove_count > 1) {
     124           0 :     multiple_loss_historic_event_count_++;
     125           0 :     multiple_loss_historic_packet_count_ += remove_count;
     126             :   } else {
     127           0 :     single_loss_historic_count_++;
     128             :   }
     129             :   // Continue pruning if the wrapped buffer is beyond a threshold and there are
     130             :   // things left in the pre-wrapped buffer.
     131           0 :   if (!lost_packets_wrapped_buffer_.empty() &&
     132           0 :       *(lost_packets_wrapped_buffer_.rbegin()) > 0x4000) {
     133           0 :     PruneBuffer();
     134             :   }
     135           0 : }
     136             : 
     137             : }  // namespace webrtc

Generated by: LCOV version 1.13