xref: /aosp_15_r20/external/webrtc/modules/video_coding/loss_notification_controller.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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