Index: webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc |
index eb76da67a62a9296247bc128436d20a1eca7d814..843ec1605d095828ae5efdd87e06d1c66ebcc933 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc |
@@ -17,16 +17,11 @@ |
#include "testing/gtest/include/gtest/gtest.h" |
#include "webrtc/common_types.h" |
-#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h" |
-#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h" |
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" |
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" |
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" |
-#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h" |
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" |
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h" |
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" |
-#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
+#include "webrtc/test/rtcp_packet_parser.h" |
+ |
+using ::testing::ElementsAre; |
namespace webrtc { |
@@ -185,264 +180,450 @@ TEST(NACKStringBuilderTest, TestCase13) { |
EXPECT_EQ(std::string("5-6,9"), builder.GetResult()); |
} |
-void CreateRtpPacket(const bool marker_bit, const uint8_t payload_type, |
- const uint16_t seq_num, const uint32_t timestamp, |
- const uint32_t ssrc, uint8_t* array, |
- size_t* cur_pos) { |
- ASSERT_LE(payload_type, 127); |
- array[(*cur_pos)++] = 0x80; |
- array[(*cur_pos)++] = payload_type | (marker_bit ? 0x80 : 0); |
- array[(*cur_pos)++] = seq_num >> 8; |
- array[(*cur_pos)++] = seq_num & 0xFF; |
- array[(*cur_pos)++] = timestamp >> 24; |
- array[(*cur_pos)++] = (timestamp >> 16) & 0xFF; |
- array[(*cur_pos)++] = (timestamp >> 8) & 0xFF; |
- array[(*cur_pos)++] = timestamp & 0xFF; |
- array[(*cur_pos)++] = ssrc >> 24; |
- array[(*cur_pos)++] = (ssrc >> 16) & 0xFF; |
- array[(*cur_pos)++] = (ssrc >> 8) & 0xFF; |
- array[(*cur_pos)++] = ssrc & 0xFF; |
- // VP8 payload header |
- array[(*cur_pos)++] = 0x90; // X bit = 1 |
- array[(*cur_pos)++] = 0x20; // T bit = 1 |
- array[(*cur_pos)++] = 0x00; // TID = 0 |
- array[(*cur_pos)++] = 0x00; // Key frame |
- array[(*cur_pos)++] = 0x00; |
- array[(*cur_pos)++] = 0x00; |
- array[(*cur_pos)++] = 0x9d; |
- array[(*cur_pos)++] = 0x01; |
- array[(*cur_pos)++] = 0x2a; |
- array[(*cur_pos)++] = 128; |
- array[(*cur_pos)++] = 0; |
- array[(*cur_pos)++] = 96; |
- array[(*cur_pos)++] = 0; |
-} |
+class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver { |
+ public: |
+ RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {} |
+ virtual ~RtcpPacketTypeCounterObserverImpl() {} |
+ void RtcpPacketTypesCounterUpdated( |
+ uint32_t ssrc, |
+ const RtcpPacketTypeCounter& packet_counter) override { |
+ ssrc_ = ssrc; |
+ counter_ = packet_counter; |
+ } |
+ uint32_t ssrc_; |
+ RtcpPacketTypeCounter counter_; |
+}; |
class TestTransport : public Transport, |
public NullRtpData { |
public: |
- TestTransport() |
- : rtcp_receiver_(NULL) { |
- } |
- void SetRTCPReceiver(RTCPReceiver* rtcp_receiver) { |
- rtcp_receiver_ = rtcp_receiver; |
- } |
+ TestTransport() {} |
+ |
int SendPacket(int /*ch*/, const void* /*data*/, size_t /*len*/) override { |
return -1; |
} |
- |
- int SendRTCPPacket(int /*ch*/, |
- const void* packet, |
- size_t packet_len) override { |
- RTCPUtility::RTCPParserV2 rtcpParser((uint8_t*)packet, |
- packet_len, |
- true); // Allow non-compound RTCP |
- |
- EXPECT_TRUE(rtcpParser.IsValid()); |
- RTCPHelp::RTCPPacketInformation rtcpPacketInformation; |
- EXPECT_EQ(0, rtcp_receiver_->IncomingRTCPPacket(rtcpPacketInformation, |
- &rtcpParser)); |
- rtcp_packet_info_.rtcpPacketTypeFlags = |
- rtcpPacketInformation.rtcpPacketTypeFlags; |
- rtcp_packet_info_.remoteSSRC = rtcpPacketInformation.remoteSSRC; |
- rtcp_packet_info_.applicationSubType = |
- rtcpPacketInformation.applicationSubType; |
- rtcp_packet_info_.applicationName = rtcpPacketInformation.applicationName; |
- rtcp_packet_info_.report_blocks = rtcpPacketInformation.report_blocks; |
- rtcp_packet_info_.rtt = rtcpPacketInformation.rtt; |
- rtcp_packet_info_.interArrivalJitter = |
- rtcpPacketInformation.interArrivalJitter; |
- rtcp_packet_info_.sliPictureId = rtcpPacketInformation.sliPictureId; |
- rtcp_packet_info_.rpsiPictureId = rtcpPacketInformation.rpsiPictureId; |
- rtcp_packet_info_.receiverEstimatedMaxBitrate = |
- rtcpPacketInformation.receiverEstimatedMaxBitrate; |
- rtcp_packet_info_.ntp_secs = rtcpPacketInformation.ntp_secs; |
- rtcp_packet_info_.ntp_frac = rtcpPacketInformation.ntp_frac; |
- rtcp_packet_info_.rtp_timestamp = rtcpPacketInformation.rtp_timestamp; |
- |
- return static_cast<int>(packet_len); |
+ int SendRTCPPacket(int /*ch*/, const void* data, size_t len) override { |
+ parser_.Parse(static_cast<const uint8_t*>(data), len); |
+ return static_cast<int>(len); |
} |
- |
- int OnReceivedPayloadData(const uint8_t* payloadData, |
- const size_t payloadSize, |
- const WebRtcRTPHeader* rtpHeader) override { |
+ int OnReceivedPayloadData(const uint8_t* payload_data, |
+ const size_t payload_size, |
+ const WebRtcRTPHeader* rtp_header) override { |
return 0; |
} |
- RTCPReceiver* rtcp_receiver_; |
- RTCPHelp::RTCPPacketInformation rtcp_packet_info_; |
+ test::RtcpPacketParser parser_; |
}; |
namespace { |
- static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; |
- static const int kMaxPacketLength = 1500; |
- static const uint32_t kMainSsrc = 0x11111111; |
+static const uint32_t kSenderSsrc = 0x11111111; |
+static const uint32_t kRemoteSsrc = 0x22222222; |
} |
class RtcpSenderTest : public ::testing::Test { |
protected: |
RtcpSenderTest() |
- : over_use_detector_options_(), |
- clock_(1335900000), |
- rtp_payload_registry_( |
- new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))), |
- remote_bitrate_observer_(), |
- remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream( |
- &remote_bitrate_observer_, |
- &clock_, |
- kRemoteBitrateEstimatorMinBitrateBps)), |
+ : clock_(1335900000), |
receive_statistics_(ReceiveStatistics::Create(&clock_)) { |
- test_transport_ = new TestTransport(); |
- |
RtpRtcp::Configuration configuration; |
configuration.id = 0; |
configuration.audio = false; |
configuration.clock = &clock_; |
- configuration.outgoing_transport = test_transport_; |
- configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get(); |
- |
- rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration); |
- rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver( |
- configuration.id, &clock_, test_transport_, NULL, |
- rtp_payload_registry_.get())); |
- rtcp_sender_ = |
- new RTCPSender(configuration.id, false, &clock_, |
- receive_statistics_.get(), NULL); |
- rtcp_sender_->SetSSRC(kMainSsrc); |
- rtcp_receiver_ = |
- new RTCPReceiver(configuration.id, &clock_, false, NULL, NULL, NULL, |
- rtp_rtcp_impl_); |
- rtcp_receiver_->SetRemoteSSRC(kMainSsrc); |
- |
- std::set<uint32_t> registered_ssrcs; |
- registered_ssrcs.insert(kMainSsrc); |
- rtcp_receiver_->SetSsrcs(kMainSsrc, registered_ssrcs); |
- test_transport_->SetRTCPReceiver(rtcp_receiver_); |
- // Initialize |
- EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); |
+ configuration.outgoing_transport = &test_transport_; |
+ |
+ rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration)); |
+ rtcp_sender_.reset(new RTCPSender(configuration.id, false, &clock_, |
+ receive_statistics_.get(), nullptr)); |
+ rtcp_sender_->SetSSRC(kSenderSsrc); |
+ rtcp_sender_->SetRemoteSSRC(kRemoteSsrc); |
+ EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(&test_transport_)); |
} |
- ~RtcpSenderTest() { |
- delete rtcp_sender_; |
- delete rtcp_receiver_; |
- delete rtp_rtcp_impl_; |
- delete test_transport_; |
+ void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) { |
+ RTPHeader header; |
+ header.ssrc = remote_ssrc; |
+ header.sequenceNumber = seq_num; |
+ header.timestamp = 12345; |
+ header.headerLength = 12; |
+ size_t kPacketLength = 100; |
+ receive_statistics_->IncomingPacket(header, kPacketLength, false); |
} |
- // Helper function: Incoming RTCP has a specific packet type. |
- bool gotPacketType(RTCPPacketType packet_type) { |
- return ((test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags) & |
- packet_type) != 0U; |
+ test::RtcpPacketParser* parser() { return &test_transport_.parser_; } |
+ |
+ RTCPSender::FeedbackState feedback_state() { |
+ return rtp_rtcp_impl_->GetFeedbackState(); |
} |
- OverUseDetectorOptions over_use_detector_options_; |
SimulatedClock clock_; |
- rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_; |
- rtc::scoped_ptr<RtpReceiver> rtp_receiver_; |
- ModuleRtpRtcpImpl* rtp_rtcp_impl_; |
- RTCPSender* rtcp_sender_; |
- RTCPReceiver* rtcp_receiver_; |
- TestTransport* test_transport_; |
- MockRemoteBitrateObserver remote_bitrate_observer_; |
- rtc::scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_; |
+ TestTransport test_transport_; |
rtc::scoped_ptr<ReceiveStatistics> receive_statistics_; |
- |
- uint8_t packet_[kMaxPacketLength]; |
+ rtc::scoped_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_; |
+ rtc::scoped_ptr<RTCPSender> rtcp_sender_; |
}; |
-TEST_F(RtcpSenderTest, RtcpOff) { |
+TEST_F(RtcpSenderTest, SetRtcpStatus) { |
+ EXPECT_EQ(kRtcpOff, rtcp_sender_->Status()); |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(kRtcpNonCompound, rtcp_sender_->Status()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SetSendingStatus) { |
+ EXPECT_FALSE(rtcp_sender_->Sending()); |
+ EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true)); |
+ EXPECT_TRUE(rtcp_sender_->Sending()); |
+} |
+ |
+TEST_F(RtcpSenderTest, NoPacketSentIfOff) { |
rtcp_sender_->SetRTCPStatus(kRtcpOff); |
+ EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr)); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendSr) { |
+ const uint32_t kPacketCount = 0x12345; |
+ const uint32_t kOctetCount = 0x23456; |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); |
-} |
- |
-TEST_F(RtcpSenderTest, TestCompound) { |
- const bool marker_bit = false; |
- const uint8_t payload_type = 100; |
- const uint16_t seq_num = 11111; |
- const uint32_t timestamp = 1234567; |
- size_t packet_length = 0; |
- CreateRtpPacket(marker_bit, payload_type, seq_num, timestamp, kMainSsrc, |
- packet_, &packet_length); |
- EXPECT_EQ(25u, packet_length); |
- |
- VideoCodec codec_inst; |
- strncpy(codec_inst.plName, "VP8", webrtc::kPayloadNameSize - 1); |
- codec_inst.codecType = webrtc::kVideoCodecVP8; |
- codec_inst.plType = payload_type; |
- EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec_inst.plName, |
- codec_inst.plType, |
- 90000, |
- 0, |
- codec_inst.maxBitrate)); |
- |
- // Make sure RTP packet has been received. |
- rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); |
- RTPHeader header; |
- EXPECT_TRUE(parser->Parse(packet_, packet_length, &header)); |
- PayloadUnion payload_specific; |
- EXPECT_TRUE(rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, |
- &payload_specific)); |
- receive_statistics_->IncomingPacket(header, packet_length, false); |
- EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, packet_, packet_length, |
- payload_specific, true)); |
- |
- rtcp_sender_->SetCNAME("Foo"); |
+ feedback_state.packets_sent = kPacketCount; |
+ feedback_state.media_bytes_sent = kOctetCount; |
+ uint32_t ntp_secs; |
+ uint32_t ntp_frac; |
+ clock_.CurrentNtp(ntp_secs, ntp_frac); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); |
+ EXPECT_EQ(1, parser()->sender_report()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->sender_report()->Ssrc()); |
+ EXPECT_EQ(ntp_secs, parser()->sender_report()->NtpSec()); |
+ EXPECT_EQ(ntp_frac, parser()->sender_report()->NtpFrac()); |
+ EXPECT_EQ(kPacketCount, parser()->sender_report()->PacketCount()); |
+ EXPECT_EQ(kOctetCount, parser()->sender_report()->OctetCount()); |
+ EXPECT_EQ(0, parser()->report_block()->num_packets()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendRr) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr)); |
+ EXPECT_EQ(1, parser()->receiver_report()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->Ssrc()); |
+ EXPECT_EQ(0, parser()->report_block()->num_packets()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) { |
+ const uint16_t kSeqNum = 11111; |
+ InsertIncomingPacket(kRemoteSsrc, kSeqNum); |
rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
- RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr)); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr)); |
+ EXPECT_EQ(1, parser()->receiver_report()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->Ssrc()); |
+ EXPECT_EQ(1, parser()->report_block()->num_packets()); |
+ EXPECT_EQ(kRemoteSsrc, parser()->report_block()->Ssrc()); |
+ EXPECT_EQ(0U, parser()->report_block()->FractionLost()); |
+ EXPECT_EQ(0U, parser()->report_block()->CumPacketLost()); |
+ EXPECT_EQ(kSeqNum, parser()->report_block()->ExtHighestSeqNum()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) { |
+ const uint16_t kSeqNum = 11111; |
+ InsertIncomingPacket(kRemoteSsrc, kSeqNum); |
+ InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1); |
+ rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr)); |
+ EXPECT_EQ(1, parser()->receiver_report()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->Ssrc()); |
+ EXPECT_EQ(2, parser()->report_block()->num_packets()); |
+ EXPECT_EQ(1, parser()->report_blocks_per_ssrc(kRemoteSsrc)); |
+ EXPECT_EQ(1, parser()->report_blocks_per_ssrc(kRemoteSsrc + 1)); |
+} |
- // Sdes packet should be received, along with report blocks. |
- ASSERT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & |
- kRtcpSdes); |
- EXPECT_GT(test_transport_->rtcp_packet_info_.report_blocks.size(), 0u); |
+TEST_F(RtcpSenderTest, SendSdes) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host")); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes)); |
+ EXPECT_EQ(1, parser()->sdes()->num_packets()); |
+ EXPECT_EQ(1, parser()->sdes_chunk()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->sdes_chunk()->Ssrc()); |
+ EXPECT_EQ("alice@host", parser()->sdes_chunk()->Cname()); |
} |
-TEST_F(RtcpSenderTest, TestCompound_NoRtpReceived) { |
- rtcp_sender_->SetCNAME("Foo"); |
+TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) { |
rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host")); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(1, parser()->receiver_report()->num_packets()); |
+ EXPECT_EQ(1, parser()->sdes()->num_packets()); |
+ EXPECT_EQ(1, parser()->sdes_chunk()->num_packets()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendBye) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye)); |
+ EXPECT_EQ(1, parser()->bye()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->bye()->Ssrc()); |
+} |
+ |
+TEST_F(RtcpSenderTest, StopSendingTriggersBye) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true)); |
+ EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false)); |
+ EXPECT_EQ(1, parser()->bye()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->bye()->Ssrc()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendApp) { |
+ const uint8_t kSubType = 30; |
+ uint32_t name = 'n' << 24; |
+ name += 'a' << 16; |
+ name += 'm' << 8; |
+ name += 'e'; |
+ const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'}; |
+ const uint16_t kDataLength = sizeof(kData) / sizeof(kData[0]); |
+ EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData, |
+ kDataLength)); |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp)); |
+ EXPECT_EQ(1, parser()->app()->num_packets()); |
+ EXPECT_EQ(kSubType, parser()->app()->SubType()); |
+ EXPECT_EQ(name, parser()->app()->Name()); |
+ EXPECT_EQ(1, parser()->app_item()->num_packets()); |
+ EXPECT_EQ(kDataLength, parser()->app_item()->DataLength()); |
+ EXPECT_EQ(0, strncmp(reinterpret_cast<const char*>(kData), |
+ reinterpret_cast<const char*>(parser()->app_item()->Data()), |
+ parser()->app_item()->DataLength())); |
+} |
+ |
+TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) { |
+ const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'}; |
+ const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]); |
+ EXPECT_EQ(-1, rtcp_sender_->SetApplicationSpecificData( |
+ 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4. |
+} |
+ |
+TEST_F(RtcpSenderTest, SendFirNonRepeat) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir)); |
+ EXPECT_EQ(1, parser()->fir()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->fir()->Ssrc()); |
+ EXPECT_EQ(1, parser()->fir_item()->num_packets()); |
+ EXPECT_EQ(kRemoteSsrc, parser()->fir_item()->Ssrc()); |
+ uint8_t seq = parser()->fir_item()->SeqNum(); |
+ // Sends non-repeat FIR as default. |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir)); |
+ EXPECT_EQ(2, parser()->fir()->num_packets()); |
+ EXPECT_EQ(2, parser()->fir_item()->num_packets()); |
+ EXPECT_EQ(seq + 1, parser()->fir_item()->SeqNum()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendFirRepeat) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir)); |
+ EXPECT_EQ(1, parser()->fir()->num_packets()); |
+ EXPECT_EQ(1, parser()->fir_item()->num_packets()); |
+ uint8_t seq = parser()->fir_item()->SeqNum(); |
+ const bool kRepeat = true; |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir, 0, nullptr, |
+ kRepeat)); |
+ EXPECT_EQ(2, parser()->fir()->num_packets()); |
+ EXPECT_EQ(2, parser()->fir_item()->num_packets()); |
+ EXPECT_EQ(seq, parser()->fir_item()->SeqNum()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendPli) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli)); |
+ EXPECT_EQ(1, parser()->pli()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->pli()->Ssrc()); |
+ EXPECT_EQ(kRemoteSsrc, parser()->pli()->MediaSsrc()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendRpsi) { |
+ const uint64_t kPictureId = 0x41; |
+ const int8_t kPayloadType = 100; |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRr)); |
+ feedback_state.send_payload_type = kPayloadType; |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRpsi, 0, nullptr, |
+ false, kPictureId)); |
+ EXPECT_EQ(kPayloadType, parser()->rpsi()->PayloadType()); |
+ EXPECT_EQ(kPictureId, parser()->rpsi()->PictureId()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendSli) { |
+ const uint16_t kFirstMb = 0; |
+ const uint16_t kNumberOfMb = 0x1FFF; |
+ const uint8_t kPictureId = 60; |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSli, 0, nullptr, |
+ false, kPictureId)); |
+ EXPECT_EQ(1, parser()->sli()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->sli()->Ssrc()); |
+ EXPECT_EQ(kRemoteSsrc, parser()->sli()->MediaSsrc()); |
+ EXPECT_EQ(1, parser()->sli_item()->num_packets()); |
+ EXPECT_EQ(kFirstMb, parser()->sli_item()->FirstMb()); |
+ EXPECT_EQ(kNumberOfMb, parser()->sli_item()->NumberOfMb()); |
+ EXPECT_EQ(kPictureId, parser()->sli_item()->PictureId()); |
+} |
- // Sdes should be received, but no report blocks. |
- ASSERT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & |
- kRtcpSdes); |
- EXPECT_EQ(0u, test_transport_->rtcp_packet_info_.report_blocks.size()); |
+TEST_F(RtcpSenderTest, SendNack) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ const uint16_t kList[] = {0, 1, 16}; |
+ const int32_t kListLength = sizeof(kList) / sizeof(kList[0]); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength, |
+ kList)); |
+ EXPECT_EQ(1, parser()->nack()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->nack()->Ssrc()); |
+ EXPECT_EQ(kRemoteSsrc, parser()->nack()->MediaSsrc()); |
+ EXPECT_EQ(1, parser()->nack_item()->num_packets()); |
+ EXPECT_THAT(parser()->nack_item()->last_nack_list(), ElementsAre(0, 1, 16)); |
} |
-TEST_F(RtcpSenderTest, TestXrReceiverReferenceTime) { |
+TEST_F(RtcpSenderTest, SendRemb) { |
+ const int kBitrate = 261011; |
+ std::vector<uint32_t> ssrcs; |
+ ssrcs.push_back(kRemoteSsrc); |
+ ssrcs.push_back(kRemoteSsrc + 1); |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ rtcp_sender_->SetREMBData(kBitrate, ssrcs); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb)); |
+ EXPECT_EQ(1, parser()->psfb_app()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->psfb_app()->Ssrc()); |
+ EXPECT_EQ(1, parser()->remb_item()->num_packets()); |
+ EXPECT_EQ(kBitrate, parser()->remb_item()->last_bitrate_bps()); |
+ EXPECT_THAT(parser()->remb_item()->last_ssrc_list(), |
+ ElementsAre(kRemoteSsrc, kRemoteSsrc + 1)); |
+} |
+ |
+TEST_F(RtcpSenderTest, RembIncludedInCompoundPacketIfEnabled) { |
+ const int kBitrate = 261011; |
+ std::vector<uint32_t> ssrcs; |
+ ssrcs.push_back(kRemoteSsrc); |
rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
- RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); |
- rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); |
- EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); |
+ rtcp_sender_->SetREMBStatus(true); |
+ EXPECT_TRUE(rtcp_sender_->REMB()); |
+ rtcp_sender_->SetREMBData(kBitrate, ssrcs); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(1, parser()->psfb_app()->num_packets()); |
+ EXPECT_EQ(1, parser()->remb_item()->num_packets()); |
+ // REMB should be included in each compound packet. |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(2, parser()->psfb_app()->num_packets()); |
+ EXPECT_EQ(2, parser()->remb_item()->num_packets()); |
+} |
- EXPECT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & |
- kRtcpXrReceiverReferenceTime); |
+TEST_F(RtcpSenderTest, RembNotIncludedInCompoundPacketIfNotEnabled) { |
+ const int kBitrate = 261011; |
+ std::vector<uint32_t> ssrcs; |
+ ssrcs.push_back(kRemoteSsrc); |
+ rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ rtcp_sender_->SetREMBData(kBitrate, ssrcs); |
+ EXPECT_FALSE(rtcp_sender_->REMB()); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(0, parser()->psfb_app()->num_packets()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendXrWithVoipMetric) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ RTCPVoIPMetric metric; |
+ metric.lossRate = 1; |
+ metric.discardRate = 2; |
+ metric.burstDensity = 3; |
+ metric.gapDensity = 4; |
+ metric.burstDuration = 0x1111; |
+ metric.gapDuration = 0x2222; |
+ metric.roundTripDelay = 0x3333; |
+ metric.endSystemDelay = 0x4444; |
+ metric.signalLevel = 5; |
+ metric.noiseLevel = 6; |
+ metric.RERL = 7; |
+ metric.Gmin = 8; |
+ metric.Rfactor = 9; |
+ metric.extRfactor = 10; |
+ metric.MOSLQ = 11; |
+ metric.MOSCQ = 12; |
+ metric.RXconfig = 13; |
+ metric.JBnominal = 0x5555; |
+ metric.JBmax = 0x6666; |
+ metric.JBabsMax = 0x7777; |
+ EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric)); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpXrVoipMetric)); |
+ EXPECT_EQ(1, parser()->xr_header()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->xr_header()->Ssrc()); |
+ EXPECT_EQ(1, parser()->voip_metric()->num_packets()); |
+ EXPECT_EQ(kRemoteSsrc, parser()->voip_metric()->Ssrc()); |
+ EXPECT_EQ(metric.lossRate, parser()->voip_metric()->LossRate()); |
+ EXPECT_EQ(metric.discardRate, parser()->voip_metric()->DiscardRate()); |
+ EXPECT_EQ(metric.burstDensity, parser()->voip_metric()->BurstDensity()); |
+ EXPECT_EQ(metric.gapDensity, parser()->voip_metric()->GapDensity()); |
+ EXPECT_EQ(metric.burstDuration, parser()->voip_metric()->BurstDuration()); |
+ EXPECT_EQ(metric.gapDuration, parser()->voip_metric()->GapDuration()); |
+ EXPECT_EQ(metric.roundTripDelay, parser()->voip_metric()->RoundTripDelay()); |
+ EXPECT_EQ(metric.endSystemDelay, parser()->voip_metric()->EndSystemDelay()); |
+ EXPECT_EQ(metric.signalLevel, parser()->voip_metric()->SignalLevel()); |
+ EXPECT_EQ(metric.noiseLevel, parser()->voip_metric()->NoiseLevel()); |
+ EXPECT_EQ(metric.RERL, parser()->voip_metric()->Rerl()); |
+ EXPECT_EQ(metric.Gmin, parser()->voip_metric()->Gmin()); |
+ EXPECT_EQ(metric.Rfactor, parser()->voip_metric()->Rfactor()); |
+ EXPECT_EQ(metric.extRfactor, parser()->voip_metric()->ExtRfactor()); |
+ EXPECT_EQ(metric.MOSLQ, parser()->voip_metric()->MosLq()); |
+ EXPECT_EQ(metric.MOSCQ, parser()->voip_metric()->MosCq()); |
+ EXPECT_EQ(metric.RXconfig, parser()->voip_metric()->RxConfig()); |
+ EXPECT_EQ(metric.JBnominal, parser()->voip_metric()->JbNominal()); |
+ EXPECT_EQ(metric.JBmax, parser()->voip_metric()->JbMax()); |
+ EXPECT_EQ(metric.JBabsMax, parser()->voip_metric()->JbAbsMax()); |
} |
-TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfSending) { |
+TEST_F(RtcpSenderTest, SendXrWithDlrr) { |
rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, true)); |
- rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); |
+ feedback_state.has_last_xr_rr = true; |
+ RtcpReceiveTimeInfo last_xr_rr; |
+ last_xr_rr.sourceSSRC = 0x11111111; |
+ last_xr_rr.lastRR = 0x22222222; |
+ last_xr_rr.delaySinceLastRR = 0x33333333; |
+ feedback_state.last_xr_rr = last_xr_rr; |
EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); |
+ EXPECT_EQ(1, parser()->xr_header()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->xr_header()->Ssrc()); |
+ EXPECT_EQ(1, parser()->dlrr()->num_packets()); |
+ EXPECT_EQ(1, parser()->dlrr_items()->num_packets()); |
+ EXPECT_EQ(last_xr_rr.sourceSSRC, parser()->dlrr_items()->Ssrc(0)); |
+ EXPECT_EQ(last_xr_rr.lastRR, parser()->dlrr_items()->LastRr(0)); |
+ EXPECT_EQ(last_xr_rr.delaySinceLastRR, |
+ parser()->dlrr_items()->DelayLastRr(0)); |
+} |
- EXPECT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & |
- kRtcpXrReceiverReferenceTime); |
+TEST_F(RtcpSenderTest, SendXrWithRrtr) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false)); |
+ rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); |
+ uint32_t ntp_secs; |
+ uint32_t ntp_frac; |
+ clock_.CurrentNtp(ntp_secs, ntp_frac); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(1, parser()->xr_header()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->xr_header()->Ssrc()); |
+ EXPECT_EQ(0, parser()->dlrr()->num_packets()); |
+ EXPECT_EQ(1, parser()->rrtr()->num_packets()); |
+ EXPECT_EQ(ntp_secs, parser()->rrtr()->NtpSec()); |
+ EXPECT_EQ(ntp_frac, parser()->rrtr()->NtpFrac()); |
} |
-TEST_F(RtcpSenderTest, TestNoXrReceiverReferenceTimeIfNotEnabled) { |
+TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) { |
rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
- RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); |
- rtcp_sender_->SendRtcpXrReceiverReferenceTime(false); |
- EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); |
+ EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true)); |
+ rtcp_sender_->SendRtcpXrReceiverReferenceTime(true); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(0, parser()->xr_header()->num_packets()); |
+ EXPECT_EQ(0, parser()->rrtr()->num_packets()); |
+} |
- EXPECT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & |
- kRtcpXrReceiverReferenceTime); |
+TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false)); |
+ rtcp_sender_->SendRtcpXrReceiverReferenceTime(false); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(0, parser()->xr_header()->num_packets()); |
+ EXPECT_EQ(0, parser()->rrtr()->num_packets()); |
} |
-TEST_F(RtcpSenderTest, TestSendTimeOfXrRrReport) { |
+TEST_F(RtcpSenderTest, TestSendTimeOfXrRrtr) { |
rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false)); |
@@ -459,20 +640,82 @@ TEST_F(RtcpSenderTest, TestSendTimeOfXrRrReport) { |
// Send XR RR packets. |
for (int i = 0; i <= RTCP_NUMBER_OF_SR; ++i) { |
EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport)); |
- EXPECT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags & |
- kRtcpXrReceiverReferenceTime); |
- |
+ EXPECT_EQ(i + 1, test_transport_.parser_.rrtr()->num_packets()); |
clock_.CurrentNtp(ntp_sec, ntp_frac); |
uint32_t mid_ntp = RTCPUtility::MidNtp(ntp_sec, ntp_frac); |
EXPECT_TRUE(rtcp_sender_->SendTimeOfXrRrReport(mid_ntp, &time_ms)); |
EXPECT_EQ(clock_.CurrentNtpInMilliseconds(), time_ms); |
clock_.AdvanceTimeMilliseconds(1000); |
} |
- |
// The first report should no longer be stored. |
EXPECT_FALSE(rtcp_sender_->SendTimeOfXrRrReport(initial_mid_ntp, &time_ms)); |
} |
+TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) { |
+ RtcpPacketTypeCounterObserverImpl observer; |
+ rtcp_sender_.reset( |
+ new RTCPSender(0, false, &clock_, receive_statistics_.get(), &observer)); |
+ rtcp_sender_->SetRemoteSSRC(kRemoteSsrc); |
+ EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(&test_transport_)); |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli)); |
+ EXPECT_EQ(1, parser()->pli()->num_packets()); |
+ EXPECT_EQ(kRemoteSsrc, observer.ssrc_); |
+ EXPECT_EQ(1U, observer.counter_.pli_packets); |
+ EXPECT_EQ(clock_.TimeInMilliseconds(), |
+ observer.counter_.first_packet_time_ms); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendTmmbr) { |
+ const unsigned int kBitrateBps = 312000; |
+ rtcp_sender_->SetRTCPStatus(kRtcpNonCompound); |
+ rtcp_sender_->SetTargetBitrate(kBitrateBps); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr)); |
+ EXPECT_EQ(1, parser()->tmmbr()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->Ssrc()); |
+ EXPECT_EQ(1, parser()->tmmbr_item()->num_packets()); |
+ EXPECT_EQ(kBitrateBps / 1000, parser()->tmmbr_item()->BitrateKbps()); |
+ // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero. |
+} |
+ |
+TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) { |
+ const unsigned int kBitrateBps = 312000; |
+ rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ EXPECT_FALSE(rtcp_sender_->TMMBR()); |
+ rtcp_sender_->SetTMMBRStatus(true); |
+ EXPECT_TRUE(rtcp_sender_->TMMBR()); |
+ rtcp_sender_->SetTargetBitrate(kBitrateBps); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(1, parser()->tmmbr()->num_packets()); |
+ EXPECT_EQ(1, parser()->tmmbr_item()->num_packets()); |
+ // TMMBR should be included in each compound packet. |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport)); |
+ EXPECT_EQ(2, parser()->tmmbr()->num_packets()); |
+ EXPECT_EQ(2, parser()->tmmbr_item()->num_packets()); |
+ |
+ rtcp_sender_->SetTMMBRStatus(false); |
+ EXPECT_FALSE(rtcp_sender_->TMMBR()); |
+} |
+ |
+TEST_F(RtcpSenderTest, SendTmmbn) { |
+ rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ TMMBRSet bounding_set; |
+ bounding_set.VerifyAndAllocateSet(1); |
+ const uint32_t kBitrateKbps = 32768; |
+ const uint32_t kPacketOh = 40; |
+ const uint32_t kSourceSsrc = 12345; |
+ bounding_set.AddEntry(kBitrateKbps, kPacketOh, kSourceSsrc); |
+ EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 0)); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr)); |
+ EXPECT_EQ(1, parser()->sender_report()->num_packets()); |
+ EXPECT_EQ(1, parser()->tmmbn()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->Ssrc()); |
+ EXPECT_EQ(1, parser()->tmmbn_items()->num_packets()); |
+ EXPECT_EQ(kBitrateKbps, parser()->tmmbn_items()->BitrateKbps(0)); |
+ EXPECT_EQ(kPacketOh, parser()->tmmbn_items()->Overhead(0)); |
+ EXPECT_EQ(kSourceSsrc, parser()->tmmbn_items()->Ssrc(0)); |
+} |
+ |
// This test is written to verify actual behaviour. It does not seem |
// to make much sense to send an empty TMMBN, since there is no place |
// to put an actual limit here. It's just information that no limit |
@@ -483,42 +726,25 @@ TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) { |
rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
TMMBRSet bounding_set; |
EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3)); |
- ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); |
- RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); |
- // We now expect the packet to show up in the rtcp_packet_info_ of |
- // test_transport_. |
- ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); |
- EXPECT_TRUE(gotPacketType(kRtcpTmmbn)); |
- TMMBRSet* incoming_set = NULL; |
- bool owner = false; |
- // The BoundingSet function returns the number of members of the |
- // bounding set, and touches the incoming set only if there's > 1. |
- EXPECT_EQ(0, test_transport_->rtcp_receiver_->BoundingSet(owner, |
- incoming_set)); |
-} |
- |
-TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndValid) { |
- rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
- TMMBRSet bounding_set; |
- bounding_set.VerifyAndAllocateSet(1); |
- const uint32_t kSourceSsrc = 12345; |
- bounding_set.AddEntry(32768, 0, kSourceSsrc); |
+ EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr)); |
+ EXPECT_EQ(1, parser()->sender_report()->num_packets()); |
+ EXPECT_EQ(1, parser()->tmmbn()->num_packets()); |
+ EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->Ssrc()); |
+ EXPECT_EQ(0, parser()->tmmbn_items()->num_packets()); |
+} |
- EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3)); |
- ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); |
- RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState(); |
- EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr)); |
- // We now expect the packet to show up in the rtcp_packet_info_ of |
- // test_transport_. |
- ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags); |
- EXPECT_TRUE(gotPacketType(kRtcpTmmbn)); |
- TMMBRSet incoming_set; |
- bool owner = false; |
- // We expect 1 member of the incoming set. |
- EXPECT_EQ(1, test_transport_->rtcp_receiver_->BoundingSet(owner, |
- &incoming_set)); |
- EXPECT_EQ(kSourceSsrc, incoming_set.Ssrc(0)); |
+TEST_F(RtcpSenderTest, SendCompoundPliRemb) { |
+ const int kBitrate = 261011; |
+ std::vector<uint32_t> ssrcs; |
+ ssrcs.push_back(kRemoteSsrc); |
+ rtcp_sender_->SetRTCPStatus(kRtcpCompound); |
+ rtcp_sender_->SetREMBData(kBitrate, ssrcs); |
+ std::set<RTCPPacketType> packet_types; |
+ packet_types.insert(kRtcpRemb); |
+ packet_types.insert(kRtcpPli); |
+ EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types)); |
+ EXPECT_EQ(1, parser()->remb_item()->num_packets()); |
+ EXPECT_EQ(1, parser()->pli()->num_packets()); |
} |
} // namespace webrtc |