Home | History | Annotate | Download | only in neteq
      1 /*
      2  *  Copyright (c) 2011 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/audio_coding/neteq/rtcp.h"
     12 
     13 #include <string.h>
     14 
     15 #include <algorithm>
     16 
     17 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     18 #include "webrtc/modules/interface/module_common_types.h"
     19 
     20 namespace webrtc {
     21 
     22 void Rtcp::Init(uint16_t start_sequence_number) {
     23   cycles_ = 0;
     24   max_seq_no_ = start_sequence_number;
     25   base_seq_no_ = start_sequence_number;
     26   received_packets_ = 0;
     27   received_packets_prior_ = 0;
     28   expected_prior_ = 0;
     29   jitter_ = 0;
     30   transit_ = 0;
     31 }
     32 
     33 void Rtcp::Update(const RTPHeader& rtp_header, uint32_t receive_timestamp) {
     34   // Update number of received packets, and largest packet number received.
     35   received_packets_++;
     36   int16_t sn_diff = rtp_header.sequenceNumber - max_seq_no_;
     37   if (sn_diff >= 0) {
     38     if (rtp_header.sequenceNumber < max_seq_no_) {
     39       // Wrap-around detected.
     40       cycles_++;
     41     }
     42     max_seq_no_ = rtp_header.sequenceNumber;
     43   }
     44 
     45   // Calculate jitter according to RFC 3550, and update previous timestamps.
     46   // Note that the value in |jitter_| is in Q4.
     47   if (received_packets_ > 1) {
     48     int32_t ts_diff = receive_timestamp - (rtp_header.timestamp - transit_);
     49     ts_diff = WEBRTC_SPL_ABS_W32(ts_diff);
     50     int32_t jitter_diff = (ts_diff << 4) - jitter_;
     51     // Calculate 15 * jitter_ / 16 + jitter_diff / 16 (with proper rounding).
     52     jitter_ = jitter_ + ((jitter_diff + 8) >> 4);
     53   }
     54   transit_ = rtp_header.timestamp - receive_timestamp;
     55 }
     56 
     57 void Rtcp::GetStatistics(bool no_reset, RtcpStatistics* stats) {
     58   // Extended highest sequence number received.
     59   stats->extended_max_sequence_number =
     60       (static_cast<int>(cycles_) << 16) + max_seq_no_;
     61 
     62   // Calculate expected number of packets and compare it with the number of
     63   // packets that were actually received. The cumulative number of lost packets
     64   // can be extracted.
     65   uint32_t expected_packets =
     66       stats->extended_max_sequence_number - base_seq_no_ + 1;
     67   if (received_packets_ == 0) {
     68     // No packets received, assume none lost.
     69     stats->cumulative_lost = 0;
     70   } else if (expected_packets > received_packets_) {
     71     stats->cumulative_lost = expected_packets - received_packets_;
     72     if (stats->cumulative_lost > 0xFFFFFF) {
     73       stats->cumulative_lost = 0xFFFFFF;
     74     }
     75   } else {
     76     stats->cumulative_lost = 0;
     77   }
     78 
     79   // Fraction lost since last report.
     80   uint32_t expected_since_last = expected_packets - expected_prior_;
     81   uint32_t received_since_last = received_packets_ - received_packets_prior_;
     82   if (!no_reset) {
     83     expected_prior_ = expected_packets;
     84     received_packets_prior_ = received_packets_;
     85   }
     86   int32_t lost = expected_since_last - received_since_last;
     87   if (expected_since_last == 0 || lost <= 0 || received_packets_ == 0) {
     88     stats->fraction_lost = 0;
     89   } else {
     90     stats->fraction_lost = std::min(0xFFU, (lost << 8) / expected_since_last);
     91   }
     92 
     93   stats->jitter = jitter_ >> 4;  // Scaling from Q4.
     94 }
     95 
     96 }  // namespace webrtc
     97