From efaeda0c76fbf9a58c44931d525348ab59dd52b0 Mon Sep 17 00:00:00 2001 From: "asapersson@webrtc.org" Date: Mon, 20 Jan 2014 08:34:49 +0000 Subject: [PATCH] Add configuration and test for extended RTCP reference time reports to new video api. R=mflodman@webrtc.org, pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/6989004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5401 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/modules/rtp_rtcp/source/rtcp_sender.cc | 5 +- webrtc/video/call_tests.cc | 97 +++++++++++++++++++ webrtc/video/video_receive_stream.cc | 4 + webrtc/video_engine/vie_channel.cc | 5 - webrtc/video_receive_stream.h | 9 ++ 5 files changed, 112 insertions(+), 8 deletions(-) diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index 8cac9969a..a376df79c 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -1778,10 +1778,9 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, rtcpPacketTypeFlags |= kRtcpTmmbn; _sendTMMBN = false; } - if (xrSendReceiverReferenceTimeEnabled_ && - (rtcpPacketTypeFlags & kRtcpReport)) + if (rtcpPacketTypeFlags & kRtcpReport) { - if (!_sending) + if (xrSendReceiverReferenceTimeEnabled_ && !_sending) { rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime; } diff --git a/webrtc/video/call_tests.cc b/webrtc/video/call_tests.cc index 120fa16df..3ec66fdd6 100644 --- a/webrtc/video/call_tests.cc +++ b/webrtc/video/call_tests.cc @@ -127,6 +127,7 @@ class CallTest : public ::testing::Test { void ReceivesPliAndRecovers(int rtp_history_ms); void RespectsRtcpMode(newapi::RtcpMode rtcp_mode); + void TestXrReceiverReferenceTimeReport(bool enable_rrtr); scoped_ptr sender_call_; scoped_ptr receiver_call_; @@ -1051,4 +1052,100 @@ TEST_F(CallTest, ReceiveStreamSendsRemb) { observer.StopSending(); DestroyStreams(); } + +void CallTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { + static const int kNumRtcpReportPacketsToObserve = 5; + class RtcpXrObserver : public test::RtpRtcpObserver { + public: + explicit RtcpXrObserver(bool enable_rrtr) + : test::RtpRtcpObserver(kDefaultTimeoutMs), + enable_rrtr_(enable_rrtr), + sent_rtcp_sr_(0), + sent_rtcp_rr_(0), + sent_rtcp_rrtr_(0), + sent_rtcp_dlrr_(0) {} + private: + // Receive stream should send RR packets (and RRTR packets if enabled). + virtual Action OnReceiveRtcp(const uint8_t* packet, + size_t length) OVERRIDE { + RTCPUtility::RTCPParserV2 parser(packet, length, true); + EXPECT_TRUE(parser.IsValid()); + + RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); + while (packet_type != RTCPUtility::kRtcpNotValidCode) { + if (packet_type == RTCPUtility::kRtcpRrCode) { + ++sent_rtcp_rr_; + } else if ( + packet_type == RTCPUtility::kRtcpXrReceiverReferenceTimeCode) { + ++sent_rtcp_rrtr_; + } + EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode); + EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode); + packet_type = parser.Iterate(); + } + return SEND_PACKET; + } + // Send stream should send SR packets (and DLRR packets if enabled). + virtual Action OnSendRtcp(const uint8_t* packet, size_t length) { + RTCPUtility::RTCPParserV2 parser(packet, length, true); + EXPECT_TRUE(parser.IsValid()); + + RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); + while (packet_type != RTCPUtility::kRtcpNotValidCode) { + if (packet_type == RTCPUtility::kRtcpSrCode) { + ++sent_rtcp_sr_; + } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) { + ++sent_rtcp_dlrr_; + } + EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode); + packet_type = parser.Iterate(); + } + if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve && + sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) { + if (enable_rrtr_) { + EXPECT_GT(sent_rtcp_rrtr_, 0); + EXPECT_GT(sent_rtcp_dlrr_, 0); + } else { + EXPECT_EQ(0, sent_rtcp_rrtr_); + EXPECT_EQ(0, sent_rtcp_dlrr_); + } + observation_complete_->Set(); + } + return SEND_PACKET; + } + bool enable_rrtr_; + int sent_rtcp_sr_; + int sent_rtcp_rr_; + int sent_rtcp_rrtr_; + int sent_rtcp_dlrr_; + } observer(enable_rrtr); + + CreateCalls(Call::Config(observer.SendTransport()), + Call::Config(observer.ReceiveTransport())); + observer.SetReceivers(receiver_call_->Receiver(), + sender_call_->Receiver()); + + CreateTestConfigs(); + receive_config_.rtp.rtcp_mode = newapi::kRtcpReducedSize; + receive_config_.rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr; + + CreateStreams(); + CreateFrameGenerator(); + StartSending(); + + EXPECT_EQ(kEventSignaled, observer.Wait()) + << "Timed out while waiting for RTCP SR/RR packets to be sent."; + + StopSending(); + observer.StopSending(); + DestroyStreams(); +} + +TEST_F(CallTest, ReceiverReferenceTimeReportEnabled) { + TestXrReceiverReferenceTimeReport(true); +} + +TEST_F(CallTest, ReceiverReferenceTimeReportDisabled) { + TestXrReceiverReferenceTimeReport(false); +} } // namespace webrtc diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc index 747ab8f21..71fc1521e 100644 --- a/webrtc/video/video_receive_stream.cc +++ b/webrtc/video/video_receive_stream.cc @@ -127,6 +127,10 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine, image_process_->RegisterPreRenderCallback(channel_, config_.pre_render_callback); + if (config.rtp.rtcp_xr.receiver_reference_time_report) { + rtp_rtcp_->SetRtcpXrRrtrStatus(channel_, true); + } + clock_ = Clock::GetRealTimeClock(); } diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 6e58313b3..c0439e724 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -412,7 +412,6 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, rtp_rtcp->DeregisterSendRtpHeaderExtension( kRtpExtensionAbsoluteSendTime); } - rtp_rtcp->SetRtcpXrRrtrStatus(rtp_rtcp_->RtcpXrRrtrStatus()); rtp_rtcp->RegisterSendFrameCountObserver( rtp_rtcp_->GetSendFrameCountObserver()); rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback( @@ -939,10 +938,6 @@ int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { void ViEChannel::SetRtcpXrRrtrStatus(bool enable) { CriticalSectionScoped cs(rtp_rtcp_cs_.get()); rtp_rtcp_->SetRtcpXrRrtrStatus(enable); - for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); - it != simulcast_rtp_rtcp_.end(); it++) { - (*it)->SetRtcpXrRrtrStatus(enable); - } } void ViEChannel::SetTransmissionSmoothingStatus(bool enable) { diff --git a/webrtc/video_receive_stream.h b/webrtc/video_receive_stream.h index c6669b9d3..55e5a626a 100644 --- a/webrtc/video_receive_stream.h +++ b/webrtc/video_receive_stream.h @@ -119,6 +119,15 @@ class VideoReceiveStream { // See RtcpMode for description. newapi::RtcpMode rtcp_mode; + // Extended RTCP settings. + struct RtcpXr { + RtcpXr() : receiver_reference_time_report(false) {} + + // True if RTCP Receiver Reference Time Report Block extension + // (RFC 3611) should be enabled. + bool receiver_reference_time_report; + } rtcp_xr; + // See draft-alvestrand-rmcat-remb for information. bool remb;