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