blob: c860787dcfbcc4697dc36ed2cffde7a0776c4856 [file] [log] [blame]
Tommid3807da2020-05-22 17:36:36 +02001/*
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
Markus Handell06a2bf02021-07-22 15:09:39 +020011#ifndef MODULES_VIDEO_CODING_NACK_REQUESTER_H_
12#define MODULES_VIDEO_CODING_NACK_REQUESTER_H_
Tommid3807da2020-05-22 17:36:36 +020013
14#include <stdint.h>
15
16#include <map>
17#include <set>
18#include <vector>
19
Jonas Orelande62c2f22022-03-29 11:04:48 +020020#include "api/field_trials_view.h"
Artem Titovd15a5752021-02-10 14:31:24 +010021#include "api/sequence_checker.h"
Artem Titovc374d112022-06-16 21:27:45 +020022#include "api/task_queue/pending_task_safety_flag.h"
Danil Chapovalov03f8b8a2022-07-18 13:11:42 +020023#include "api/task_queue/task_queue_base.h"
Tommid3807da2020-05-22 17:36:36 +020024#include "api/units/time_delta.h"
Erik Språng609aef32022-07-01 16:46:56 +020025#include "api/units/timestamp.h"
Tommid3807da2020-05-22 17:36:36 +020026#include "modules/include/module_common_types.h"
27#include "modules/video_coding/histogram.h"
Tommid3807da2020-05-22 17:36:36 +020028#include "rtc_base/numerics/sequence_number_util.h"
Tommi63673fe2020-05-27 12:55:38 +020029#include "rtc_base/task_utils/repeating_task.h"
Tommid3807da2020-05-22 17:36:36 +020030#include "rtc_base/thread_annotations.h"
31#include "system_wrappers/include/clock.h"
32
33namespace webrtc {
34
Markus Handell06a2bf02021-07-22 15:09:39 +020035class NackRequesterBase {
Markus Handell0e62f7a2021-07-20 13:32:02 +020036 public:
Markus Handell06a2bf02021-07-22 15:09:39 +020037 virtual ~NackRequesterBase() = default;
Markus Handell0e62f7a2021-07-20 13:32:02 +020038 virtual void ProcessNacks() = 0;
39};
40
41class NackPeriodicProcessor {
42 public:
43 static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(20);
44 explicit NackPeriodicProcessor(TimeDelta update_interval = kUpdateInterval);
45 ~NackPeriodicProcessor();
Markus Handell06a2bf02021-07-22 15:09:39 +020046 void RegisterNackModule(NackRequesterBase* module);
47 void UnregisterNackModule(NackRequesterBase* module);
Markus Handell0e62f7a2021-07-20 13:32:02 +020048
49 private:
50 void ProcessNackModules() RTC_RUN_ON(sequence_);
51
52 const TimeDelta update_interval_;
53 RepeatingTaskHandle repeating_task_ RTC_GUARDED_BY(sequence_);
Markus Handell06a2bf02021-07-22 15:09:39 +020054 std::vector<NackRequesterBase*> modules_ RTC_GUARDED_BY(sequence_);
Markus Handell0e62f7a2021-07-20 13:32:02 +020055 RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_;
56};
57
58class ScopedNackPeriodicProcessorRegistration {
59 public:
Markus Handell06a2bf02021-07-22 15:09:39 +020060 ScopedNackPeriodicProcessorRegistration(NackRequesterBase* module,
Markus Handell0e62f7a2021-07-20 13:32:02 +020061 NackPeriodicProcessor* processor);
62 ~ScopedNackPeriodicProcessorRegistration();
63
64 private:
Markus Handell06a2bf02021-07-22 15:09:39 +020065 NackRequesterBase* const module_;
Markus Handell0e62f7a2021-07-20 13:32:02 +020066 NackPeriodicProcessor* const processor_;
67};
68
Markus Handell06a2bf02021-07-22 15:09:39 +020069class NackRequester final : public NackRequesterBase {
Tommid3807da2020-05-22 17:36:36 +020070 public:
Markus Handell06a2bf02021-07-22 15:09:39 +020071 NackRequester(TaskQueueBase* current_queue,
72 NackPeriodicProcessor* periodic_processor,
73 Clock* clock,
74 NackSender* nack_sender,
Jonas Orelande02f9ee2022-03-25 12:43:14 +010075 KeyFrameRequestSender* keyframe_request_sender,
Jonas Orelande62c2f22022-03-29 11:04:48 +020076 const FieldTrialsView& field_trials);
Markus Handell06a2bf02021-07-22 15:09:39 +020077 ~NackRequester();
Tommid3807da2020-05-22 17:36:36 +020078
Markus Handell0e62f7a2021-07-20 13:32:02 +020079 void ProcessNacks() override;
80
Tommid3807da2020-05-22 17:36:36 +020081 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);
Tommid3807da2020-05-22 17:36:36 +020086
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,
Erik Språng609aef32022-07-01 16:46:56 +020099 Timestamp created_at_time);
Tommid3807da2020-05-22 17:36:36 +0200100
101 uint16_t seq_num;
102 uint16_t send_at_seq_num;
Erik Språng609aef32022-07-01 16:46:56 +0200103 Timestamp created_at_time;
104 Timestamp sent_at_time;
Tommid3807da2020-05-22 17:36:36 +0200105 int retries;
106 };
107
Tommid3807da2020-05-22 17:36:36 +0200108 void AddPacketsToNack(uint16_t seq_num_start, uint16_t seq_num_end)
Tommi63673fe2020-05-27 12:55:38 +0200109 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200110
111 // Removes packets from the nack list until the next keyframe. Returns true
112 // if packets were removed.
Tommi63673fe2020-05-27 12:55:38 +0200113 bool RemovePacketsUntilKeyFrame()
114 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200115 std::vector<uint16_t> GetNackBatch(NackFilterOptions options)
Tommi63673fe2020-05-27 12:55:38 +0200116 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200117
118 // Update the reordering distribution.
119 void UpdateReorderingStatistics(uint16_t seq_num)
Tommi63673fe2020-05-27 12:55:38 +0200120 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200121
122 // Returns how many packets we have to wait in order to receive the packet
Artem Titovdcd7fc72021-08-09 13:02:57 +0200123 // with probability `probabilty` or higher.
Tommid3807da2020-05-22 17:36:36 +0200124 int WaitNumberOfPackets(float probability) const
Tommi63673fe2020-05-27 12:55:38 +0200125 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200126
Tommi63673fe2020-05-27 12:55:38 +0200127 TaskQueueBase* const worker_thread_;
Tommid3807da2020-05-22 17:36:36 +0200128 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
Artem Titovdcd7fc72021-08-09 13:02:57 +0200133 // known thread (e.g. see `initialized_`). Those probably do not need
Tommid3807da2020-05-22 17:36:36 +0200134 // synchronized access.
135 std::map<uint16_t, NackInfo, DescendingSeqNumComp<uint16_t>> nack_list_
Tommi63673fe2020-05-27 12:55:38 +0200136 RTC_GUARDED_BY(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200137 std::set<uint16_t, DescendingSeqNumComp<uint16_t>> keyframe_list_
Tommi63673fe2020-05-27 12:55:38 +0200138 RTC_GUARDED_BY(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200139 std::set<uint16_t, DescendingSeqNumComp<uint16_t>> recovered_list_
Tommi63673fe2020-05-27 12:55:38 +0200140 RTC_GUARDED_BY(worker_thread_);
141 video_coding::Histogram reordering_histogram_ RTC_GUARDED_BY(worker_thread_);
142 bool initialized_ RTC_GUARDED_BY(worker_thread_);
Erik Språng609aef32022-07-01 16:46:56 +0200143 TimeDelta rtt_ RTC_GUARDED_BY(worker_thread_);
Tommi63673fe2020-05-27 12:55:38 +0200144 uint16_t newest_seq_num_ RTC_GUARDED_BY(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200145
146 // Adds a delay before send nack on packet received.
Erik Språng609aef32022-07-01 16:46:56 +0200147 const TimeDelta send_nack_delay_;
Tommi63673fe2020-05-27 12:55:38 +0200148
Markus Handell0e62f7a2021-07-20 13:32:02 +0200149 ScopedNackPeriodicProcessorRegistration processor_registration_;
150
Tommi63673fe2020-05-27 12:55:38 +0200151 // Used to signal destruction to potentially pending tasks.
152 ScopedTaskSafety task_safety_;
Tommid3807da2020-05-22 17:36:36 +0200153};
154
155} // namespace webrtc
156
Markus Handell06a2bf02021-07-22 15:09:39 +0200157#endif // MODULES_VIDEO_CODING_NACK_REQUESTER_H_