LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/neteq - nack_tracker.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 6 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 3 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             : #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_
      12             : #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_
      13             : 
      14             : #include <vector>
      15             : #include <map>
      16             : 
      17             : #include "webrtc/base/gtest_prod_util.h"
      18             : #include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h"
      19             : 
      20             : //
      21             : // The NackTracker class keeps track of the lost packets, an estimate of
      22             : // time-to-play for each packet is also given.
      23             : //
      24             : // Every time a packet is pushed into NetEq, LastReceivedPacket() has to be
      25             : // called to update the NACK list.
      26             : //
      27             : // Every time 10ms audio is pulled from NetEq LastDecodedPacket() should be
      28             : // called, and time-to-play is updated at that moment.
      29             : //
      30             : // If packet N is received, any packet prior to |N - NackThreshold| which is not
      31             : // arrived is considered lost, and should be labeled as "missing" (the size of
      32             : // the list might be limited and older packet eliminated from the list). Packets
      33             : // |N - NackThreshold|, |N - NackThreshold + 1|, ..., |N - 1| are considered
      34             : // "late." A "late" packet with sequence number K is changed to "missing" any
      35             : // time a packet with sequence number newer than |K + NackList| is arrived.
      36             : //
      37             : // The NackTracker class has to know about the sample rate of the packets to
      38             : // compute time-to-play. So sample rate should be set as soon as the first
      39             : // packet is received. If there is a change in the receive codec (sender changes
      40             : // codec) then NackTracker should be reset. This is because NetEQ would flush
      41             : // its buffer and re-transmission is meaning less for old packet. Therefore, in
      42             : // that case, after reset the sampling rate has to be updated.
      43             : //
      44             : // Thread Safety
      45             : // =============
      46             : // Please note that this class in not thread safe. The class must be protected
      47             : // if different APIs are called from different threads.
      48             : //
      49             : namespace webrtc {
      50             : 
      51           0 : class NackTracker {
      52             :  public:
      53             :   // A limit for the size of the NACK list.
      54             :   static const size_t kNackListSizeLimit = 500;  // 10 seconds for 20 ms frame
      55             :                                                  // packets.
      56             :   // Factory method.
      57             :   static NackTracker* Create(int nack_threshold_packets);
      58             : 
      59             :   ~NackTracker();
      60             : 
      61             :   // Set a maximum for the size of the NACK list. If the last received packet
      62             :   // has sequence number of N, then NACK list will not contain any element
      63             :   // with sequence number earlier than N - |max_nack_list_size|.
      64             :   //
      65             :   // The largest maximum size is defined by |kNackListSizeLimit|
      66             :   void SetMaxNackListSize(size_t max_nack_list_size);
      67             : 
      68             :   // Set the sampling rate.
      69             :   //
      70             :   // If associated sampling rate of the received packets is changed, call this
      71             :   // function to update sampling rate. Note that if there is any change in
      72             :   // received codec then NetEq will flush its buffer and NACK has to be reset.
      73             :   // After Reset() is called sampling rate has to be set.
      74             :   void UpdateSampleRate(int sample_rate_hz);
      75             : 
      76             :   // Update the sequence number and the timestamp of the last decoded RTP. This
      77             :   // API should be called every time 10 ms audio is pulled from NetEq.
      78             :   void UpdateLastDecodedPacket(uint16_t sequence_number, uint32_t timestamp);
      79             : 
      80             :   // Update the sequence number and the timestamp of the last received RTP. This
      81             :   // API should be called every time a packet pushed into ACM.
      82             :   void UpdateLastReceivedPacket(uint16_t sequence_number, uint32_t timestamp);
      83             : 
      84             :   // Get a list of "missing" packets which have expected time-to-play larger
      85             :   // than the given round-trip-time (in milliseconds).
      86             :   // Note: Late packets are not included.
      87             :   std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const;
      88             : 
      89             :   // Reset to default values. The NACK list is cleared.
      90             :   // |nack_threshold_packets_| & |max_nack_list_size_| preserve their values.
      91             :   void Reset();
      92             : 
      93             :  private:
      94             :   // This test need to access the private method GetNackList().
      95             :   FRIEND_TEST_ALL_PREFIXES(NackTrackerTest, EstimateTimestampAndTimeToPlay);
      96             : 
      97             :   struct NackElement {
      98           0 :     NackElement(int64_t initial_time_to_play_ms,
      99             :                 uint32_t initial_timestamp,
     100             :                 bool missing)
     101           0 :         : time_to_play_ms(initial_time_to_play_ms),
     102             :           estimated_timestamp(initial_timestamp),
     103           0 :           is_missing(missing) {}
     104             : 
     105             :     // Estimated time (ms) left for this packet to be decoded. This estimate is
     106             :     // updated every time jitter buffer decodes a packet.
     107             :     int64_t time_to_play_ms;
     108             : 
     109             :     // A guess about the timestamp of the missing packet, it is used for
     110             :     // estimation of |time_to_play_ms|. The estimate might be slightly wrong if
     111             :     // there has been frame-size change since the last received packet and the
     112             :     // missing packet. However, the risk of this is low, and in case of such
     113             :     // errors, there will be a minor misestimation in time-to-play of missing
     114             :     // packets. This will have a very minor effect on NACK performance.
     115             :     uint32_t estimated_timestamp;
     116             : 
     117             :     // True if the packet is considered missing. Otherwise indicates packet is
     118             :     // late.
     119             :     bool is_missing;
     120             :   };
     121             : 
     122             :   class NackListCompare {
     123             :    public:
     124           0 :     bool operator()(uint16_t sequence_number_old,
     125             :                     uint16_t sequence_number_new) const {
     126           0 :       return IsNewerSequenceNumber(sequence_number_new, sequence_number_old);
     127             :     }
     128             :   };
     129             : 
     130             :   typedef std::map<uint16_t, NackElement, NackListCompare> NackList;
     131             : 
     132             :   // Constructor.
     133             :   explicit NackTracker(int nack_threshold_packets);
     134             : 
     135             :   // This API is used only for testing to assess whether time-to-play is
     136             :   // computed correctly.
     137             :   NackList GetNackList() const;
     138             : 
     139             :   // Given the |sequence_number_current_received_rtp| of currently received RTP,
     140             :   // recognize packets which are not arrive and add to the list.
     141             :   void AddToList(uint16_t sequence_number_current_received_rtp);
     142             : 
     143             :   // This function subtracts 10 ms of time-to-play for all packets in NACK list.
     144             :   // This is called when 10 ms elapsed with no new RTP packet decoded.
     145             :   void UpdateEstimatedPlayoutTimeBy10ms();
     146             : 
     147             :   // Given the |sequence_number_current_received_rtp| and
     148             :   // |timestamp_current_received_rtp| of currently received RTP update number
     149             :   // of samples per packet.
     150             :   void UpdateSamplesPerPacket(uint16_t sequence_number_current_received_rtp,
     151             :                               uint32_t timestamp_current_received_rtp);
     152             : 
     153             :   // Given the |sequence_number_current_received_rtp| of currently received RTP
     154             :   // update the list. That is; some packets will change from late to missing,
     155             :   // some packets are inserted as missing and some inserted as late.
     156             :   void UpdateList(uint16_t sequence_number_current_received_rtp);
     157             : 
     158             :   // Packets which are considered late for too long (according to
     159             :   // |nack_threshold_packets_|) are flagged as missing.
     160             :   void ChangeFromLateToMissing(uint16_t sequence_number_current_received_rtp);
     161             : 
     162             :   // Packets which have sequence number older that
     163             :   // |sequence_num_last_received_rtp_| - |max_nack_list_size_| are removed
     164             :   // from the NACK list.
     165             :   void LimitNackListSize();
     166             : 
     167             :   // Estimate timestamp of a missing packet given its sequence number.
     168             :   uint32_t EstimateTimestamp(uint16_t sequence_number);
     169             : 
     170             :   // Compute time-to-play given a timestamp.
     171             :   int64_t TimeToPlay(uint32_t timestamp) const;
     172             : 
     173             :   // If packet N is arrived, any packet prior to N - |nack_threshold_packets_|
     174             :   // which is not arrived is considered missing, and should be in NACK list.
     175             :   // Also any packet in the range of N-1 and N - |nack_threshold_packets_|,
     176             :   // exclusive, which is not arrived is considered late, and should should be
     177             :   // in the list of late packets.
     178             :   const int nack_threshold_packets_;
     179             : 
     180             :   // Valid if a packet is received.
     181             :   uint16_t sequence_num_last_received_rtp_;
     182             :   uint32_t timestamp_last_received_rtp_;
     183             :   bool any_rtp_received_;  // If any packet received.
     184             : 
     185             :   // Valid if a packet is decoded.
     186             :   uint16_t sequence_num_last_decoded_rtp_;
     187             :   uint32_t timestamp_last_decoded_rtp_;
     188             :   bool any_rtp_decoded_;  // If any packet decoded.
     189             : 
     190             :   int sample_rate_khz_;  // Sample rate in kHz.
     191             : 
     192             :   // Number of samples per packet. We update this every time we receive a
     193             :   // packet, not only for consecutive packets.
     194             :   int samples_per_packet_;
     195             : 
     196             :   // A list of missing packets to be retransmitted. Components of the list
     197             :   // contain the sequence number of missing packets and the estimated time that
     198             :   // each pack is going to be played out.
     199             :   NackList nack_list_;
     200             : 
     201             :   // NACK list will not keep track of missing packets prior to
     202             :   // |sequence_num_last_received_rtp_| - |max_nack_list_size_|.
     203             :   size_t max_nack_list_size_;
     204             : };
     205             : 
     206             : }  // namespace webrtc
     207             : 
     208             : #endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_NACK_TRACKER_H_

Generated by: LCOV version 1.13