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