1 /*
2  *  Copyright (c) 2016 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 MODULES_VIDEO_CODING_NACK_MODULE_H_
12 #define MODULES_VIDEO_CODING_NACK_MODULE_H_
13 
14 #include <map>
15 #include <vector>
16 #include <set>
17 
18 #include "modules/include/module.h"
19 #include "modules/video_coding/histogram.h"
20 #include "modules/video_coding/include/video_coding_defines.h"
21 #include "modules/video_coding/packet.h"
22 #include "rtc_base/criticalsection.h"
23 #include "rtc_base/numerics/sequence_number_util.h"
24 #include "rtc_base/thread_annotations.h"
25 #include "system_wrappers/include/clock.h"
26 
27 namespace webrtc {
28 
29 class NackModule : public Module {
30  public:
31   NackModule(Clock* clock,
32              NackSender* nack_sender,
33              KeyFrameRequestSender* keyframe_request_sender);
34 
35   int OnReceivedPacket(const VCMPacket& packet);
36   void ClearUpTo(uint16_t seq_num);
37   void UpdateRtt(int64_t rtt_ms);
38   void Clear();
39 
40   // Module implementation
41   int64_t TimeUntilNextProcess() override;
42   void Process() override;
43 
44  private:
45   // Which fields to consider when deciding which packet to nack in
46   // GetNackBatch.
47   enum NackFilterOptions { kSeqNumOnly, kTimeOnly, kSeqNumAndTime };
48 
49   // This class holds the sequence number of the packet that is in the nack list
50   // as well as the meta data about when it should be nacked and how many times
51   // we have tried to nack this packet.
52   struct NackInfo {
53     NackInfo();
54     NackInfo(uint16_t seq_num, uint16_t send_at_seq_num);
55 
56     uint16_t seq_num;
57     uint16_t send_at_seq_num;
58     int64_t sent_at_time;
59     int retries;
60   };
61   void AddPacketsToNack(uint16_t seq_num_start, uint16_t seq_num_end)
62       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
63 
64   // Removes packets from the nack list until the next keyframe. Returns true
65   // if packets were removed.
66   bool RemovePacketsUntilKeyFrame() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
67   std::vector<uint16_t> GetNackBatch(NackFilterOptions options)
68       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
69 
70   // Update the reordering distribution.
71   void UpdateReorderingStatistics(uint16_t seq_num)
72       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
73 
74   // Returns how many packets we have to wait in order to receive the packet
75   // with probability |probabilty| or higher.
76   int WaitNumberOfPackets(float probability) const
77       RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
78 
79   rtc::CriticalSection crit_;
80   Clock* const clock_;
81   NackSender* const nack_sender_;
82   KeyFrameRequestSender* const keyframe_request_sender_;
83 
84   // TODO(philipel): Some of the variables below are consistently used on a
85   // known thread (e.g. see |initialized_|). Those probably do not need
86   // synchronized access.
87   std::map<uint16_t, NackInfo, DescendingSeqNumComp<uint16_t>> nack_list_
88       RTC_GUARDED_BY(crit_);
89   std::set<uint16_t, DescendingSeqNumComp<uint16_t>> keyframe_list_
90       RTC_GUARDED_BY(crit_);
91   video_coding::Histogram reordering_histogram_ RTC_GUARDED_BY(crit_);
92   bool initialized_ RTC_GUARDED_BY(crit_);
93   int64_t rtt_ms_ RTC_GUARDED_BY(crit_);
94   uint16_t newest_seq_num_ RTC_GUARDED_BY(crit_);
95 
96   // Only touched on the process thread.
97   int64_t next_process_time_ms_;
98 };
99 
100 }  // namespace webrtc
101 
102 #endif  // MODULES_VIDEO_CODING_NACK_MODULE_H_
103