1 /* 2 * Copyright (c) 2019 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_LOSS_NOTIFICATION_CONTROLLER_H_ 12 #define MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_ 13 14 #include <stdint.h> 15 16 #include <set> 17 18 #include "absl/types/optional.h" 19 #include "api/array_view.h" 20 #include "api/sequence_checker.h" 21 #include "modules/include/module_common_types.h" 22 #include "rtc_base/system/no_unique_address.h" 23 24 namespace webrtc { 25 26 class LossNotificationController { 27 public: 28 struct FrameDetails { 29 bool is_keyframe; 30 int64_t frame_id; 31 rtc::ArrayView<const int64_t> frame_dependencies; 32 }; 33 34 LossNotificationController(KeyFrameRequestSender* key_frame_request_sender, 35 LossNotificationSender* loss_notification_sender); 36 ~LossNotificationController(); 37 38 // An RTP packet was received from the network. 39 // `frame` is non-null iff the packet is the first packet in the frame. 40 void OnReceivedPacket(uint16_t rtp_seq_num, const FrameDetails* frame); 41 42 // A frame was assembled from packets previously received. 43 // (Should be called even if the frame was composed of a single packet.) 44 void OnAssembledFrame(uint16_t first_seq_num, 45 int64_t frame_id, 46 bool discardable, 47 rtc::ArrayView<const int64_t> frame_dependencies); 48 49 private: 50 void DiscardOldInformation(); 51 52 bool AllDependenciesDecodable( 53 rtc::ArrayView<const int64_t> frame_dependencies) const; 54 55 // When the loss of a packet or the non-decodability of a frame is detected, 56 // produces a key frame request or a loss notification. 57 // 1. `last_received_seq_num` is the last received sequence number. 58 // 2. `decodability_flag` refers to the frame associated with the last packet. 59 // It is set to `true` if and only if all of that frame's dependencies are 60 // known to be decodable, and the frame itself is not yet known to be 61 // unassemblable (i.e. no earlier parts of it were lost). 62 // Clarifications: 63 // a. In a multi-packet frame, the first packet reveals the frame's 64 // dependencies, but it is not yet known whether all parts of the 65 // current frame will be received. 66 // b. In a multi-packet frame, if the first packet is missed, the 67 // dependencies are unknown, but it is known that the frame itself 68 // is unassemblable. 69 void HandleLoss(uint16_t last_received_seq_num, bool decodability_flag); 70 71 KeyFrameRequestSender* const key_frame_request_sender_ 72 RTC_GUARDED_BY(sequence_checker_); 73 74 LossNotificationSender* const loss_notification_sender_ 75 RTC_GUARDED_BY(sequence_checker_); 76 77 // Tracked to avoid processing repeated frames (buggy/malicious remote). 78 absl::optional<int64_t> last_received_frame_id_ 79 RTC_GUARDED_BY(sequence_checker_); 80 81 // Tracked to avoid processing repeated packets. 82 absl::optional<uint16_t> last_received_seq_num_ 83 RTC_GUARDED_BY(sequence_checker_); 84 85 // Tracked in order to correctly report the potential-decodability of 86 // multi-packet frames. 87 bool current_frame_potentially_decodable_ RTC_GUARDED_BY(sequence_checker_); 88 89 // Loss notifications contain the sequence number of the first packet of 90 // the last decodable-and-non-discardable frame. Since this is a bit of 91 // a mouthful, last_decodable_non_discardable_.first_seq_num is used, 92 // which hopefully is a bit easier for human beings to parse 93 // than `first_seq_num_of_last_decodable_non_discardable_`. 94 struct FrameInfo { FrameInfoFrameInfo95 explicit FrameInfo(uint16_t first_seq_num) : first_seq_num(first_seq_num) {} 96 uint16_t first_seq_num; 97 }; 98 absl::optional<FrameInfo> last_decodable_non_discardable_ 99 RTC_GUARDED_BY(sequence_checker_); 100 101 // Track which frames are decodable. Later frames are also decodable if 102 // all of their dependencies can be found in this container. 103 // (Naturally, later frames must also be assemblable to be decodable.) 104 std::set<int64_t> decodable_frame_ids_ RTC_GUARDED_BY(sequence_checker_); 105 106 RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; 107 }; 108 109 } // namespace webrtc 110 111 #endif // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_ 112