From c74c3c244784fc1d6cea53ecb2dccfe353394e6a Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Thu, 23 May 2013 13:48:22 +0000 Subject: [PATCH] Adds integration test for RTX and fixes bugs found. BUG=1811 R=mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1529004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4096 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/modules/rtp_rtcp/source/rtp_sender.cc | 1 - .../video_coding/main/source/jitter_buffer.cc | 1 - .../primitives/framedrop_primitives.cc | 3 +- .../auto_test/source/vie_autotest_rtp_rtcp.cc | 80 ++++++++++++++++--- .../include/tb_external_transport.h | 8 +- .../testbed/tb_external_transport.cc | 8 +- webrtc/video_engine/vie_channel.cc | 8 +- webrtc/video_engine/vie_rtp_rtcp_impl.cc | 2 +- 8 files changed, 92 insertions(+), 19 deletions(-) diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index a0e27a8bd..5bbf3c539 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -510,7 +510,6 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, uint32_t min_resend_time) { TRACE_EVENT_INSTANT2("webrtc_rtp", "RTPSender::ReSendPacket", "timestamp", rtp_header.header.timestamp, "seqnum", rtp_header.header.sequenceNumber); - if (paced_sender_) { if (!paced_sender_->SendPacket(PacedSender::kHighPriority, rtp_header.header.ssrc, diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.cc b/webrtc/modules/video_coding/main/source/jitter_buffer.cc index 8e3d6adf9..0c0306a83 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer.cc +++ b/webrtc/modules/video_coding/main/source/jitter_buffer.cc @@ -627,7 +627,6 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet, int64_t now_ms = clock_->TimeInMilliseconds(); VCMFrameBufferEnum buffer_return = kSizeError; VCMFrameBufferEnum ret = kSizeError; - VCMFrameBuffer* frame = NULL; const VCMFrameBufferEnum error = GetFrame(packet, &frame); if (error != kNoError) { diff --git a/webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.cc b/webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.cc index b63daaca2..f62732b34 100644 --- a/webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.cc +++ b/webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.cc @@ -255,8 +255,9 @@ void TestFullStack(const TbInterfaces& interfaces, int32_t num_rtp_packets = 0; int32_t num_dropped_packets = 0; int32_t num_rtcp_packets = 0; + std::map packet_counters; external_transport.GetStats(num_rtp_packets, num_dropped_packets, - num_rtcp_packets); + num_rtcp_packets, &packet_counters); ViETest::Log("RTP packets : %5d", num_rtp_packets); ViETest::Log("Dropped packets: %5d", num_dropped_packets); ViETest::Log("RTCP packets : %5d", num_rtcp_packets); diff --git a/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc b/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc index f9fe5dcf1..dc34815b3 100644 --- a/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc +++ b/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc @@ -160,17 +160,83 @@ void ViEAutoTest::ViERtpRtcpStandardTest() EXPECT_STRCASEEQ(sendCName, remoteCName); } + // + // RTX + // + unsigned short recFractionsLost = 0; + unsigned int recCumulativeLost = 0; + unsigned int recExtendedMax = 0; + unsigned int recJitter = 0; + int recRttMs = 0; + unsigned int sentTotalBitrate = 0; + unsigned int sentVideoBitrate = 0; + unsigned int sentFecBitrate = 0; + unsigned int sentNackBitrate = 0; + + ViETest::Log("Testing NACK over RTX\n"); + EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel)); + EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel)); + + myTransport.ClearStats(); + + const uint8_t kRtxPayloadType = 96; + EXPECT_EQ(0, ViE.rtp_rtcp->SetNACKStatus(tbChannel.videoChannel, true)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetRtxSendPayloadType(tbChannel.videoChannel, + kRtxPayloadType)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetRtxReceivePayloadType(tbChannel.videoChannel, + kRtxPayloadType)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetLocalSSRC(tbChannel.videoChannel, 1234, + webrtc::kViEStreamTypeRtx, 0)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetRemoteSSRCType(tbChannel.videoChannel, + webrtc::kViEStreamTypeRtx, + 1234)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetStartSequenceNumber( + tbChannel.videoChannel, startSequenceNumber)); + EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel)); + EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel)); + + // Make sure the first key frame gets through. + AutoTestSleep(100); + const int kPacketLossRate = 20; + NetworkParameters network; + network.packet_loss_rate = kPacketLossRate; + network.loss_model = kUniformLoss; + myTransport.SetNetworkParameters(network); + AutoTestSleep(kAutoTestSleepTimeMs); + + EXPECT_EQ(0, ViE.rtp_rtcp->GetReceivedRTCPStatistics( + tbChannel.videoChannel, recFractionsLost, recCumulativeLost, + recExtendedMax, recJitter, recRttMs)); + EXPECT_EQ(0, ViE.rtp_rtcp->GetBandwidthUsage( + tbChannel.videoChannel, sentTotalBitrate, sentVideoBitrate, + sentFecBitrate, sentNackBitrate)); + + int num_rtp_packets = 0; + int num_dropped_packets = 0; + int num_rtcp_packets = 0; + std::map packet_counters; + myTransport.GetStats(num_rtp_packets, num_dropped_packets, num_rtcp_packets, + &packet_counters); + EXPECT_GT(num_rtp_packets, 0); + EXPECT_GT(num_dropped_packets, 0); + EXPECT_GT(num_rtcp_packets, 0); + EXPECT_GT(packet_counters[kRtxPayloadType], 0); + + // Make sure we have lost packets and that they were retransmitted. + EXPECT_GT(recCumulativeLost, 0u); + EXPECT_GT(sentTotalBitrate, 0u); + EXPECT_GT(sentNackBitrate, 0u); + // // Statistics // // Stop and restart to clear stats ViETest::Log("Testing statistics\n"); + EXPECT_EQ(0, ViE.rtp_rtcp->SetNACKStatus(tbChannel.videoChannel, false)); EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel)); EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel)); myTransport.ClearStats(); - const int kPacketLossRate = 20; - NetworkParameters network; network.packet_loss_rate = kPacketLossRate; network.loss_model = kUniformLoss; myTransport.SetNetworkParameters(network); @@ -189,16 +255,6 @@ void ViEAutoTest::ViERtpRtcpStandardTest() unsigned int sentExtendedMax = 0; unsigned int sentJitter = 0; int sentRttMs = 0; - unsigned short recFractionsLost = 0; - unsigned int recCumulativeLost = 0; - unsigned int recExtendedMax = 0; - unsigned int recJitter = 0; - int recRttMs = 0; - - unsigned int sentTotalBitrate = 0; - unsigned int sentVideoBitrate = 0; - unsigned int sentFecBitrate = 0; - unsigned int sentNackBitrate = 0; EXPECT_EQ(0, ViE.rtp_rtcp->GetBandwidthUsage( tbChannel.videoChannel, sentTotalBitrate, sentVideoBitrate, diff --git a/webrtc/video_engine/test/libvietest/include/tb_external_transport.h b/webrtc/video_engine/test/libvietest/include/tb_external_transport.h index 51cc58490..541b5cd52 100644 --- a/webrtc/video_engine/test/libvietest/include/tb_external_transport.h +++ b/webrtc/video_engine/test/libvietest/include/tb_external_transport.h @@ -102,9 +102,12 @@ public: void SetSSRCFilter(uint32_t SSRC); void ClearStats(); + // |packet_counters| is a map which counts the number of packets sent per + // payload type. void GetStats(int32_t& numRtpPackets, int32_t& numDroppedPackets, - int32_t& numRtcpPackets); + int32_t& numRtcpPackets, + std::map* packet_counters); void SetTemporalToggle(unsigned char layers); void EnableSSRCCheck(); @@ -153,6 +156,9 @@ private: int32_t _rtpCount; int32_t _rtcpCount; int32_t _dropCount; + // |packet_counters| is a map which counts the number of packets sent per + // payload type. + std::map packet_counters_; std::list _rtpPackets; std::list _rtcpPackets; diff --git a/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc b/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc index 7ea787d2a..ed891ac6c 100644 --- a/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc +++ b/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc @@ -53,6 +53,7 @@ TbExternalTransport::TbExternalTransport( _rtpCount(0), _rtcpCount(0), _dropCount(0), + packet_counters_(), _rtpPackets(), _rtcpPackets(), _send_frame_callback(NULL), @@ -109,6 +110,7 @@ int TbExternalTransport::SendPacket(int channel, const void *data, int len) { // Parse timestamp from RTP header according to RFC 3550, section 5.1. uint8_t* ptr = (uint8_t*)data; + uint8_t payload_type = ptr[1] & 0x7F; uint32_t rtp_timestamp = ptr[4] << 24; rtp_timestamp += ptr[5] << 16; rtp_timestamp += ptr[6] << 8; @@ -122,6 +124,7 @@ int TbExternalTransport::SendPacket(int channel, const void *data, int len) _lastSendRTPTimestamp != rtp_timestamp) { _send_frame_callback->FrameSent(rtp_timestamp); } + ++packet_counters_[payload_type]; _lastSendRTPTimestamp = rtp_timestamp; if (_filterSSRC) @@ -323,16 +326,19 @@ void TbExternalTransport::ClearStats() _rtpCount = 0; _dropCount = 0; _rtcpCount = 0; + packet_counters_.clear(); } void TbExternalTransport::GetStats(int32_t& numRtpPackets, int32_t& numDroppedPackets, - int32_t& numRtcpPackets) + int32_t& numRtcpPackets, + std::map* packet_counters) { webrtc::CriticalSectionScoped cs(&_statCrit); numRtpPackets = _rtpCount; numDroppedPackets = _dropCount; numRtcpPackets = _rtcpCount; + *packet_counters = packet_counters_; } void TbExternalTransport::EnableSSRCCheck() diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 2129742af..0eca8b47d 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -956,9 +956,15 @@ int32_t ViEChannel::SetSSRC(const uint32_t SSRC, "%s(usage:%d, SSRC: 0x%x, idx:%u)", __FUNCTION__, usage, SSRC, simulcast_idx); if (simulcast_idx == 0) { + if (usage == kViEStreamTypeRtx) { + return rtp_rtcp_->SetRTXSendStatus(kRtxRetransmitted, true, SSRC); + } return rtp_rtcp_->SetSSRC(SSRC); } CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + if (rtp_rtcp_->SetSSRC(SSRC) != 0) { + return -1; + } if (simulcast_idx > simulcast_rtp_rtcp_.size()) { return -1; } @@ -972,7 +978,7 @@ int32_t ViEChannel::SetSSRC(const uint32_t SSRC, if (usage == kViEStreamTypeRtx) { return rtp_rtcp->SetRTXSendStatus(kRtxRetransmitted, true, SSRC); } - return rtp_rtcp->SetSSRC(SSRC); + return 0; } int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage, diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.cc b/webrtc/video_engine/vie_rtp_rtcp_impl.cc index a34af02e6..7148a471d 100644 --- a/webrtc/video_engine/vie_rtp_rtcp_impl.cc +++ b/webrtc/video_engine/vie_rtp_rtcp_impl.cc @@ -247,7 +247,7 @@ int ViERTP_RTCPImpl::SetRtxSendPayloadType(const int video_channel, shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); return -1; } - if (!vie_channel->SetRtxSendPayloadType(payload_type)) { + if (vie_channel->SetRtxSendPayloadType(payload_type) != 0) { return -1; } return 0;