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_MODULE2_H_
12 #define MODULES_VIDEO_CODING_NACK_MODULE2_H_
13 
14 #include <stdint.h>
15 
16 #include <map>
17 #include <set>
18 #include <vector>
19 
20 #include "api/units/time_delta.h"
21 #include "modules/include/module_common_types.h"
22 #include "modules/video_coding/histogram.h"
23 #include "rtc_base/numerics/sequence_number_util.h"
24 #include "rtc_base/synchronization/sequence_checker.h"
25 #include "rtc_base/task_queue.h"
26 #include "rtc_base/task_utils/pending_task_safety_flag.h"
27 #include "rtc_base/task_utils/repeating_task.h"
28 #include "rtc_base/thread_annotations.h"
29 #include "system_wrappers/include/clock.h"
30 
31 namespace webrtc {
32 
33 // TODO(bugs.webrtc.org/11594): This class no longer implements the Module
34 // interface and therefore "NackModule" may not be a descriptive name anymore.
35 // Consider renaming to e.g. NackTracker or NackRequester.
36 class NackModule2 final {
37  public:
38   static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(20);
39 
40   NackModule2(TaskQueueBase* current_queue,
41               Clock* clock,
42               NackSender* nack_sender,
43               KeyFrameRequestSender* keyframe_request_sender,
44               TimeDelta update_interval = kUpdateInterval);
45   ~NackModule2();
46 
47   int OnReceivedPacket(uint16_t seq_num, bool is_keyframe);
48   int OnReceivedPacket(uint16_t seq_num, bool is_keyframe, bool is_recovered);
49 
50   void ClearUpTo(uint16_t seq_num);
51   void UpdateRtt(int64_t rtt_ms);
52 
53  private:
54   // Which fields to consider when deciding which packet to nack in
55   // GetNackBatch.
56   enum NackFilterOptions { kSeqNumOnly, kTimeOnly, kSeqNumAndTime };
57 
58   // This class holds the sequence number of the packet that is in the nack list
59   // as well as the meta data about when it should be nacked and how many times
60   // we have tried to nack this packet.
61   struct NackInfo {
62     NackInfo();
63     NackInfo(uint16_t seq_num,
64              uint16_t send_at_seq_num,
65              int64_t created_at_time);
66 
67     uint16_t seq_num;
68     uint16_t send_at_seq_num;
69     int64_t created_at_time;
70     int64_t sent_at_time;
71     int retries;
72   };
73 
74   struct BackoffSettings {
75     BackoffSettings(TimeDelta min_retry, TimeDelta max_rtt, double base);
76     static absl::optional<BackoffSettings> ParseFromFieldTrials();
77 
78     // Min time between nacks.
79     const TimeDelta min_retry_interval;
80     // Upper bound on link-delay considered for exponential backoff.
81     const TimeDelta max_rtt;
82     // Base for the exponential backoff.
83     const double base;
84   };
85 
86   void AddPacketsToNack(uint16_t seq_num_start, uint16_t seq_num_end)
87       RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
88 
89   // Removes packets from the nack list until the next keyframe. Returns true
90   // if packets were removed.
91   bool RemovePacketsUntilKeyFrame()
92       RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
93   std::vector<uint16_t> GetNackBatch(NackFilterOptions options)
94       RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
95 
96   // Update the reordering distribution.
97   void UpdateReorderingStatistics(uint16_t seq_num)
98       RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
99 
100   // Returns how many packets we have to wait in order to receive the packet
101   // with probability |probabilty| or higher.
102   int WaitNumberOfPackets(float probability) const
103       RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
104 
105   TaskQueueBase* const worker_thread_;
106 
107   // Used to regularly call SendNack if needed.
108   RepeatingTaskHandle repeating_task_ RTC_GUARDED_BY(worker_thread_);
109   const TimeDelta update_interval_;
110 
111   Clock* const clock_;
112   NackSender* const nack_sender_;
113   KeyFrameRequestSender* const keyframe_request_sender_;
114 
115   // TODO(philipel): Some of the variables below are consistently used on a
116   // known thread (e.g. see |initialized_|). Those probably do not need
117   // synchronized access.
118   std::map<uint16_t, NackInfo, DescendingSeqNumComp<uint16_t>> nack_list_
119       RTC_GUARDED_BY(worker_thread_);
120   std::set<uint16_t, DescendingSeqNumComp<uint16_t>> keyframe_list_
121       RTC_GUARDED_BY(worker_thread_);
122   std::set<uint16_t, DescendingSeqNumComp<uint16_t>> recovered_list_
123       RTC_GUARDED_BY(worker_thread_);
124   video_coding::Histogram reordering_histogram_ RTC_GUARDED_BY(worker_thread_);
125   bool initialized_ RTC_GUARDED_BY(worker_thread_);
126   int64_t rtt_ms_ RTC_GUARDED_BY(worker_thread_);
127   uint16_t newest_seq_num_ RTC_GUARDED_BY(worker_thread_);
128 
129   // Adds a delay before send nack on packet received.
130   const int64_t send_nack_delay_ms_;
131 
132   const absl::optional<BackoffSettings> backoff_settings_;
133 
134   // Used to signal destruction to potentially pending tasks.
135   ScopedTaskSafety task_safety_;
136 };
137 
138 }  // namespace webrtc
139 
140 #endif  // MODULES_VIDEO_CODING_NACK_MODULE2_H_
141