diff options
Diffstat (limited to 'third_party/libwebrtc/modules/video_coding/nack_requester.h')
-rw-r--r-- | third_party/libwebrtc/modules/video_coding/nack_requester.h | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/video_coding/nack_requester.h b/third_party/libwebrtc/modules/video_coding/nack_requester.h new file mode 100644 index 0000000000..c860787dcf --- /dev/null +++ b/third_party/libwebrtc/modules/video_coding/nack_requester.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MODULES_VIDEO_CODING_NACK_REQUESTER_H_ +#define MODULES_VIDEO_CODING_NACK_REQUESTER_H_ + +#include <stdint.h> + +#include <map> +#include <set> +#include <vector> + +#include "api/field_trials_view.h" +#include "api/sequence_checker.h" +#include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_base.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" +#include "modules/include/module_common_types.h" +#include "modules/video_coding/histogram.h" +#include "rtc_base/numerics/sequence_number_util.h" +#include "rtc_base/task_utils/repeating_task.h" +#include "rtc_base/thread_annotations.h" +#include "system_wrappers/include/clock.h" + +namespace webrtc { + +class NackRequesterBase { + public: + virtual ~NackRequesterBase() = default; + virtual void ProcessNacks() = 0; +}; + +class NackPeriodicProcessor { + public: + static constexpr TimeDelta kUpdateInterval = TimeDelta::Millis(20); + explicit NackPeriodicProcessor(TimeDelta update_interval = kUpdateInterval); + ~NackPeriodicProcessor(); + void RegisterNackModule(NackRequesterBase* module); + void UnregisterNackModule(NackRequesterBase* module); + + private: + void ProcessNackModules() RTC_RUN_ON(sequence_); + + const TimeDelta update_interval_; + RepeatingTaskHandle repeating_task_ RTC_GUARDED_BY(sequence_); + std::vector<NackRequesterBase*> modules_ RTC_GUARDED_BY(sequence_); + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_; +}; + +class ScopedNackPeriodicProcessorRegistration { + public: + ScopedNackPeriodicProcessorRegistration(NackRequesterBase* module, + NackPeriodicProcessor* processor); + ~ScopedNackPeriodicProcessorRegistration(); + + private: + NackRequesterBase* const module_; + NackPeriodicProcessor* const processor_; +}; + +class NackRequester final : public NackRequesterBase { + public: + NackRequester(TaskQueueBase* current_queue, + NackPeriodicProcessor* periodic_processor, + Clock* clock, + NackSender* nack_sender, + KeyFrameRequestSender* keyframe_request_sender, + const FieldTrialsView& field_trials); + ~NackRequester(); + + void ProcessNacks() override; + + int OnReceivedPacket(uint16_t seq_num, bool is_keyframe); + int OnReceivedPacket(uint16_t seq_num, bool is_keyframe, bool is_recovered); + + void ClearUpTo(uint16_t seq_num); + void UpdateRtt(int64_t rtt_ms); + + private: + // Which fields to consider when deciding which packet to nack in + // GetNackBatch. + enum NackFilterOptions { kSeqNumOnly, kTimeOnly, kSeqNumAndTime }; + + // This class holds the sequence number of the packet that is in the nack list + // as well as the meta data about when it should be nacked and how many times + // we have tried to nack this packet. + struct NackInfo { + NackInfo(); + NackInfo(uint16_t seq_num, + uint16_t send_at_seq_num, + Timestamp created_at_time); + + uint16_t seq_num; + uint16_t send_at_seq_num; + Timestamp created_at_time; + Timestamp sent_at_time; + int retries; + }; + + void AddPacketsToNack(uint16_t seq_num_start, uint16_t seq_num_end) + RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); + + // Removes packets from the nack list until the next keyframe. Returns true + // if packets were removed. + bool RemovePacketsUntilKeyFrame() + RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); + std::vector<uint16_t> GetNackBatch(NackFilterOptions options) + RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); + + // Update the reordering distribution. + void UpdateReorderingStatistics(uint16_t seq_num) + RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); + + // Returns how many packets we have to wait in order to receive the packet + // with probability `probabilty` or higher. + int WaitNumberOfPackets(float probability) const + RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_thread_); + + TaskQueueBase* const worker_thread_; + Clock* const clock_; + NackSender* const nack_sender_; + KeyFrameRequestSender* const keyframe_request_sender_; + + // TODO(philipel): Some of the variables below are consistently used on a + // known thread (e.g. see `initialized_`). Those probably do not need + // synchronized access. + std::map<uint16_t, NackInfo, DescendingSeqNumComp<uint16_t>> nack_list_ + RTC_GUARDED_BY(worker_thread_); + std::set<uint16_t, DescendingSeqNumComp<uint16_t>> keyframe_list_ + RTC_GUARDED_BY(worker_thread_); + std::set<uint16_t, DescendingSeqNumComp<uint16_t>> recovered_list_ + RTC_GUARDED_BY(worker_thread_); + video_coding::Histogram reordering_histogram_ RTC_GUARDED_BY(worker_thread_); + bool initialized_ RTC_GUARDED_BY(worker_thread_); + TimeDelta rtt_ RTC_GUARDED_BY(worker_thread_); + uint16_t newest_seq_num_ RTC_GUARDED_BY(worker_thread_); + + // Adds a delay before send nack on packet received. + const TimeDelta send_nack_delay_; + + ScopedNackPeriodicProcessorRegistration processor_registration_; + + // Used to signal destruction to potentially pending tasks. + ScopedTaskSafety task_safety_; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_NACK_REQUESTER_H_ |