Add rtcp observers for media receiver to RtcpTransceiverImpl

Bug: webrtc:8239
Change-Id: I7b6735f2efb87e303d1b8076c965a751db4af250
Reviewed-on: https://webrtc-review.googlesource.com/31980
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21240}
This commit is contained in:
Danil Chapovalov
2017-12-13 12:26:17 +01:00
committed by Commit Bot
parent e97de91d39
commit 7ca9ae2e26
5 changed files with 322 additions and 18 deletions

View File

@ -14,6 +14,9 @@
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include "modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h"
#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
#include "modules/rtp_rtcp/source/time_util.h"
#include "rtc_base/event.h"
#include "rtc_base/fakeclock.h"
@ -31,6 +34,8 @@ using ::testing::ElementsAre;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SizeIs;
using ::testing::StrictMock;
using ::webrtc::BitrateAllocation;
using ::webrtc::CompactNtp;
using ::webrtc::CompactNtpRttToMs;
using ::webrtc::MockRtcpRttStats;
@ -40,6 +45,8 @@ using ::webrtc::RtcpTransceiverConfig;
using ::webrtc::RtcpTransceiverImpl;
using ::webrtc::SaturatedUsToCompactNtp;
using ::webrtc::TimeMicrosToNtp;
using ::webrtc::rtcp::Bye;
using ::webrtc::rtcp::CompoundPacket;
using ::webrtc::rtcp::ReportBlock;
using ::webrtc::rtcp::SenderReport;
using ::webrtc::test::RtcpPacketParser;
@ -49,6 +56,13 @@ class MockReceiveStatisticsProvider : public webrtc::ReceiveStatisticsProvider {
MOCK_METHOD1(RtcpReportBlocks, std::vector<ReportBlock>(size_t));
};
class MockMediaReceiverRtcpObserver : public webrtc::MediaReceiverRtcpObserver {
public:
MOCK_METHOD3(OnSenderReport, void(uint32_t, NtpTime, uint32_t));
MOCK_METHOD1(OnBye, void(uint32_t));
MOCK_METHOD2(OnBitrateAllocation, void(uint32_t, const BitrateAllocation&));
};
// Since some tests will need to wait for this period, make it small to avoid
// slowing tests too much. As long as there are test bots with high scheduler
// granularity, small period should be ok.
@ -108,6 +122,17 @@ class RtcpParserTransport : public webrtc::Transport {
int num_packets_ = 0;
};
RtcpTransceiverConfig DefaultTestConfig() {
// RtcpTransceiverConfig default constructor sets default values for prod.
// Test doesn't need to support all key features: Default test config returns
// valid config with all features turned off.
static MockTransport null_transport;
RtcpTransceiverConfig config;
config.outgoing_transport = &null_transport;
config.schedule_periodic_compound_packets = false;
return config;
}
TEST(RtcpTransceiverImplTest, DelaysSendingFirstCompondPacket) {
rtc::TaskQueue queue("rtcp");
FakeRtcpTransport transport;
@ -361,9 +386,175 @@ TEST(RtcpTransceiverImplTest, ReceiverReportUsesReceiveStatistics) {
kMediaSsrc);
}
// TODO(danilchap): Write test ReceivePacket handles several rtcp_packets
// stacked together when callbacks will be implemented that can be used for
// cleaner expectations.
TEST(RtcpTransceiverImplTest, MultipleObserversOnSameSsrc) {
const uint32_t kRemoteSsrc = 12345;
StrictMock<MockMediaReceiverRtcpObserver> observer1;
StrictMock<MockMediaReceiverRtcpObserver> observer2;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc, &observer1);
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc, &observer2);
const NtpTime kRemoteNtp(0x9876543211);
const uint32_t kRemoteRtp = 0x444555;
SenderReport sr;
sr.SetSenderSsrc(kRemoteSsrc);
sr.SetNtp(kRemoteNtp);
sr.SetRtpTimestamp(kRemoteRtp);
auto raw_packet = sr.Build();
EXPECT_CALL(observer1, OnSenderReport(kRemoteSsrc, kRemoteNtp, kRemoteRtp));
EXPECT_CALL(observer2, OnSenderReport(kRemoteSsrc, kRemoteNtp, kRemoteRtp));
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest, DoesntCallsObserverAfterRemoved) {
const uint32_t kRemoteSsrc = 12345;
StrictMock<MockMediaReceiverRtcpObserver> observer1;
StrictMock<MockMediaReceiverRtcpObserver> observer2;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc, &observer1);
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc, &observer2);
SenderReport sr;
sr.SetSenderSsrc(kRemoteSsrc);
auto raw_packet = sr.Build();
rtcp_transceiver.RemoveMediaReceiverObserver(kRemoteSsrc, &observer1);
EXPECT_CALL(observer1, OnSenderReport(_, _, _)).Times(0);
EXPECT_CALL(observer2, OnSenderReport(_, _, _));
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest, CallsObserverOnSenderReportBySenderSsrc) {
const uint32_t kRemoteSsrc1 = 12345;
const uint32_t kRemoteSsrc2 = 22345;
StrictMock<MockMediaReceiverRtcpObserver> observer1;
StrictMock<MockMediaReceiverRtcpObserver> observer2;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc1, &observer1);
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc2, &observer2);
const NtpTime kRemoteNtp(0x9876543211);
const uint32_t kRemoteRtp = 0x444555;
SenderReport sr;
sr.SetSenderSsrc(kRemoteSsrc1);
sr.SetNtp(kRemoteNtp);
sr.SetRtpTimestamp(kRemoteRtp);
auto raw_packet = sr.Build();
EXPECT_CALL(observer1, OnSenderReport(kRemoteSsrc1, kRemoteNtp, kRemoteRtp));
EXPECT_CALL(observer2, OnSenderReport(_, _, _)).Times(0);
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest, CallsObserverOnByeBySenderSsrc) {
const uint32_t kRemoteSsrc1 = 12345;
const uint32_t kRemoteSsrc2 = 22345;
StrictMock<MockMediaReceiverRtcpObserver> observer1;
StrictMock<MockMediaReceiverRtcpObserver> observer2;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc1, &observer1);
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc2, &observer2);
Bye bye;
bye.SetSenderSsrc(kRemoteSsrc1);
auto raw_packet = bye.Build();
EXPECT_CALL(observer1, OnBye(kRemoteSsrc1));
EXPECT_CALL(observer2, OnBye(_)).Times(0);
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest, CallsObserverOnTargetBitrateBySenderSsrc) {
const uint32_t kRemoteSsrc1 = 12345;
const uint32_t kRemoteSsrc2 = 22345;
StrictMock<MockMediaReceiverRtcpObserver> observer1;
StrictMock<MockMediaReceiverRtcpObserver> observer2;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc1, &observer1);
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc2, &observer2);
webrtc::rtcp::TargetBitrate target_bitrate;
target_bitrate.AddTargetBitrate(0, 0, /*target_bitrate_kbps=*/10);
target_bitrate.AddTargetBitrate(0, 1, /*target_bitrate_kbps=*/20);
target_bitrate.AddTargetBitrate(1, 0, /*target_bitrate_kbps=*/40);
target_bitrate.AddTargetBitrate(1, 1, /*target_bitrate_kbps=*/80);
webrtc::rtcp::ExtendedReports xr;
xr.SetSenderSsrc(kRemoteSsrc1);
xr.SetTargetBitrate(target_bitrate);
auto raw_packet = xr.Build();
BitrateAllocation bitrate_allocation;
bitrate_allocation.SetBitrate(0, 0, /*bitrate_bps=*/10000);
bitrate_allocation.SetBitrate(0, 1, /*bitrate_bps=*/20000);
bitrate_allocation.SetBitrate(1, 0, /*bitrate_bps=*/40000);
bitrate_allocation.SetBitrate(1, 1, /*bitrate_bps=*/80000);
EXPECT_CALL(observer1, OnBitrateAllocation(kRemoteSsrc1, bitrate_allocation));
EXPECT_CALL(observer2, OnBitrateAllocation(_, _)).Times(0);
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest, SkipsIncorrectTargetBitrateEntries) {
const uint32_t kRemoteSsrc = 12345;
MockMediaReceiverRtcpObserver observer;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc, &observer);
webrtc::rtcp::TargetBitrate target_bitrate;
target_bitrate.AddTargetBitrate(0, 0, /*target_bitrate_kbps=*/10);
target_bitrate.AddTargetBitrate(0, webrtc::kMaxTemporalStreams, 20);
target_bitrate.AddTargetBitrate(webrtc::kMaxSpatialLayers, 0, 40);
webrtc::rtcp::ExtendedReports xr;
xr.SetTargetBitrate(target_bitrate);
xr.SetSenderSsrc(kRemoteSsrc);
auto raw_packet = xr.Build();
BitrateAllocation expected_allocation;
expected_allocation.SetBitrate(0, 0, /*bitrate_bps=*/10000);
EXPECT_CALL(observer, OnBitrateAllocation(kRemoteSsrc, expected_allocation));
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest, CallsObserverOnByeBehindSenderReport) {
const uint32_t kRemoteSsrc = 12345;
MockMediaReceiverRtcpObserver observer;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc, &observer);
CompoundPacket compound;
SenderReport sr;
sr.SetSenderSsrc(kRemoteSsrc);
compound.Append(&sr);
Bye bye;
bye.SetSenderSsrc(kRemoteSsrc);
compound.Append(&bye);
auto raw_packet = compound.Build();
EXPECT_CALL(observer, OnBye(kRemoteSsrc));
EXPECT_CALL(observer, OnSenderReport(kRemoteSsrc, _, _));
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest, CallsObserverOnByeBehindUnknownRtcpPacket) {
const uint32_t kRemoteSsrc = 12345;
MockMediaReceiverRtcpObserver observer;
RtcpTransceiverImpl rtcp_transceiver(DefaultTestConfig());
rtcp_transceiver.AddMediaReceiverObserver(kRemoteSsrc, &observer);
CompoundPacket compound;
// Use Application-Defined rtcp packet as unknown.
webrtc::rtcp::App app;
compound.Append(&app);
Bye bye;
bye.SetSenderSsrc(kRemoteSsrc);
compound.Append(&bye);
auto raw_packet = compound.Build();
EXPECT_CALL(observer, OnBye(kRemoteSsrc));
rtcp_transceiver.ReceivePacket(raw_packet, /*now_us=*/0);
}
TEST(RtcpTransceiverImplTest,
WhenSendsReceiverReportSetsLastSenderReportTimestampPerRemoteSsrc) {