111 lines
4.4 KiB
C
111 lines
4.4 KiB
C
|
/*
|
||
|
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
#ifndef MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
|
||
|
#define MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
|
||
|
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#include <set>
|
||
|
|
||
|
#include "absl/types/optional.h"
|
||
|
#include "api/array_view.h"
|
||
|
#include "modules/include/module_common_types.h"
|
||
|
#include "rtc_base/synchronization/sequence_checker.h"
|
||
|
|
||
|
namespace webrtc {
|
||
|
|
||
|
class LossNotificationController {
|
||
|
public:
|
||
|
struct FrameDetails {
|
||
|
bool is_keyframe;
|
||
|
int64_t frame_id;
|
||
|
rtc::ArrayView<const int64_t> frame_dependencies;
|
||
|
};
|
||
|
|
||
|
LossNotificationController(KeyFrameRequestSender* key_frame_request_sender,
|
||
|
LossNotificationSender* loss_notification_sender);
|
||
|
~LossNotificationController();
|
||
|
|
||
|
// An RTP packet was received from the network.
|
||
|
// |frame| is non-null iff the packet is the first packet in the frame.
|
||
|
void OnReceivedPacket(uint16_t rtp_seq_num, const FrameDetails* frame);
|
||
|
|
||
|
// A frame was assembled from packets previously received.
|
||
|
// (Should be called even if the frame was composed of a single packet.)
|
||
|
void OnAssembledFrame(uint16_t first_seq_num,
|
||
|
int64_t frame_id,
|
||
|
bool discardable,
|
||
|
rtc::ArrayView<const int64_t> frame_dependencies);
|
||
|
|
||
|
private:
|
||
|
void DiscardOldInformation();
|
||
|
|
||
|
bool AllDependenciesDecodable(
|
||
|
rtc::ArrayView<const int64_t> frame_dependencies) const;
|
||
|
|
||
|
// When the loss of a packet or the non-decodability of a frame is detected,
|
||
|
// produces a key frame request or a loss notification.
|
||
|
// 1. |last_received_seq_num| is the last received sequence number.
|
||
|
// 2. |decodability_flag| refers to the frame associated with the last packet.
|
||
|
// It is set to |true| if and only if all of that frame's dependencies are
|
||
|
// known to be decodable, and the frame itself is not yet known to be
|
||
|
// unassemblable (i.e. no earlier parts of it were lost).
|
||
|
// Clarifications:
|
||
|
// a. In a multi-packet frame, the first packet reveals the frame's
|
||
|
// dependencies, but it is not yet known whether all parts of the
|
||
|
// current frame will be received.
|
||
|
// b. In a multi-packet frame, if the first packet is missed, the
|
||
|
// dependencies are unknown, but it is known that the frame itself
|
||
|
// is unassemblable.
|
||
|
void HandleLoss(uint16_t last_received_seq_num, bool decodability_flag);
|
||
|
|
||
|
KeyFrameRequestSender* const key_frame_request_sender_
|
||
|
RTC_GUARDED_BY(sequence_checker_);
|
||
|
|
||
|
LossNotificationSender* const loss_notification_sender_
|
||
|
RTC_GUARDED_BY(sequence_checker_);
|
||
|
|
||
|
// Tracked to avoid processing repeated frames (buggy/malicious remote).
|
||
|
absl::optional<int64_t> last_received_frame_id_
|
||
|
RTC_GUARDED_BY(sequence_checker_);
|
||
|
|
||
|
// Tracked to avoid processing repeated packets.
|
||
|
absl::optional<uint16_t> last_received_seq_num_
|
||
|
RTC_GUARDED_BY(sequence_checker_);
|
||
|
|
||
|
// Tracked in order to correctly report the potential-decodability of
|
||
|
// multi-packet frames.
|
||
|
bool current_frame_potentially_decodable_ RTC_GUARDED_BY(sequence_checker_);
|
||
|
|
||
|
// Loss notifications contain the sequence number of the first packet of
|
||
|
// the last decodable-and-non-discardable frame. Since this is a bit of
|
||
|
// a mouthful, last_decodable_non_discardable_.first_seq_num is used,
|
||
|
// which hopefully is a bit easier for human beings to parse
|
||
|
// than |first_seq_num_of_last_decodable_non_discardable_|.
|
||
|
struct FrameInfo {
|
||
|
explicit FrameInfo(uint16_t first_seq_num) : first_seq_num(first_seq_num) {}
|
||
|
uint16_t first_seq_num;
|
||
|
};
|
||
|
absl::optional<FrameInfo> last_decodable_non_discardable_
|
||
|
RTC_GUARDED_BY(sequence_checker_);
|
||
|
|
||
|
// Track which frames are decodable. Later frames are also decodable if
|
||
|
// all of their dependencies can be found in this container.
|
||
|
// (Naturally, later frames must also be assemblable to be decodable.)
|
||
|
std::set<int64_t> decodable_frame_ids_ RTC_GUARDED_BY(sequence_checker_);
|
||
|
|
||
|
SequenceChecker sequence_checker_;
|
||
|
};
|
||
|
|
||
|
} // namespace webrtc
|
||
|
|
||
|
#endif // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
|