Forward LossNotification from RTCPReceiver to EncoderRtcpFeedback

TBR=sprang@webrtc.org

Bug: webrtc:10501
Change-Id: I09a571a65ba8515b027ee32d1f46e5cc7f699704
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131325
Reviewed-by: Elad Alon <eladalon@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27513}
This commit is contained in:
Elad Alon 2019-04-09 11:55:13 +02:00 committed by Commit Bot
parent 1f44bc1df2
commit 0a8562e276
12 changed files with 88 additions and 30 deletions

View File

@ -54,6 +54,7 @@ class TransportFeedbackObserver;
struct RtpSenderObservers {
RtcpRttStats* rtcp_rtt_stats;
RtcpIntraFrameObserver* intra_frame_callback;
RtcpLossNotificationObserver* rtcp_loss_notification_observer;
RtcpStatisticsCallback* rtcp_stats;
StreamDataCountersCallback* rtp_stats;
BitrateStatisticsObserver* bitrate_observer;

View File

@ -63,6 +63,7 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
int rtcp_report_interval_ms,
Transport* send_transport,
RtcpIntraFrameObserver* intra_frame_callback,
RtcpLossNotificationObserver* rtcp_loss_notification_observer,
RtcpBandwidthObserver* bandwidth_callback,
RtpTransportControllerSendInterface* transport,
RtcpRttStats* rtt_stats,
@ -84,6 +85,8 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
configuration.receiver_only = false;
configuration.outgoing_transport = send_transport;
configuration.intra_frame_callback = intra_frame_callback;
configuration.rtcp_loss_notification_observer =
rtcp_loss_notification_observer;
configuration.bandwidth_callback = bandwidth_callback;
configuration.transport_feedback_callback =
transport->transport_feedback_observer();
@ -228,24 +231,26 @@ RtpVideoSender::RtpVideoSender(
flexfec_sender_(
MaybeCreateFlexfecSender(clock, rtp_config, suspended_ssrcs_)),
fec_controller_(std::move(fec_controller)),
rtp_streams_(CreateRtpStreamSenders(clock,
rtp_config,
rtcp_report_interval_ms,
send_transport,
observers.intra_frame_callback,
transport->GetBandwidthObserver(),
transport,
observers.rtcp_rtt_stats,
flexfec_sender_.get(),
observers.bitrate_observer,
observers.rtcp_type_observer,
observers.send_delay_observer,
observers.send_packet_observer,
event_log,
retransmission_limiter,
this,
frame_encryptor,
crypto_options)),
rtp_streams_(
CreateRtpStreamSenders(clock,
rtp_config,
rtcp_report_interval_ms,
send_transport,
observers.intra_frame_callback,
observers.rtcp_loss_notification_observer,
transport->GetBandwidthObserver(),
transport,
observers.rtcp_rtt_stats,
flexfec_sender_.get(),
observers.bitrate_observer,
observers.rtcp_type_observer,
observers.send_delay_observer,
observers.send_packet_observer,
event_log,
retransmission_limiter,
this,
frame_encryptor,
crypto_options)),
rtp_config_(rtp_config),
transport_(transport),
transport_overhead_bytes_per_packet_(0),

View File

@ -64,9 +64,12 @@ class RtpRtcp : public Module, public RtcpFeedbackSenderInterface {
// out on the network.
Transport* outgoing_transport = nullptr;
// Called when the receiver request a intra frame.
// Called when the receiver requests an intra frame.
RtcpIntraFrameObserver* intra_frame_callback = nullptr;
// Called when the receiver sends a loss notification.
RtcpLossNotificationObserver* rtcp_loss_notification_observer = nullptr;
// Called when we receive a changed estimate from the receiver of out
// stream.
RtcpBandwidthObserver* bandwidth_callback = nullptr;

View File

@ -186,6 +186,18 @@ class RtcpIntraFrameObserver {
virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) = 0;
};
// Observer for incoming LossNotification RTCP messages.
// See the documentation of LossNotification for details.
class RtcpLossNotificationObserver {
public:
virtual ~RtcpLossNotificationObserver() = default;
virtual void OnReceivedLossNotification(uint32_t ssrc,
uint16_t seq_num_of_last_decodable,
uint16_t seq_num_of_last_received,
bool decodability_flag) = 0;
};
class RtcpBandwidthObserver {
public:
// REMB or TMMBR

View File

@ -131,6 +131,7 @@ RTCPReceiver::RTCPReceiver(
RtcpPacketTypeCounterObserver* packet_type_counter_observer,
RtcpBandwidthObserver* rtcp_bandwidth_observer,
RtcpIntraFrameObserver* rtcp_intra_frame_observer,
RtcpLossNotificationObserver* rtcp_loss_notification_observer,
TransportFeedbackObserver* transport_feedback_observer,
VideoBitrateAllocationObserver* bitrate_allocation_observer,
int report_interval_ms,
@ -140,6 +141,7 @@ RTCPReceiver::RTCPReceiver(
rtp_rtcp_(owner),
rtcp_bandwidth_observer_(rtcp_bandwidth_observer),
rtcp_intra_frame_observer_(rtcp_intra_frame_observer),
rtcp_loss_notification_observer_(rtcp_loss_notification_observer),
transport_feedback_observer_(transport_feedback_observer),
bitrate_allocation_observer_(bitrate_allocation_observer),
report_interval_ms_(report_interval_ms),
@ -1019,6 +1021,18 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
rtcp_intra_frame_observer_->OnReceivedIntraFrameRequest(local_ssrc);
}
}
if (rtcp_loss_notification_observer_ &&
(packet_information.packet_type_flags & kRtcpLossNotification)) {
rtcp::LossNotification* loss_notification =
packet_information.loss_notification.get();
RTC_DCHECK(loss_notification);
if (loss_notification->media_ssrc() == local_ssrc) {
rtcp_loss_notification_observer_->OnReceivedLossNotification(
loss_notification->media_ssrc(), loss_notification->last_decoded(),
loss_notification->last_received(),
loss_notification->decodability_flag());
}
}
if (rtcp_bandwidth_observer_) {
RTC_DCHECK(!receiver_only_);
if (packet_information.packet_type_flags & kRtcpRemb) {
@ -1028,16 +1042,6 @@ void RTCPReceiver::TriggerCallbacksFromRtcpPacket(
rtcp_bandwidth_observer_->OnReceivedEstimatedBitrate(
packet_information.receiver_estimated_max_bitrate_bps);
}
if (packet_information.packet_type_flags & kRtcpLossNotification) {
rtcp::LossNotification* loss_notification =
packet_information.loss_notification.get();
RTC_DCHECK(loss_notification);
RTC_LOG(LS_VERBOSE) << "Incoming Loss Notification: ("
<< loss_notification->last_decoded() << ", "
<< loss_notification->last_received() << ", "
<< loss_notification->decodability_flag() << ").";
// TODO(eladalon): Notify observer.
}
if ((packet_information.packet_type_flags & kRtcpSr) ||
(packet_information.packet_type_flags & kRtcpRr)) {
int64_t now_ms = clock_->TimeInMilliseconds();

View File

@ -55,6 +55,7 @@ class RTCPReceiver {
RtcpPacketTypeCounterObserver* packet_type_counter_observer,
RtcpBandwidthObserver* rtcp_bandwidth_observer,
RtcpIntraFrameObserver* rtcp_intra_frame_observer,
RtcpLossNotificationObserver* rtcp_loss_notification_observer,
TransportFeedbackObserver* transport_feedback_observer,
VideoBitrateAllocationObserver* bitrate_allocation_observer,
int report_interval_ms,
@ -215,6 +216,7 @@ class RTCPReceiver {
rtc::CriticalSection feedbacks_lock_;
RtcpBandwidthObserver* const rtcp_bandwidth_observer_;
RtcpIntraFrameObserver* const rtcp_intra_frame_observer_;
RtcpLossNotificationObserver* const rtcp_loss_notification_observer_;
TransportFeedbackObserver* const transport_feedback_observer_;
VideoBitrateAllocationObserver* const bitrate_allocation_observer_;
const int report_interval_ms_;

View File

@ -66,6 +66,16 @@ class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
};
class MockRtcpLossNotificationObserver : public RtcpLossNotificationObserver {
public:
~MockRtcpLossNotificationObserver() override = default;
MOCK_METHOD4(OnReceivedLossNotification,
void(uint32_t ssrc,
uint16_t seq_num_of_last_decodable,
uint16_t seq_num_of_last_received,
bool decodability_flag));
};
class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
public:
MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
@ -119,6 +129,7 @@ class RtcpReceiverTest : public ::testing::Test {
&packet_type_counter_observer_,
&bandwidth_observer_,
&intra_frame_observer_,
&rtcp_loss_notification_observer_,
&transport_feedback_observer_,
&bitrate_allocation_observer_,
kRtcpIntervalMs,
@ -145,6 +156,7 @@ class RtcpReceiverTest : public ::testing::Test {
NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;

View File

@ -74,6 +74,7 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
configuration.rtcp_packet_type_counter_observer,
configuration.bandwidth_callback,
configuration.intra_frame_callback,
configuration.rtcp_loss_notification_observer,
configuration.transport_feedback_callback,
configuration.bitrate_allocation_observer,
configuration.rtcp_report_interval_ms > 0

View File

@ -40,7 +40,7 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
SimulatedClock clock(1234);
RTCPReceiver receiver(&clock, false, nullptr, nullptr, nullptr, nullptr,
nullptr, kRtcpIntervalMs, &rtp_rtcp_module);
nullptr, nullptr, kRtcpIntervalMs, &rtp_rtcp_module);
receiver.IncomingPacket(data, size);
}

View File

@ -68,4 +68,12 @@ void EncoderRtcpFeedback::OnKeyFrameRequested(uint64_t channel_id) {
video_stream_encoder_->SendKeyFrame();
}
void EncoderRtcpFeedback::OnReceivedLossNotification(
uint32_t ssrc,
uint16_t seq_num_of_last_decodable,
uint16_t seq_num_of_last_received,
bool decodability_flag) {
// TODO(eladalon): Handle.
}
} // namespace webrtc

View File

@ -27,16 +27,25 @@ class VideoStreamEncoderInterface;
// TODO(bugs.webrtc.org/9719): Should be eliminated when RtpMediaTransport is
// implemented.
class EncoderRtcpFeedback : public RtcpIntraFrameObserver,
public RtcpLossNotificationObserver,
public MediaTransportKeyFrameRequestCallback {
public:
EncoderRtcpFeedback(Clock* clock,
const std::vector<uint32_t>& ssrcs,
VideoStreamEncoderInterface* encoder);
~EncoderRtcpFeedback() override = default;
void OnReceivedIntraFrameRequest(uint32_t ssrc) override;
// Implements MediaTransportKeyFrameRequestCallback
void OnKeyFrameRequested(uint64_t channel_id) override;
// Implements RtcpLossNotificationObserver.
void OnReceivedLossNotification(uint32_t ssrc,
uint16_t seq_num_of_last_decodable,
uint16_t seq_num_of_last_received,
bool decodability_flag) override;
private:
bool HasSsrc(uint32_t ssrc);

View File

@ -149,6 +149,7 @@ RtpSenderObservers CreateObservers(CallStats* call_stats,
RtpSenderObservers observers;
observers.rtcp_rtt_stats = call_stats;
observers.intra_frame_callback = encoder_feedback;
observers.rtcp_loss_notification_observer = encoder_feedback;
observers.rtcp_stats = stats_proxy;
observers.rtp_stats = stats_proxy;
observers.bitrate_observer = stats_proxy;