nack_requester.h (5186B)
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_REQUESTER_H_ 12 #define MODULES_VIDEO_CODING_NACK_REQUESTER_H_ 13 14 #include <stdint.h> 15 16 #include <map> 17 #include <set> 18 #include <vector> 19 20 #include "api/field_trials_view.h" 21 #include "api/sequence_checker.h" 22 #include "api/task_queue/pending_task_safety_flag.h" 23 #include "api/task_queue/task_queue_base.h" 24 #include "api/units/time_delta.h" 25 #include "api/units/timestamp.h" 26 #include "modules/include/module_common_types.h" 27 #include "modules/video_coding/histogram.h" 28 #include "rtc_base/numerics/sequence_number_util.h" 29 #include "rtc_base/system/no_unique_address.h" 30 #include "rtc_base/task_utils/repeating_task.h" 31 #include "rtc_base/thread_annotations.h" 32 #include "system_wrappers/include/clock.h" 33 34 namespace webrtc { 35 36 class NackRequesterBase { 37 public: 38 virtual ~NackRequesterBase() = default; 39 virtual void ProcessNacks() = 0; 40 }; 41 42 class NackPeriodicProcessor { 43 public: 44 static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(20); 45 explicit NackPeriodicProcessor(TimeDelta update_interval = kUpdateInterval); 46 ~NackPeriodicProcessor(); 47 void RegisterNackModule(NackRequesterBase* module); 48 void UnregisterNackModule(NackRequesterBase* module); 49 50 private: 51 void ProcessNackModules() RTC_RUN_ON(sequence_); 52 53 const TimeDelta update_interval_; 54 RepeatingTaskHandle repeating_task_ RTC_GUARDED_BY(sequence_); 55 std::vector<NackRequesterBase*> modules_ RTC_GUARDED_BY(sequence_); 56 RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_; 57 }; 58 59 class ScopedNackPeriodicProcessorRegistration { 60 public: 61 ScopedNackPeriodicProcessorRegistration(NackRequesterBase* module, 62 NackPeriodicProcessor* processor); 63 ~ScopedNackPeriodicProcessorRegistration(); 64 65 private: 66 NackRequesterBase* const module_; 67 NackPeriodicProcessor* const processor_; 68 }; 69 70 class NackRequester final : public NackRequesterBase { 71 public: 72 NackRequester(TaskQueueBase* current_queue, 73 NackPeriodicProcessor* periodic_processor, 74 Clock* clock, 75 NackSender* nack_sender, 76 KeyFrameRequestSender* keyframe_request_sender, 77 const FieldTrialsView& field_trials); 78 ~NackRequester(); 79 80 void ProcessNacks() override; 81 82 int OnReceivedPacket(uint16_t seq_num); 83 int OnReceivedPacket(uint16_t seq_num, bool is_recovered); 84 85 void ClearUpTo(uint16_t seq_num); 86 void UpdateRtt(int64_t rtt_ms); 87 88 private: 89 // Which fields to consider when deciding which packet to nack in 90 // GetNackBatch. 91 enum NackFilterOptions { kSeqNumOnly, kTimeOnly }; 92 93 // This class holds the sequence number of the packet that is in the nack list 94 // as well as the meta data about when it should be nacked and how many times 95 // we have tried to nack this packet. 96 struct NackInfo { 97 NackInfo(); 98 NackInfo(uint16_t seq_num, 99 uint16_t send_at_seq_num, 100 Timestamp created_at_time); 101 102 uint16_t seq_num; 103 uint16_t send_at_seq_num; 104 Timestamp created_at_time; 105 Timestamp sent_at_time; 106 int retries; 107 }; 108 109 void AddPacketsToNack(uint16_t seq_num_start, uint16_t seq_num_end) 110 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); 111 112 std::vector<uint16_t> GetNackBatch(NackFilterOptions options) 113 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); 114 115 // Update the reordering distribution. 116 void UpdateReorderingStatistics(uint16_t seq_num) 117 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); 118 119 // Returns how many packets we have to wait in order to receive the packet 120 // with probability `probabilty` or higher. 121 int WaitNumberOfPackets(float probability) const 122 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); 123 124 TaskQueueBase* const worker_thread_; 125 Clock* const clock_; 126 NackSender* const nack_sender_; 127 KeyFrameRequestSender* const keyframe_request_sender_; 128 129 // TODO(philipel): Some of the variables below are consistently used on a 130 // known thread (e.g. see `initialized_`). Those probably do not need 131 // synchronized access. 132 std::map<uint16_t, NackInfo, DescendingSeqNumComp<uint16_t>> nack_list_ 133 RTC_GUARDED_BY(worker_thread_); 134 std::set<uint16_t, DescendingSeqNumComp<uint16_t>> recovered_list_ 135 RTC_GUARDED_BY(worker_thread_); 136 video_coding::Histogram reordering_histogram_ RTC_GUARDED_BY(worker_thread_); 137 bool initialized_ RTC_GUARDED_BY(worker_thread_); 138 TimeDelta rtt_ RTC_GUARDED_BY(worker_thread_); 139 uint16_t newest_seq_num_ RTC_GUARDED_BY(worker_thread_); 140 141 // Adds a delay before send nack on packet received. 142 const TimeDelta send_nack_delay_; 143 144 ScopedNackPeriodicProcessorRegistration processor_registration_; 145 146 // Used to signal destruction to potentially pending tasks. 147 ScopedTaskSafety task_safety_; 148 }; 149 150 } // namespace webrtc 151 152 #endif // MODULES_VIDEO_CODING_NACK_REQUESTER_H_