blob: ecba41267ba2604c4343f4cae3e77a3fa760531f [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
Danil Chapovalov159c4142020-01-23 15:17:52 +010014#include <stdint.h>
15
Elad Alon10874b22019-02-21 16:25:40 +010016#include <set>
17
18#include "absl/types/optional.h"
Danil Chapovalov159c4142020-01-23 15:17:52 +010019#include "api/array_view.h"
Artem Titovd15a5752021-02-10 14:31:24 +010020#include "api/sequence_checker.h"
Elad Alon10874b22019-02-21 16:25:40 +010021#include "modules/include/module_common_types.h"
Mirko Bonadei20e4c802020-11-23 11:07:42 +010022#include "rtc_base/system/no_unique_address.h"
Elad Alon10874b22019-02-21 16:25:40 +010023
24namespace webrtc {
25
26class LossNotificationController {
27 public:
Danil Chapovalov159c4142020-01-23 15:17:52 +010028 struct FrameDetails {
29 bool is_keyframe;
30 int64_t frame_id;
31 rtc::ArrayView<const int64_t> frame_dependencies;
32 };
33
Elad Alon10874b22019-02-21 16:25:40 +010034 LossNotificationController(KeyFrameRequestSender* key_frame_request_sender,
35 LossNotificationSender* loss_notification_sender);
36 ~LossNotificationController();
37
38 // An RTP packet was received from the network.
Artem Titovdcd7fc72021-08-09 13:02:57 +020039 // `frame` is non-null iff the packet is the first packet in the frame.
Danil Chapovalov159c4142020-01-23 15:17:52 +010040 void OnReceivedPacket(uint16_t rtp_seq_num, const FrameDetails* frame);
Elad Alon10874b22019-02-21 16:25:40 +010041
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,
Danil Chapovalov159c4142020-01-23 15:17:52 +010045 int64_t frame_id,
Elad Alon10874b22019-02-21 16:25:40 +010046 bool discardable,
Danil Chapovalov159c4142020-01-23 15:17:52 +010047 rtc::ArrayView<const int64_t> frame_dependencies);
Elad Alon10874b22019-02-21 16:25:40 +010048
49 private:
50 void DiscardOldInformation();
51
52 bool AllDependenciesDecodable(
Danil Chapovalov159c4142020-01-23 15:17:52 +010053 rtc::ArrayView<const int64_t> frame_dependencies) const;
Elad Alon10874b22019-02-21 16:25:40 +010054
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.
Artem Titovdcd7fc72021-08-09 13:02:57 +020057 // 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
Elad Alon10874b22019-02-21 16:25:40 +010060 // 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_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020072 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010073
74 LossNotificationSender* const loss_notification_sender_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020075 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010076
Elad Alon10874b22019-02-21 16:25:40 +010077 // Tracked to avoid processing repeated frames (buggy/malicious remote).
Danil Chapovalov159c4142020-01-23 15:17:52 +010078 absl::optional<int64_t> last_received_frame_id_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020079 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010080
81 // Tracked to avoid processing repeated packets.
82 absl::optional<uint16_t> last_received_seq_num_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020083 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010084
85 // Tracked in order to correctly report the potential-decodability of
86 // multi-packet frames.
Sebastian Janssonb55015e2019-04-09 13:44:04 +020087 bool current_frame_potentially_decodable_ RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +010088
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
Artem Titovdcd7fc72021-08-09 13:02:57 +020093 // than `first_seq_num_of_last_decodable_non_discardable_`.
Elad Alon10874b22019-02-21 16:25:40 +010094 struct FrameInfo {
95 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_
Sebastian Janssonb55015e2019-04-09 13:44:04 +020099 RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +0100100
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.)
Danil Chapovalov159c4142020-01-23 15:17:52 +0100104 std::set<int64_t> decodable_frame_ids_ RTC_GUARDED_BY(sequence_checker_);
Elad Alon10874b22019-02-21 16:25:40 +0100105
Mirko Bonadei20e4c802020-11-23 11:07:42 +0100106 RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
Elad Alon10874b22019-02-21 16:25:40 +0100107};
108
109} // namespace webrtc
110
111#endif // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_