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:

committed by
Commit Bot

parent
e97de91d39
commit
7ca9ae2e26
@ -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) {
|
||||
|
Reference in New Issue
Block a user