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