[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`. // thread` but will be `network thread`.
virtual void SetFlexFecProtection(RtpPacketSinkInterface* flexfec_sink) = 0; 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: protected:
virtual ~VideoReceiveStreamInterface() {} virtual ~VideoReceiveStreamInterface() {}
}; };

View File

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

View File

@ -2985,7 +2985,7 @@ bool WebRtcVideoChannel::WebRtcVideoReceiveStream::ReconfigureCodecs(
const bool has_lntf = HasLntf(codec.codec); const bool has_lntf = HasLntf(codec.codec);
if (config_.rtp.lntf.enabled != has_lntf) { if (config_.rtp.lntf.enabled != has_lntf) {
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; 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 = int nack_history_ms =
nack_enabled ? rtx_time != -1 ? rtx_time : kNackHistoryMs : 0; nack_enabled ? rtx_time != -1 ? rtx_time : kNackHistoryMs : 0;
if (config_.rtp.lntf.enabled == lntf_enabled && if (config_.rtp.nack.rtp_history_ms == nack_history_ms) {
config_.rtp.nack.rtp_history_ms == nack_history_ms) {
RTC_LOG(LS_INFO) RTC_LOG(LS_INFO)
<< "Ignoring call to SetFeedbackParameters because parameters are " << "Ignoring call to SetFeedbackParameters because parameters are "
"unchanged; lntf=" "unchanged; nack="
<< lntf_enabled << ", nack=" << nack_enabled << nack_enabled << ", rtx_time=" << rtx_time;
<< ", rtx_time=" << rtx_time;
return; 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; config_.rtp.nack.rtp_history_ms = nack_history_ms;
RTC_LOG_F(LS_INFO) << "(recv) because of SetFeedbackParameters; nack="
<< nack_enabled;
RecreateReceiveStream(); 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( RtpVideoStreamReceiver2::RtpVideoStreamReceiver2(
TaskQueueBase* current_queue, TaskQueueBase* current_queue,
Clock* clock, Clock* clock,
@ -935,6 +940,18 @@ void RtpVideoStreamReceiver2::SetPacketSink(
packet_sink_ = packet_sink; 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 { absl::optional<int64_t> RtpVideoStreamReceiver2::LastReceivedPacketMs() const {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_); RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
if (last_received_rtp_system_time_) { if (last_received_rtp_system_time_) {

View File

@ -194,6 +194,10 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender,
// thread` but will be `network thread`. // thread` but will be `network thread`.
void SetPacketSink(RtpPacketSinkInterface* packet_sink); 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> LastReceivedPacketMs() const;
absl::optional<int64_t> LastReceivedKeyframePacketMs() const; absl::optional<int64_t> LastReceivedKeyframePacketMs() const;
@ -236,6 +240,8 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender,
// Send all RTCP feedback messages buffered thus far. // Send all RTCP feedback messages buffered thus far.
void SendBufferedRtcpFeedback(); void SendBufferedRtcpFeedback();
void ClearLossNotificationState();
private: private:
// LNTF-related state. // LNTF-related state.
struct LossNotificationState { struct LossNotificationState {
@ -336,7 +342,8 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender,
RtcpFeedbackBuffer rtcp_feedback_buffer_; RtcpFeedbackBuffer rtcp_feedback_buffer_;
const std::unique_ptr<NackRequester> nack_module_; 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_ video_coding::PacketBuffer packet_buffer_
RTC_GUARDED_BY(packet_sequence_checker_); RTC_GUARDED_BY(packet_sequence_checker_);

View File

@ -517,6 +517,13 @@ void VideoReceiveStream2::SetFlexFecProtection(
(flexfec_sink != nullptr); (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( void VideoReceiveStream2::CreateAndRegisterExternalDecoder(
const Decoder& decoder) { const Decoder& decoder) {
TRACE_EVENT0("webrtc", TRACE_EVENT0("webrtc",

View File

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