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