blob: 6fc5eb858c4ed2ea22767ba44fd7cff510da959e [file] [log] [blame]
Elad Alon10874b22019-02-21 16:25:40 +01001/*
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 <set>
15
16#include "absl/types/optional.h"
17#include "modules/include/module_common_types.h"
Niels Möllera7401422019-09-13 14:18:58 +020018#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
Elad Alon10874b22019-02-21 16:25:40 +010019#include "rtc_base/numerics/sequence_number_util.h"
Sebastian Janssonb55015e2019-04-09 13:44:04 +020020#include "rtc_base/synchronization/sequence_checker.h"
Elad Alon10874b22019-02-21 16:25:40 +010021
22namespace webrtc {
23
24class LossNotificationController {
25 public:
26 LossNotificationController(KeyFrameRequestSender* key_frame_request_sender,
27 LossNotificationSender* loss_notification_sender);
28 ~LossNotificationController();
29
30 // An RTP packet was received from the network.
Niels Möllera7401422019-09-13 14:18:58 +020031 void OnReceivedPacket(uint16_t sequence_number,
32 const RtpGenericFrameDescriptor& generic_descriptor);
Elad Alon10874b22019-02-21 16:25:40 +010033
34 // A frame was assembled from packets previously received.
35 // (Should be called even if the frame was composed of a single packet.)
36 void OnAssembledFrame(uint16_t first_seq_num,
37 uint16_t frame_id,
38 bool discardable,
39 rtc::ArrayView<const uint16_t> frame_dependency_diffs);
40
41 private:
42 void DiscardOldInformation();
43
44 bool AllDependenciesDecodable(
Philip Eliasson1f850a62019-03-19 12:15:00 +000045 int64_t unwrapped_frame_id,
Elad Alon10874b22019-02-21 16:25:40 +010046 rtc::ArrayView<const uint16_t> frame_dependency_diffs) const;
47
48 // When the loss of a packet or the non-decodability of a frame is detected,
49 // produces a key frame request or a loss notification.
50 // 1. |last_received_seq_num| is the last received sequence number.
51 // 2. |decodability_flag| refers to the frame associated with the last packet.
52 // It is set to |true| if and only if all of that frame's dependencies are
53 // known to be decodable, and the frame itself is not yet known to be
54 // unassemblable (i.e. no earlier parts of it were lost).
55 // Clarifications:
56 // a. In a multi-packet frame, the first packet reveals the frame's
57 // dependencies, but it is not yet known whether all parts of the
58 // current frame will be received.
59 // b. In a multi-packet frame, if the first packet is missed, the
60 // dependencies are unknown, but it is known that the frame itself
61 // is unassemblable.
62 void HandleLoss(uint16_t last_received_seq_num, bool decodability_flag);
63
64 KeyFrameRequestSender* const key_frame_request_sender_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020065 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010066
67 LossNotificationSender* const loss_notification_sender_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020068 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010069
70 SeqNumUnwrapper<uint16_t> frame_id_unwrapper_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020071 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010072
73 // Tracked to avoid processing repeated frames (buggy/malicious remote).
Philip Eliasson1f850a62019-03-19 12:15:00 +000074 absl::optional<int64_t> last_received_unwrapped_frame_id_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020075 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010076
77 // Tracked to avoid processing repeated packets.
78 absl::optional<uint16_t> last_received_seq_num_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020079 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010080
81 // Tracked in order to correctly report the potential-decodability of
82 // multi-packet frames.
Sebastian Janssonb55015e2019-04-09 13:44:04 +020083 bool current_frame_potentially_decodable_ RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010084
85 // Loss notifications contain the sequence number of the first packet of
86 // the last decodable-and-non-discardable frame. Since this is a bit of
87 // a mouthful, last_decodable_non_discardable_.first_seq_num is used,
88 // which hopefully is a bit easier for human beings to parse
89 // than |first_seq_num_of_last_decodable_non_discardable_|.
90 struct FrameInfo {
91 explicit FrameInfo(uint16_t first_seq_num) : first_seq_num(first_seq_num) {}
92 uint16_t first_seq_num;
93 };
94 absl::optional<FrameInfo> last_decodable_non_discardable_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020095 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010096
97 // Track which frames are decodable. Later frames are also decodable if
98 // all of their dependencies can be found in this container.
99 // (Naturally, later frames must also be assemblable to be decodable.)
Philip Eliasson1f850a62019-03-19 12:15:00 +0000100 std::set<int64_t> decodable_unwrapped_frame_ids_
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200101 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +0100102
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200103 SequenceChecker sequence_checker_;
Elad Alon10874b22019-02-21 16:25:40 +0100104};
105
106} // namespace webrtc
107
108#endif // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_