[WebRtcVideoReceiveStream] Add SetLossNotificationEnabled

...to allow for turning on/off loss notifications for video receive
streams without tearing down and recreating the whole stream.

Bug: webrtc:11993
Change-Id: Ia961bd343ce816ffe3414f11e3a58bb3c235307c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/269252
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37688}
This commit is contained in:
Tommi
2022-08-03 16:13:53 +02:00
committed by WebRTC LUCI CQ
parent 39ff241eac
commit e644a4bde0
7 changed files with 53 additions and 10 deletions

View File

@ -294,6 +294,10 @@ class VideoReceiveStreamInterface : public MediaReceiveStreamInterface {
// thread` but will be `network thread`.
virtual void SetFlexFecProtection(RtpPacketSinkInterface* flexfec_sink) = 0;
// Turns on/off loss notifications. Must be called on the packet delivery
// thread.
virtual void SetLossNotificationEnabled(bool enabled) = 0;
protected:
virtual ~VideoReceiveStreamInterface() {}
};

View File

@ -289,6 +289,10 @@ class FakeVideoReceiveStream final
config_.rtp.protected_by_flexfec = (sink != nullptr);
}
void SetLossNotificationEnabled(bool enabled) override {
config_.rtp.lntf.enabled = enabled;
}
void Start() override;
void Stop() override;

View File

@ -2985,7 +2985,7 @@ bool WebRtcVideoChannel::WebRtcVideoReceiveStream::ReconfigureCodecs(
const bool has_lntf = HasLntf(codec.codec);
if (config_.rtp.lntf.enabled != has_lntf) {
config_.rtp.lntf.enabled = has_lntf;
recreate_needed = true;
stream_->SetLossNotificationEnabled(has_lntf);
}
const int rtp_history_ms = HasNack(codec.codec) ? kNackHistoryMs : 0;
@ -3060,23 +3060,26 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetFeedbackParameters(
}
}
config_.rtp.lntf.enabled = lntf_enabled;
stream_->SetLossNotificationEnabled(lntf_enabled);
int nack_history_ms =
nack_enabled ? rtx_time != -1 ? rtx_time : kNackHistoryMs : 0;
if (config_.rtp.lntf.enabled == lntf_enabled &&
config_.rtp.nack.rtp_history_ms == nack_history_ms) {
if (config_.rtp.nack.rtp_history_ms == nack_history_ms) {
RTC_LOG(LS_INFO)
<< "Ignoring call to SetFeedbackParameters because parameters are "
"unchanged; lntf="
<< lntf_enabled << ", nack=" << nack_enabled
<< ", rtx_time=" << rtx_time;
"unchanged; nack="
<< nack_enabled << ", rtx_time=" << rtx_time;
return;
}
config_.rtp.lntf.enabled = lntf_enabled;
RTC_LOG_F(LS_INFO) << "(recv) because of SetFeedbackParameters; nack="
<< nack_enabled << ". rtp_history_ms "
<< config_.rtp.nack.rtp_history_ms << "->"
<< nack_history_ms;
config_.rtp.nack.rtp_history_ms = nack_history_ms;
RTC_LOG_F(LS_INFO) << "(recv) because of SetFeedbackParameters; nack="
<< nack_enabled;
RecreateReceiveStream();
}

View File

@ -202,6 +202,11 @@ void RtpVideoStreamReceiver2::RtcpFeedbackBuffer::SendBufferedRtcpFeedback() {
}
}
void RtpVideoStreamReceiver2::RtcpFeedbackBuffer::ClearLossNotificationState() {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
lntf_state_.reset();
}
RtpVideoStreamReceiver2::RtpVideoStreamReceiver2(
TaskQueueBase* current_queue,
Clock* clock,
@ -935,6 +940,18 @@ void RtpVideoStreamReceiver2::SetPacketSink(
packet_sink_ = packet_sink;
}
void RtpVideoStreamReceiver2::SetLossNotificationEnabled(bool enabled) {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
if (enabled && !loss_notification_controller_) {
loss_notification_controller_ =
std::make_unique<LossNotificationController>(&rtcp_feedback_buffer_,
&rtcp_feedback_buffer_);
} else if (!enabled && loss_notification_controller_) {
loss_notification_controller_.reset();
rtcp_feedback_buffer_.ClearLossNotificationState();
}
}
absl::optional<int64_t> RtpVideoStreamReceiver2::LastReceivedPacketMs() const {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
if (last_received_rtp_system_time_) {

View File

@ -194,6 +194,10 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender,
// thread` but will be `network thread`.
void SetPacketSink(RtpPacketSinkInterface* packet_sink);
// Turns on/off loss notifications. Must be called on the packet delivery
// thread.
void SetLossNotificationEnabled(bool enabled);
absl::optional<int64_t> LastReceivedPacketMs() const;
absl::optional<int64_t> LastReceivedKeyframePacketMs() const;
@ -236,6 +240,8 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender,
// Send all RTCP feedback messages buffered thus far.
void SendBufferedRtcpFeedback();
void ClearLossNotificationState();
private:
// LNTF-related state.
struct LossNotificationState {
@ -336,7 +342,8 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender,
RtcpFeedbackBuffer rtcp_feedback_buffer_;
const std::unique_ptr<NackRequester> nack_module_;
std::unique_ptr<LossNotificationController> loss_notification_controller_;
std::unique_ptr<LossNotificationController> loss_notification_controller_
RTC_GUARDED_BY(packet_sequence_checker_);
video_coding::PacketBuffer packet_buffer_
RTC_GUARDED_BY(packet_sequence_checker_);

View File

@ -517,6 +517,13 @@ void VideoReceiveStream2::SetFlexFecProtection(
(flexfec_sink != nullptr);
}
void VideoReceiveStream2::SetLossNotificationEnabled(bool enabled) {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
// TODO(tommi): Stop using the config struct for the internal state.
const_cast<bool&>(config_.rtp.lntf.enabled) = enabled;
rtp_video_stream_receiver_.SetLossNotificationEnabled(enabled);
}
void VideoReceiveStream2::CreateAndRegisterExternalDecoder(
const Decoder& decoder) {
TRACE_EVENT0("webrtc",

View File

@ -147,6 +147,7 @@ class VideoReceiveStream2
void SetTransportCc(bool transport_cc) override;
void SetRtcpMode(RtcpMode mode) override;
void SetFlexFecProtection(RtpPacketSinkInterface* flexfec_sink) override;
void SetLossNotificationEnabled(bool enabled) override;
webrtc::VideoReceiveStreamInterface::Stats GetStats() const override;