Connect LossNotificationController to RtpRtcp
* LossNotificationController is the class that decides when to issue
LossNotification RTCP messages.
* RtpRtcp handles the technicalities of producing RTCP messages.
Bug: webrtc:10336
Change-Id: I292536257a984ca85d21d9cfa38e7ff2569cbb39
Reviewed-on: https://webrtc-review.googlesource.com/c/124123
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26840}
diff --git a/video/rtp_video_stream_receiver.cc b/video/rtp_video_stream_receiver.cc
index df492ff..f40df3e 100644
--- a/video/rtp_video_stream_receiver.cc
+++ b/video/rtp_video_stream_receiver.cc
@@ -15,7 +15,6 @@
#include <vector>
#include "absl/memory/memory.h"
-
#include "media/base/media_constants.h"
#include "modules/pacing/packet_router.h"
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
@@ -143,7 +142,11 @@
process_thread_->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE);
- if (config_.rtp.nack.rtp_history_ms != 0) {
+ if (webrtc::field_trial::IsEnabled("WebRTC-RtcpLossNotification")) {
+ loss_notification_controller_ =
+ absl::make_unique<LossNotificationController>(keyframe_request_sender_,
+ this);
+ } else if (config_.rtp.nack.rtp_history_ms != 0) {
nack_module_ = absl::make_unique<NackModule>(clock_, nack_sender,
keyframe_request_sender);
process_thread_->RegisterModule(nack_module_.get(), RTC_FROM_HERE);
@@ -234,6 +237,8 @@
ntp_estimator_.Estimate(rtp_header->header.timestamp);
VCMPacket packet(payload_data, payload_size, rtp_header_with_ntp);
+ packet.generic_descriptor = generic_descriptor;
+
if (nack_module_) {
const bool is_keyframe =
rtp_header->video_header().is_first_packet_in_frame &&
@@ -247,6 +252,16 @@
}
packet.receive_time_ms = clock_->TimeInMilliseconds();
+ if (loss_notification_controller_) {
+ if (is_recovered) {
+ // TODO(bugs.webrtc.org/10336): Implement support for reordering.
+ RTC_LOG(LS_WARNING)
+ << "LossNotificationController does not support reordering.";
+ } else {
+ loss_notification_controller_->OnReceivedPacket(packet);
+ }
+ }
+
if (packet.sizeBytes == 0) {
NotifyReceiverOfEmptyPacket(packet.seqNum);
return 0;
@@ -277,8 +292,6 @@
packet.dataPtr = data;
}
- packet.generic_descriptor = generic_descriptor;
-
packet_buffer_->InsertPacket(&packet);
return 0;
}
@@ -364,6 +377,14 @@
return rtp_rtcp_->RequestKeyFrame();
}
+void RtpVideoStreamReceiver::SendLossNotification(
+ uint16_t last_decoded_seq_num,
+ uint16_t last_received_seq_num,
+ bool decodability_flag) {
+ rtp_rtcp_->SendLossNotification(last_decoded_seq_num, last_received_seq_num,
+ decodability_flag);
+}
+
bool RtpVideoStreamReceiver::IsUlpfecEnabled() const {
return config_.rtp.ulpfec_payload_type != -1;
}
@@ -385,15 +406,25 @@
void RtpVideoStreamReceiver::OnAssembledFrame(
std::unique_ptr<video_coding::RtpFrameObject> frame) {
RTC_DCHECK_RUN_ON(&network_tc_);
- // Request a key frame as soon as possible.
- bool key_frame_requested = false;
- if (!has_received_frame_) {
- has_received_frame_ = true;
+ RTC_DCHECK(frame);
+
+ absl::optional<RtpGenericFrameDescriptor> descriptor =
+ frame->GetGenericFrameDescriptor();
+
+ if (loss_notification_controller_ && descriptor) {
+ loss_notification_controller_->OnAssembledFrame(
+ frame->first_seq_num(), descriptor->FrameId(),
+ descriptor->Discardable().value_or(false),
+ descriptor->FrameDependenciesDiffs());
+ } else if (!has_received_frame_) {
+ // Request a key frame as soon as possible.
if (frame->FrameType() != kVideoFrameKey) {
- key_frame_requested = true;
keyframe_request_sender_->RequestKeyFrame();
}
}
+
+ has_received_frame_ = true;
+
if (buffered_frame_decryptor_ == nullptr) {
reference_finder_->ManageFrame(std::move(frame));
} else {
@@ -607,6 +638,10 @@
nack_module_->OnReceivedPacket(seq_num, /* is_keyframe = */ false,
/* is _recovered = */ false);
}
+ if (loss_notification_controller_) {
+ RTC_LOG(LS_WARNING)
+ << "LossNotificationController does not expect empty packets.";
+ }
}
bool RtpVideoStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet,