blob: 89dd082192249f2a9a21583f8a28c1c1d239cd0d [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
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"
Tommid3807da2020-05-22 17:36:36 +020021#include "modules/include/module_common_types.h"
22#include "modules/video_coding/histogram.h"
Tommid3807da2020-05-22 17:36:36 +020023#include "rtc_base/numerics/sequence_number_util.h"
Tommi63673fe2020-05-27 12:55:38 +020024#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"
Tommid3807da2020-05-22 17:36:36 +020028#include "rtc_base/thread_annotations.h"
29#include "system_wrappers/include/clock.h"
30
31namespace webrtc {
32
Tommi63673fe2020-05-27 12:55:38 +020033// 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.
36class NackModule2 final {
Tommid3807da2020-05-22 17:36:36 +020037 public:
Tommi63673fe2020-05-27 12:55:38 +020038 static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(20);
39
40 NackModule2(TaskQueueBase* current_queue,
41 Clock* clock,
Tommid3807da2020-05-22 17:36:36 +020042 NackSender* nack_sender,
Tommi63673fe2020-05-27 12:55:38 +020043 KeyFrameRequestSender* keyframe_request_sender,
44 TimeDelta update_interval = kUpdateInterval);
45 ~NackModule2();
Tommid3807da2020-05-22 17:36:36 +020046
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);
Tommid3807da2020-05-22 17:36:36 +020052
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)
Tommi63673fe2020-05-27 12:55:38 +020087 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +020088
89 // Removes packets from the nack list until the next keyframe. Returns true
90 // if packets were removed.
Tommi63673fe2020-05-27 12:55:38 +020091 bool RemovePacketsUntilKeyFrame()
92 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +020093 std::vector<uint16_t> GetNackBatch(NackFilterOptions options)
Tommi63673fe2020-05-27 12:55:38 +020094 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +020095
96 // Update the reordering distribution.
97 void UpdateReorderingStatistics(uint16_t seq_num)
Tommi63673fe2020-05-27 12:55:38 +020098 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +020099
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
Tommi63673fe2020-05-27 12:55:38 +0200103 RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200104
Tommi63673fe2020-05-27 12:55:38 +0200105 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
Tommid3807da2020-05-22 17:36:36 +0200111 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_
Tommi63673fe2020-05-27 12:55:38 +0200119 RTC_GUARDED_BY(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200120 std::set<uint16_t, DescendingSeqNumComp<uint16_t>> keyframe_list_
Tommi63673fe2020-05-27 12:55:38 +0200121 RTC_GUARDED_BY(worker_thread_);
Tommid3807da2020-05-22 17:36:36 +0200122 std::set<uint16_t, DescendingSeqNumComp<uint16_t>> recovered_list_
Tommi63673fe2020-05-27 12:55:38 +0200123 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_);
Tommid3807da2020-05-22 17:36:36 +0200128
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_;
Tommi63673fe2020-05-27 12:55:38 +0200133
134 // Used to signal destruction to potentially pending tasks.
135 ScopedTaskSafety task_safety_;
Tommid3807da2020-05-22 17:36:36 +0200136};
137
138} // namespace webrtc
139
140#endif // MODULES_VIDEO_CODING_NACK_MODULE2_H_