mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 22:00:47 +01:00

Create LossNotificationController, which produces LossNotification RTCP feedback messages when video packets/frames are lost. (LossNotification messages are sent when an RTP gap is detected, as well as when frames are later received which are undecodable because of the missing frames due to the previously dropped packets.) Bug: webrtc:10336 Change-Id: I7b3a156ed14e5a727349acdd82dae6997462421b Reviewed-on: https://webrtc-review.googlesource.com/c/123762 Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Elad Alon <eladalon@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26812}
108 lines
4.4 KiB
C++
108 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 <set>
|
|
|
|
#include "absl/types/optional.h"
|
|
#include "modules/include/module_common_types.h"
|
|
#include "modules/video_coding/packet.h"
|
|
#include "rtc_base/numerics/sequence_number_util.h"
|
|
#include "rtc_base/sequenced_task_checker.h"
|
|
|
|
namespace webrtc {
|
|
|
|
class LossNotificationController {
|
|
public:
|
|
LossNotificationController(KeyFrameRequestSender* key_frame_request_sender,
|
|
LossNotificationSender* loss_notification_sender);
|
|
~LossNotificationController();
|
|
|
|
// An RTP packet was received from the network.
|
|
void OnReceivedPacket(const VCMPacket& packet);
|
|
|
|
// 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,
|
|
uint16_t frame_id,
|
|
bool discardable,
|
|
rtc::ArrayView<const uint16_t> frame_dependency_diffs);
|
|
|
|
private:
|
|
void DiscardOldInformation();
|
|
|
|
bool AllDependenciesDecodable(
|
|
uint64_t unwrapped_frame_id,
|
|
rtc::ArrayView<const uint16_t> frame_dependency_diffs) 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(sequenced_task_checker_);
|
|
|
|
LossNotificationSender* const loss_notification_sender_
|
|
RTC_GUARDED_BY(sequenced_task_checker_);
|
|
|
|
SeqNumUnwrapper<uint16_t> frame_id_unwrapper_
|
|
RTC_GUARDED_BY(sequenced_task_checker_);
|
|
|
|
// Tracked to avoid processing repeated frames (buggy/malicious remote).
|
|
absl::optional<uint64_t> last_received_unwrapped_frame_id_
|
|
RTC_GUARDED_BY(sequenced_task_checker_);
|
|
|
|
// Tracked to avoid processing repeated packets.
|
|
absl::optional<uint16_t> last_received_seq_num_
|
|
RTC_GUARDED_BY(sequenced_task_checker_);
|
|
|
|
// Tracked in order to correctly report the potential-decodability of
|
|
// multi-packet frames.
|
|
bool current_frame_potentially_decodable_
|
|
RTC_GUARDED_BY(sequenced_task_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(sequenced_task_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<uint64_t> decodable_unwrapped_frame_ids_
|
|
RTC_GUARDED_BY(sequenced_task_checker_);
|
|
|
|
rtc::SequencedTaskChecker sequenced_task_checker_;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
|