xref: /aosp_15_r20/external/webrtc/modules/pacing/packet_router_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "modules/pacing/packet_router.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <cstddef>
14*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <utility>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
19*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
20*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
21*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_clock.h"
24*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
25*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker // TODO(eladalon): Restructure and/or replace the existing monolithic tests
30*d9f75844SAndroid Build Coastguard Worker // (only some of the test are monolithic) according to the new
31*d9f75844SAndroid Build Coastguard Worker // guidelines - small tests for one thing at a time.
32*d9f75844SAndroid Build Coastguard Worker // (I'm not removing any tests during CL, so as to demonstrate no regressions.)
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker namespace {
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
37*d9f75844SAndroid Build Coastguard Worker using ::testing::AnyNumber;
38*d9f75844SAndroid Build Coastguard Worker using ::testing::AtLeast;
39*d9f75844SAndroid Build Coastguard Worker using ::testing::ElementsAreArray;
40*d9f75844SAndroid Build Coastguard Worker using ::testing::Field;
41*d9f75844SAndroid Build Coastguard Worker using ::testing::Gt;
42*d9f75844SAndroid Build Coastguard Worker using ::testing::Le;
43*d9f75844SAndroid Build Coastguard Worker using ::testing::NiceMock;
44*d9f75844SAndroid Build Coastguard Worker using ::testing::Property;
45*d9f75844SAndroid Build Coastguard Worker using ::testing::Return;
46*d9f75844SAndroid Build Coastguard Worker using ::testing::SaveArg;
47*d9f75844SAndroid Build Coastguard Worker 
48*d9f75844SAndroid Build Coastguard Worker constexpr int kProbeMinProbes = 5;
49*d9f75844SAndroid Build Coastguard Worker constexpr int kProbeMinBytes = 1000;
50*d9f75844SAndroid Build Coastguard Worker 
51*d9f75844SAndroid Build Coastguard Worker }  // namespace
52*d9f75844SAndroid Build Coastguard Worker 
53*d9f75844SAndroid Build Coastguard Worker class PacketRouterTest : public ::testing::Test {
54*d9f75844SAndroid Build Coastguard Worker  public:
PacketRouterTest()55*d9f75844SAndroid Build Coastguard Worker   PacketRouterTest() {
56*d9f75844SAndroid Build Coastguard Worker     extension_manager.Register<TransportSequenceNumber>(/*id=*/1);
57*d9f75844SAndroid Build Coastguard Worker   }
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker  protected:
BuildRtpPacket(uint32_t ssrc)60*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<RtpPacketToSend> BuildRtpPacket(uint32_t ssrc) {
61*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<RtpPacketToSend> packet =
62*d9f75844SAndroid Build Coastguard Worker         std::make_unique<RtpPacketToSend>(&extension_manager);
63*d9f75844SAndroid Build Coastguard Worker     packet->SetSsrc(ssrc);
64*d9f75844SAndroid Build Coastguard Worker     return packet;
65*d9f75844SAndroid Build Coastguard Worker   }
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router_;
68*d9f75844SAndroid Build Coastguard Worker   RtpHeaderExtensionMap extension_manager;
69*d9f75844SAndroid Build Coastguard Worker };
70*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,Sanity_NoModuleRegistered_GeneratePadding)71*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_GeneratePadding) {
72*d9f75844SAndroid Build Coastguard Worker   constexpr DataSize bytes = DataSize::Bytes(300);
73*d9f75844SAndroid Build Coastguard Worker   const PacedPacketInfo paced_info(1, kProbeMinProbes, kProbeMinBytes);
74*d9f75844SAndroid Build Coastguard Worker 
75*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(packet_router_.GeneratePadding(bytes).empty());
76*d9f75844SAndroid Build Coastguard Worker }
77*d9f75844SAndroid Build Coastguard Worker 
78*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,Sanity_NoModuleRegistered_SendRemb)79*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_SendRemb) {
80*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1, 2, 3};
81*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_bps = 10000;
82*d9f75844SAndroid Build Coastguard Worker   // Expect not to crash
83*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendRemb(bitrate_bps, ssrcs);
84*d9f75844SAndroid Build Coastguard Worker }
85*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,Sanity_NoModuleRegistered_SendTransportFeedback)86*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_SendTransportFeedback) {
87*d9f75844SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback;
88*d9f75844SAndroid Build Coastguard Worker   feedback.push_back(std::make_unique<rtcp::TransportFeedback>());
89*d9f75844SAndroid Build Coastguard Worker   // Expect not to crash
90*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendCombinedRtcpPacket(std::move(feedback));
91*d9f75844SAndroid Build Coastguard Worker }
92*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,GeneratePaddingPrioritizesRtx)93*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, GeneratePaddingPrioritizesRtx) {
94*d9f75844SAndroid Build Coastguard Worker   // Two RTP modules. The first (prioritized due to rtx) isn't sending media so
95*d9f75844SAndroid Build Coastguard Worker   // should not be called.
96*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc1 = 1234;
97*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc2 = 4567;
98*d9f75844SAndroid Build Coastguard Worker 
99*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
100*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, RtxSendStatus()).WillByDefault(Return(kRtxRedundantPayloads));
101*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, SSRC()).WillByDefault(Return(kSsrc1));
102*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, SupportsPadding).WillByDefault(Return(false));
103*d9f75844SAndroid Build Coastguard Worker 
104*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_2;
105*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_2, RtxSendStatus()).WillByDefault(Return(kRtxOff));
106*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_2, SSRC()).WillByDefault(Return(kSsrc2));
107*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_2, SupportsPadding).WillByDefault(Return(true));
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_1, false);
110*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_2, false);
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   const size_t kPaddingSize = 123;
113*d9f75844SAndroid Build Coastguard Worker   const size_t kExpectedPaddingPackets = 1;
114*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, GeneratePadding(_)).Times(0);
115*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, GeneratePadding(kPaddingSize))
116*d9f75844SAndroid Build Coastguard Worker       .WillOnce([&](size_t padding_size) {
117*d9f75844SAndroid Build Coastguard Worker         return std::vector<std::unique_ptr<RtpPacketToSend>>(
118*d9f75844SAndroid Build Coastguard Worker             kExpectedPaddingPackets);
119*d9f75844SAndroid Build Coastguard Worker       });
120*d9f75844SAndroid Build Coastguard Worker   auto generated_padding =
121*d9f75844SAndroid Build Coastguard Worker       packet_router_.GeneratePadding(DataSize::Bytes(kPaddingSize));
122*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(generated_padding.size(), kExpectedPaddingPackets);
123*d9f75844SAndroid Build Coastguard Worker 
124*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_1);
125*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_2);
126*d9f75844SAndroid Build Coastguard Worker }
127*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,GeneratePaddingPrioritizesVideo)128*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, GeneratePaddingPrioritizesVideo) {
129*d9f75844SAndroid Build Coastguard Worker   // Two RTP modules. Neither support RTX, both support padding,
130*d9f75844SAndroid Build Coastguard Worker   // but the first one is for audio and second for video.
131*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc1 = 1234;
132*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc2 = 4567;
133*d9f75844SAndroid Build Coastguard Worker   const size_t kPaddingSize = 123;
134*d9f75844SAndroid Build Coastguard Worker   const size_t kExpectedPaddingPackets = 1;
135*d9f75844SAndroid Build Coastguard Worker 
136*d9f75844SAndroid Build Coastguard Worker   auto generate_padding = [&](size_t padding_size) {
137*d9f75844SAndroid Build Coastguard Worker     return std::vector<std::unique_ptr<RtpPacketToSend>>(
138*d9f75844SAndroid Build Coastguard Worker         kExpectedPaddingPackets);
139*d9f75844SAndroid Build Coastguard Worker   };
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> audio_module;
142*d9f75844SAndroid Build Coastguard Worker   ON_CALL(audio_module, RtxSendStatus()).WillByDefault(Return(kRtxOff));
143*d9f75844SAndroid Build Coastguard Worker   ON_CALL(audio_module, SSRC()).WillByDefault(Return(kSsrc1));
144*d9f75844SAndroid Build Coastguard Worker   ON_CALL(audio_module, SupportsPadding).WillByDefault(Return(true));
145*d9f75844SAndroid Build Coastguard Worker   ON_CALL(audio_module, IsAudioConfigured).WillByDefault(Return(true));
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> video_module;
148*d9f75844SAndroid Build Coastguard Worker   ON_CALL(video_module, RtxSendStatus()).WillByDefault(Return(kRtxOff));
149*d9f75844SAndroid Build Coastguard Worker   ON_CALL(video_module, SSRC()).WillByDefault(Return(kSsrc2));
150*d9f75844SAndroid Build Coastguard Worker   ON_CALL(video_module, SupportsPadding).WillByDefault(Return(true));
151*d9f75844SAndroid Build Coastguard Worker   ON_CALL(video_module, IsAudioConfigured).WillByDefault(Return(false));
152*d9f75844SAndroid Build Coastguard Worker 
153*d9f75844SAndroid Build Coastguard Worker   // First add only the audio module. Since this is the only choice we have,
154*d9f75844SAndroid Build Coastguard Worker   // padding should be sent on the audio ssrc.
155*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&audio_module, false);
156*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(audio_module, GeneratePadding(kPaddingSize))
157*d9f75844SAndroid Build Coastguard Worker       .WillOnce(generate_padding);
158*d9f75844SAndroid Build Coastguard Worker   packet_router_.GeneratePadding(DataSize::Bytes(kPaddingSize));
159*d9f75844SAndroid Build Coastguard Worker 
160*d9f75844SAndroid Build Coastguard Worker   // Add the video module, this should now be prioritized since we cannot
161*d9f75844SAndroid Build Coastguard Worker   // guarantee that audio packets will be included in the BWE.
162*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&video_module, false);
163*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(audio_module, GeneratePadding).Times(0);
164*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(video_module, GeneratePadding(kPaddingSize))
165*d9f75844SAndroid Build Coastguard Worker       .WillOnce(generate_padding);
166*d9f75844SAndroid Build Coastguard Worker   packet_router_.GeneratePadding(DataSize::Bytes(kPaddingSize));
167*d9f75844SAndroid Build Coastguard Worker 
168*d9f75844SAndroid Build Coastguard Worker   // Remove and the add audio module again. Module order shouldn't matter;
169*d9f75844SAndroid Build Coastguard Worker   // video should still be prioritized.
170*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&audio_module);
171*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&audio_module, false);
172*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(audio_module, GeneratePadding).Times(0);
173*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(video_module, GeneratePadding(kPaddingSize))
174*d9f75844SAndroid Build Coastguard Worker       .WillOnce(generate_padding);
175*d9f75844SAndroid Build Coastguard Worker   packet_router_.GeneratePadding(DataSize::Bytes(kPaddingSize));
176*d9f75844SAndroid Build Coastguard Worker 
177*d9f75844SAndroid Build Coastguard Worker   // Remove and the video module, we should fall back to padding on the
178*d9f75844SAndroid Build Coastguard Worker   // audio module again.
179*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&video_module);
180*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(audio_module, GeneratePadding(kPaddingSize))
181*d9f75844SAndroid Build Coastguard Worker       .WillOnce(generate_padding);
182*d9f75844SAndroid Build Coastguard Worker   packet_router_.GeneratePadding(DataSize::Bytes(kPaddingSize));
183*d9f75844SAndroid Build Coastguard Worker 
184*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&audio_module);
185*d9f75844SAndroid Build Coastguard Worker }
186*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,PadsOnLastActiveMediaStream)187*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, PadsOnLastActiveMediaStream) {
188*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc1 = 1234;
189*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc2 = 4567;
190*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc3 = 8901;
191*d9f75844SAndroid Build Coastguard Worker 
192*d9f75844SAndroid Build Coastguard Worker   // First two rtp modules send media and have rtx.
193*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
194*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, SSRC()).WillRepeatedly(Return(kSsrc1));
195*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, SupportsPadding).WillRepeatedly(Return(true));
196*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, SupportsRtxPayloadPadding).WillRepeatedly(Return(true));
197*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, TrySendPacket).WillRepeatedly(Return(false));
198*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
199*d9f75844SAndroid Build Coastguard Worker       rtp_1,
200*d9f75844SAndroid Build Coastguard Worker       TrySendPacket(
201*d9f75844SAndroid Build Coastguard Worker           ::testing::Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc1)), _))
202*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(true));
203*d9f75844SAndroid Build Coastguard Worker 
204*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_2;
205*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, SSRC()).WillRepeatedly(Return(kSsrc2));
206*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, SupportsPadding).WillRepeatedly(Return(true));
207*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, SupportsRtxPayloadPadding).WillRepeatedly(Return(true));
208*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, TrySendPacket).WillRepeatedly(Return(false));
209*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
210*d9f75844SAndroid Build Coastguard Worker       rtp_2,
211*d9f75844SAndroid Build Coastguard Worker       TrySendPacket(
212*d9f75844SAndroid Build Coastguard Worker           ::testing::Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc2)), _))
213*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(true));
214*d9f75844SAndroid Build Coastguard Worker 
215*d9f75844SAndroid Build Coastguard Worker   // Third module is sending media, but does not support rtx.
216*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_3;
217*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_3, SSRC()).WillRepeatedly(Return(kSsrc3));
218*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_3, SupportsPadding).WillRepeatedly(Return(true));
219*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_3, SupportsRtxPayloadPadding).WillRepeatedly(Return(false));
220*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_3, TrySendPacket).WillRepeatedly(Return(false));
221*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
222*d9f75844SAndroid Build Coastguard Worker       rtp_3,
223*d9f75844SAndroid Build Coastguard Worker       TrySendPacket(
224*d9f75844SAndroid Build Coastguard Worker           ::testing::Pointee(Property(&RtpPacketToSend::Ssrc, kSsrc3)), _))
225*d9f75844SAndroid Build Coastguard Worker       .WillRepeatedly(Return(true));
226*d9f75844SAndroid Build Coastguard Worker 
227*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_1, false);
228*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_2, false);
229*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_3, false);
230*d9f75844SAndroid Build Coastguard Worker 
231*d9f75844SAndroid Build Coastguard Worker   const size_t kPaddingBytes = 100;
232*d9f75844SAndroid Build Coastguard Worker 
233*d9f75844SAndroid Build Coastguard Worker   // Initially, padding will be sent on last added rtp module that sends media
234*d9f75844SAndroid Build Coastguard Worker   // and supports rtx.
235*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, GeneratePadding(kPaddingBytes))
236*d9f75844SAndroid Build Coastguard Worker       .Times(1)
237*d9f75844SAndroid Build Coastguard Worker       .WillOnce([&](size_t target_size_bytes) {
238*d9f75844SAndroid Build Coastguard Worker         std::vector<std::unique_ptr<RtpPacketToSend>> packets;
239*d9f75844SAndroid Build Coastguard Worker         packets.push_back(BuildRtpPacket(kSsrc2));
240*d9f75844SAndroid Build Coastguard Worker         return packets;
241*d9f75844SAndroid Build Coastguard Worker       });
242*d9f75844SAndroid Build Coastguard Worker   packet_router_.GeneratePadding(DataSize::Bytes(kPaddingBytes));
243*d9f75844SAndroid Build Coastguard Worker 
244*d9f75844SAndroid Build Coastguard Worker   // Send media on first module. Padding should be sent on that module.
245*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendPacket(BuildRtpPacket(kSsrc1), PacedPacketInfo());
246*d9f75844SAndroid Build Coastguard Worker 
247*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, GeneratePadding(kPaddingBytes))
248*d9f75844SAndroid Build Coastguard Worker       .Times(1)
249*d9f75844SAndroid Build Coastguard Worker       .WillOnce([&](size_t target_size_bytes) {
250*d9f75844SAndroid Build Coastguard Worker         std::vector<std::unique_ptr<RtpPacketToSend>> packets;
251*d9f75844SAndroid Build Coastguard Worker         packets.push_back(BuildRtpPacket(kSsrc1));
252*d9f75844SAndroid Build Coastguard Worker         return packets;
253*d9f75844SAndroid Build Coastguard Worker       });
254*d9f75844SAndroid Build Coastguard Worker   packet_router_.GeneratePadding(DataSize::Bytes(kPaddingBytes));
255*d9f75844SAndroid Build Coastguard Worker 
256*d9f75844SAndroid Build Coastguard Worker   // Send media on second module. Padding should be sent there.
257*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendPacket(BuildRtpPacket(kSsrc2), PacedPacketInfo());
258*d9f75844SAndroid Build Coastguard Worker 
259*d9f75844SAndroid Build Coastguard Worker   // If the last active module is removed, and no module sends media before
260*d9f75844SAndroid Build Coastguard Worker   // the next padding request, and arbitrary module will be selected.
261*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_2);
262*d9f75844SAndroid Build Coastguard Worker 
263*d9f75844SAndroid Build Coastguard Worker   // Send on and then remove all remaining modules.
264*d9f75844SAndroid Build Coastguard Worker   RtpRtcpInterface* last_send_module;
265*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, GeneratePadding(kPaddingBytes))
266*d9f75844SAndroid Build Coastguard Worker       .Times(1)
267*d9f75844SAndroid Build Coastguard Worker       .WillOnce([&](size_t target_size_bytes) {
268*d9f75844SAndroid Build Coastguard Worker         last_send_module = &rtp_1;
269*d9f75844SAndroid Build Coastguard Worker         std::vector<std::unique_ptr<RtpPacketToSend>> packets;
270*d9f75844SAndroid Build Coastguard Worker         packets.push_back(BuildRtpPacket(kSsrc1));
271*d9f75844SAndroid Build Coastguard Worker         return packets;
272*d9f75844SAndroid Build Coastguard Worker       });
273*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_3, GeneratePadding(kPaddingBytes))
274*d9f75844SAndroid Build Coastguard Worker       .Times(1)
275*d9f75844SAndroid Build Coastguard Worker       .WillOnce([&](size_t target_size_bytes) {
276*d9f75844SAndroid Build Coastguard Worker         last_send_module = &rtp_3;
277*d9f75844SAndroid Build Coastguard Worker         std::vector<std::unique_ptr<RtpPacketToSend>> packets;
278*d9f75844SAndroid Build Coastguard Worker         packets.push_back(BuildRtpPacket(kSsrc3));
279*d9f75844SAndroid Build Coastguard Worker         return packets;
280*d9f75844SAndroid Build Coastguard Worker       });
281*d9f75844SAndroid Build Coastguard Worker 
282*d9f75844SAndroid Build Coastguard Worker   for (int i = 0; i < 2; ++i) {
283*d9f75844SAndroid Build Coastguard Worker     last_send_module = nullptr;
284*d9f75844SAndroid Build Coastguard Worker     packet_router_.GeneratePadding(DataSize::Bytes(kPaddingBytes));
285*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(last_send_module, nullptr);
286*d9f75844SAndroid Build Coastguard Worker     packet_router_.RemoveSendRtpModule(last_send_module);
287*d9f75844SAndroid Build Coastguard Worker   }
288*d9f75844SAndroid Build Coastguard Worker }
289*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,AllocatesTransportSequenceNumbers)290*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, AllocatesTransportSequenceNumbers) {
291*d9f75844SAndroid Build Coastguard Worker   const uint16_t kStartSeq = 0xFFF0;
292*d9f75844SAndroid Build Coastguard Worker   const size_t kNumPackets = 32;
293*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc1 = 1234;
294*d9f75844SAndroid Build Coastguard Worker 
295*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router(kStartSeq - 1);
296*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
297*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, SSRC()).WillRepeatedly(Return(kSsrc1));
298*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, TrySendPacket).WillRepeatedly(Return(true));
299*d9f75844SAndroid Build Coastguard Worker   packet_router.AddSendRtpModule(&rtp_1, false);
300*d9f75844SAndroid Build Coastguard Worker 
301*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumPackets; ++i) {
302*d9f75844SAndroid Build Coastguard Worker     auto packet = BuildRtpPacket(kSsrc1);
303*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
304*d9f75844SAndroid Build Coastguard Worker     packet_router.SendPacket(std::move(packet), PacedPacketInfo());
305*d9f75844SAndroid Build Coastguard Worker     uint32_t expected_unwrapped_seq = static_cast<uint32_t>(kStartSeq) + i;
306*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint16_t>(expected_unwrapped_seq & 0xFFFF),
307*d9f75844SAndroid Build Coastguard Worker               packet_router.CurrentTransportSequenceNumber());
308*d9f75844SAndroid Build Coastguard Worker   }
309*d9f75844SAndroid Build Coastguard Worker 
310*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveSendRtpModule(&rtp_1);
311*d9f75844SAndroid Build Coastguard Worker }
312*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,SendTransportFeedback)313*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, SendTransportFeedback) {
314*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
315*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_2;
316*d9f75844SAndroid Build Coastguard Worker 
317*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, RTCP()).WillByDefault(Return(RtcpMode::kCompound));
318*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_2, RTCP()).WillByDefault(Return(RtcpMode::kCompound));
319*d9f75844SAndroid Build Coastguard Worker 
320*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_1, false);
321*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddReceiveRtpModule(&rtp_2, false);
322*d9f75844SAndroid Build Coastguard Worker 
323*d9f75844SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback;
324*d9f75844SAndroid Build Coastguard Worker   feedback.push_back(std::make_unique<rtcp::TransportFeedback>());
325*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, SendCombinedRtcpPacket);
326*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendCombinedRtcpPacket(std::move(feedback));
327*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_1);
328*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, SendCombinedRtcpPacket);
329*d9f75844SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<rtcp::RtcpPacket>> new_feedback;
330*d9f75844SAndroid Build Coastguard Worker   new_feedback.push_back(std::make_unique<rtcp::TransportFeedback>());
331*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendCombinedRtcpPacket(std::move(new_feedback));
332*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveReceiveRtpModule(&rtp_2);
333*d9f75844SAndroid Build Coastguard Worker }
334*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,SendPacketWithoutTransportSequenceNumbers)335*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, SendPacketWithoutTransportSequenceNumbers) {
336*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc1 = 1234;
337*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
338*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, SendingMedia).WillByDefault(Return(true));
339*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
340*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_1, false);
341*d9f75844SAndroid Build Coastguard Worker 
342*d9f75844SAndroid Build Coastguard Worker   // Send a packet without TransportSequenceNumber extension registered,
343*d9f75844SAndroid Build Coastguard Worker   // packets sent should not have the extension set.
344*d9f75844SAndroid Build Coastguard Worker   RtpHeaderExtensionMap extension_manager;
345*d9f75844SAndroid Build Coastguard Worker   auto packet = std::make_unique<RtpPacketToSend>(&extension_manager);
346*d9f75844SAndroid Build Coastguard Worker   packet->SetSsrc(kSsrc1);
347*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
348*d9f75844SAndroid Build Coastguard Worker       rtp_1,
349*d9f75844SAndroid Build Coastguard Worker       TrySendPacket(
350*d9f75844SAndroid Build Coastguard Worker           Property(&RtpPacketToSend::HasExtension<TransportSequenceNumber>,
351*d9f75844SAndroid Build Coastguard Worker                    false),
352*d9f75844SAndroid Build Coastguard Worker           _))
353*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Return(true));
354*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
355*d9f75844SAndroid Build Coastguard Worker 
356*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_1);
357*d9f75844SAndroid Build Coastguard Worker }
358*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,SendPacketAssignsTransportSequenceNumbers)359*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, SendPacketAssignsTransportSequenceNumbers) {
360*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
361*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_2;
362*d9f75844SAndroid Build Coastguard Worker 
363*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc1 = 1234;
364*d9f75844SAndroid Build Coastguard Worker   const uint16_t kSsrc2 = 2345;
365*d9f75844SAndroid Build Coastguard Worker 
366*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
367*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
368*d9f75844SAndroid Build Coastguard Worker 
369*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_1, false);
370*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_2, false);
371*d9f75844SAndroid Build Coastguard Worker 
372*d9f75844SAndroid Build Coastguard Worker   // Transport sequence numbers start at 1, for historical reasons.
373*d9f75844SAndroid Build Coastguard Worker   uint16_t transport_sequence_number = 1;
374*d9f75844SAndroid Build Coastguard Worker 
375*d9f75844SAndroid Build Coastguard Worker   auto packet = BuildRtpPacket(kSsrc1);
376*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
377*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
378*d9f75844SAndroid Build Coastguard Worker       rtp_1,
379*d9f75844SAndroid Build Coastguard Worker       TrySendPacket(
380*d9f75844SAndroid Build Coastguard Worker           Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
381*d9f75844SAndroid Build Coastguard Worker                    transport_sequence_number),
382*d9f75844SAndroid Build Coastguard Worker           _))
383*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Return(true));
384*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
385*d9f75844SAndroid Build Coastguard Worker 
386*d9f75844SAndroid Build Coastguard Worker   ++transport_sequence_number;
387*d9f75844SAndroid Build Coastguard Worker   packet = BuildRtpPacket(kSsrc2);
388*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
389*d9f75844SAndroid Build Coastguard Worker 
390*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
391*d9f75844SAndroid Build Coastguard Worker       rtp_2,
392*d9f75844SAndroid Build Coastguard Worker       TrySendPacket(
393*d9f75844SAndroid Build Coastguard Worker           Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
394*d9f75844SAndroid Build Coastguard Worker                    transport_sequence_number),
395*d9f75844SAndroid Build Coastguard Worker           _))
396*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Return(true));
397*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
398*d9f75844SAndroid Build Coastguard Worker 
399*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_1);
400*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_2);
401*d9f75844SAndroid Build Coastguard Worker }
402*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,DoesNotIncrementTransportSequenceNumberOnSendFailure)403*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, DoesNotIncrementTransportSequenceNumberOnSendFailure) {
404*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp;
405*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t kSsrc = 1234;
406*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp, SSRC).WillByDefault(Return(kSsrc));
407*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp, false);
408*d9f75844SAndroid Build Coastguard Worker 
409*d9f75844SAndroid Build Coastguard Worker   // Transport sequence numbers start at 1, for historical reasons.
410*d9f75844SAndroid Build Coastguard Worker   const uint16_t kStartTransportSequenceNumber = 1;
411*d9f75844SAndroid Build Coastguard Worker 
412*d9f75844SAndroid Build Coastguard Worker   // Build and send a packet - it should be assigned the start sequence number.
413*d9f75844SAndroid Build Coastguard Worker   // Return failure status code to make sure sequence number is not incremented.
414*d9f75844SAndroid Build Coastguard Worker   auto packet = BuildRtpPacket(kSsrc);
415*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
416*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
417*d9f75844SAndroid Build Coastguard Worker       rtp, TrySendPacket(
418*d9f75844SAndroid Build Coastguard Worker                Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
419*d9f75844SAndroid Build Coastguard Worker                         kStartTransportSequenceNumber),
420*d9f75844SAndroid Build Coastguard Worker                _))
421*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Return(false));
422*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
423*d9f75844SAndroid Build Coastguard Worker 
424*d9f75844SAndroid Build Coastguard Worker   // Send another packet, verify transport sequence number is still at the
425*d9f75844SAndroid Build Coastguard Worker   // start state.
426*d9f75844SAndroid Build Coastguard Worker   packet = BuildRtpPacket(kSsrc);
427*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(packet->ReserveExtension<TransportSequenceNumber>());
428*d9f75844SAndroid Build Coastguard Worker 
429*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(
430*d9f75844SAndroid Build Coastguard Worker       rtp, TrySendPacket(
431*d9f75844SAndroid Build Coastguard Worker                Property(&RtpPacketToSend::GetExtension<TransportSequenceNumber>,
432*d9f75844SAndroid Build Coastguard Worker                         kStartTransportSequenceNumber),
433*d9f75844SAndroid Build Coastguard Worker                _))
434*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Return(true));
435*d9f75844SAndroid Build Coastguard Worker   packet_router_.SendPacket(std::move(packet), PacedPacketInfo());
436*d9f75844SAndroid Build Coastguard Worker 
437*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp);
438*d9f75844SAndroid Build Coastguard Worker }
439*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,ForwardsAbortedRetransmissions)440*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, ForwardsAbortedRetransmissions) {
441*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
442*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_2;
443*d9f75844SAndroid Build Coastguard Worker 
444*d9f75844SAndroid Build Coastguard Worker   const uint32_t kSsrc1 = 1234;
445*d9f75844SAndroid Build Coastguard Worker   const uint32_t kSsrc2 = 2345;
446*d9f75844SAndroid Build Coastguard Worker   const uint32_t kInvalidSsrc = 3456;
447*d9f75844SAndroid Build Coastguard Worker 
448*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
449*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
450*d9f75844SAndroid Build Coastguard Worker 
451*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_1, false);
452*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_2, false);
453*d9f75844SAndroid Build Coastguard Worker 
454*d9f75844SAndroid Build Coastguard Worker   // Sets of retransmission sequence numbers we wish to abort, per ssrc.
455*d9f75844SAndroid Build Coastguard Worker   const uint16_t kAbortedRetransmissionsOnSsrc1[] = {17, 42};
456*d9f75844SAndroid Build Coastguard Worker   const uint16_t kAbortedRetransmissionsOnSsrc2[] = {1337, 4711};
457*d9f75844SAndroid Build Coastguard Worker   const uint16_t kAbortedRetransmissionsOnSsrc3[] = {123};
458*d9f75844SAndroid Build Coastguard Worker 
459*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_1, OnAbortedRetransmissions(
460*d9f75844SAndroid Build Coastguard Worker                          ElementsAreArray(kAbortedRetransmissionsOnSsrc1)));
461*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_2, OnAbortedRetransmissions(
462*d9f75844SAndroid Build Coastguard Worker                          ElementsAreArray(kAbortedRetransmissionsOnSsrc2)));
463*d9f75844SAndroid Build Coastguard Worker 
464*d9f75844SAndroid Build Coastguard Worker   packet_router_.OnAbortedRetransmissions(kSsrc1,
465*d9f75844SAndroid Build Coastguard Worker                                           kAbortedRetransmissionsOnSsrc1);
466*d9f75844SAndroid Build Coastguard Worker   packet_router_.OnAbortedRetransmissions(kSsrc2,
467*d9f75844SAndroid Build Coastguard Worker                                           kAbortedRetransmissionsOnSsrc2);
468*d9f75844SAndroid Build Coastguard Worker 
469*d9f75844SAndroid Build Coastguard Worker   // Should be noop and not cause any issues.
470*d9f75844SAndroid Build Coastguard Worker   packet_router_.OnAbortedRetransmissions(kInvalidSsrc,
471*d9f75844SAndroid Build Coastguard Worker                                           kAbortedRetransmissionsOnSsrc3);
472*d9f75844SAndroid Build Coastguard Worker 
473*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_1);
474*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_2);
475*d9f75844SAndroid Build Coastguard Worker }
476*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterTest,ReportsRtxSsrc)477*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterTest, ReportsRtxSsrc) {
478*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_1;
479*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_2;
480*d9f75844SAndroid Build Coastguard Worker 
481*d9f75844SAndroid Build Coastguard Worker   const uint32_t kSsrc1 = 1234;
482*d9f75844SAndroid Build Coastguard Worker   const uint32_t kRtxSsrc1 = 1235;
483*d9f75844SAndroid Build Coastguard Worker   const uint32_t kSsrc2 = 2345;
484*d9f75844SAndroid Build Coastguard Worker   const uint32_t kInvalidSsrc = 3456;
485*d9f75844SAndroid Build Coastguard Worker 
486*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, SSRC).WillByDefault(Return(kSsrc1));
487*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_1, RtxSsrc).WillByDefault(Return(kRtxSsrc1));
488*d9f75844SAndroid Build Coastguard Worker   ON_CALL(rtp_2, SSRC).WillByDefault(Return(kSsrc2));
489*d9f75844SAndroid Build Coastguard Worker 
490*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_1, false);
491*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&rtp_2, false);
492*d9f75844SAndroid Build Coastguard Worker 
493*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kSsrc1), kRtxSsrc1);
494*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kRtxSsrc1), absl::nullopt);
495*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kSsrc2), absl::nullopt);
496*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(packet_router_.GetRtxSsrcForMedia(kInvalidSsrc), absl::nullopt);
497*d9f75844SAndroid Build Coastguard Worker 
498*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_1);
499*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&rtp_2);
500*d9f75844SAndroid Build Coastguard Worker }
501*d9f75844SAndroid Build Coastguard Worker 
502*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
503*d9f75844SAndroid Build Coastguard Worker using PacketRouterDeathTest = PacketRouterTest;
TEST_F(PacketRouterDeathTest,DoubleRegistrationOfSendModuleDisallowed)504*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterDeathTest, DoubleRegistrationOfSendModuleDisallowed) {
505*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
506*d9f75844SAndroid Build Coastguard Worker 
507*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = false;  // Value irrelevant.
508*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddSendRtpModule(&module, remb_candidate);
509*d9f75844SAndroid Build Coastguard Worker   EXPECT_DEATH(packet_router_.AddSendRtpModule(&module, remb_candidate), "");
510*d9f75844SAndroid Build Coastguard Worker 
511*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
512*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveSendRtpModule(&module);
513*d9f75844SAndroid Build Coastguard Worker }
514*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterDeathTest,DoubleRegistrationOfReceiveModuleDisallowed)515*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterDeathTest, DoubleRegistrationOfReceiveModuleDisallowed) {
516*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
517*d9f75844SAndroid Build Coastguard Worker 
518*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = false;  // Value irrelevant.
519*d9f75844SAndroid Build Coastguard Worker   packet_router_.AddReceiveRtpModule(&module, remb_candidate);
520*d9f75844SAndroid Build Coastguard Worker   EXPECT_DEATH(packet_router_.AddReceiveRtpModule(&module, remb_candidate), "");
521*d9f75844SAndroid Build Coastguard Worker 
522*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
523*d9f75844SAndroid Build Coastguard Worker   packet_router_.RemoveReceiveRtpModule(&module);
524*d9f75844SAndroid Build Coastguard Worker }
525*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterDeathTest,RemovalOfNeverAddedSendModuleDisallowed)526*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterDeathTest, RemovalOfNeverAddedSendModuleDisallowed) {
527*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
528*d9f75844SAndroid Build Coastguard Worker 
529*d9f75844SAndroid Build Coastguard Worker   EXPECT_DEATH(packet_router_.RemoveSendRtpModule(&module), "");
530*d9f75844SAndroid Build Coastguard Worker }
531*d9f75844SAndroid Build Coastguard Worker 
TEST_F(PacketRouterDeathTest,RemovalOfNeverAddedReceiveModuleDisallowed)532*d9f75844SAndroid Build Coastguard Worker TEST_F(PacketRouterDeathTest, RemovalOfNeverAddedReceiveModuleDisallowed) {
533*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
534*d9f75844SAndroid Build Coastguard Worker 
535*d9f75844SAndroid Build Coastguard Worker   EXPECT_DEATH(packet_router_.RemoveReceiveRtpModule(&module), "");
536*d9f75844SAndroid Build Coastguard Worker }
537*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
538*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,ChangeSendRtpModuleChangeRembSender)539*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest, ChangeSendRtpModuleChangeRembSender) {
540*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
541*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_send;
542*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp_recv;
543*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
544*d9f75844SAndroid Build Coastguard Worker   packet_router.AddSendRtpModule(&rtp_send, true);
545*d9f75844SAndroid Build Coastguard Worker   packet_router.AddReceiveRtpModule(&rtp_recv, true);
546*d9f75844SAndroid Build Coastguard Worker 
547*d9f75844SAndroid Build Coastguard Worker   uint32_t bitrate_estimate = 456;
548*d9f75844SAndroid Build Coastguard Worker   std::vector<uint32_t> ssrcs = {1234, 5678};
549*d9f75844SAndroid Build Coastguard Worker 
550*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_send, SetRemb(bitrate_estimate, ssrcs));
551*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
552*d9f75844SAndroid Build Coastguard Worker 
553*d9f75844SAndroid Build Coastguard Worker   // Remove the sending module -> should get remb on the second module.
554*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveSendRtpModule(&rtp_send);
555*d9f75844SAndroid Build Coastguard Worker 
556*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp_recv, SetRemb(bitrate_estimate, ssrcs));
557*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
558*d9f75844SAndroid Build Coastguard Worker 
559*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveReceiveRtpModule(&rtp_recv);
560*d9f75844SAndroid Build Coastguard Worker }
561*d9f75844SAndroid Build Coastguard Worker 
562*d9f75844SAndroid Build Coastguard Worker // Only register receiving modules and make sure we fallback to trigger a REMB
563*d9f75844SAndroid Build Coastguard Worker // packet on this one.
TEST(PacketRouterRembTest,NoSendingRtpModule)564*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest, NoSendingRtpModule) {
565*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
566*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> rtp;
567*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
568*d9f75844SAndroid Build Coastguard Worker 
569*d9f75844SAndroid Build Coastguard Worker   packet_router.AddReceiveRtpModule(&rtp, true);
570*d9f75844SAndroid Build Coastguard Worker 
571*d9f75844SAndroid Build Coastguard Worker   uint32_t bitrate_estimate = 456;
572*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
573*d9f75844SAndroid Build Coastguard Worker 
574*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp, SetRemb(bitrate_estimate, ssrcs));
575*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
576*d9f75844SAndroid Build Coastguard Worker 
577*d9f75844SAndroid Build Coastguard Worker   // Lower the estimate to trigger a new packet REMB packet.
578*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp, SetRemb(bitrate_estimate, ssrcs));
579*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
580*d9f75844SAndroid Build Coastguard Worker 
581*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(rtp, UnsetRemb());
582*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveReceiveRtpModule(&rtp);
583*d9f75844SAndroid Build Coastguard Worker }
584*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,NonCandidateSendRtpModuleNotUsedForRemb)585*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest, NonCandidateSendRtpModuleNotUsedForRemb) {
586*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
587*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
588*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
589*d9f75844SAndroid Build Coastguard Worker 
590*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = false;
591*d9f75844SAndroid Build Coastguard Worker 
592*d9f75844SAndroid Build Coastguard Worker   packet_router.AddSendRtpModule(&module, remb_candidate);
593*d9f75844SAndroid Build Coastguard Worker 
594*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_estimate = 456;
595*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
596*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(module, SetRemb(_, _)).Times(0);
597*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
598*d9f75844SAndroid Build Coastguard Worker 
599*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
600*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveSendRtpModule(&module);
601*d9f75844SAndroid Build Coastguard Worker }
602*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,CandidateSendRtpModuleUsedForRemb)603*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest, CandidateSendRtpModuleUsedForRemb) {
604*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
605*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
606*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
607*d9f75844SAndroid Build Coastguard Worker 
608*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = true;
609*d9f75844SAndroid Build Coastguard Worker 
610*d9f75844SAndroid Build Coastguard Worker   packet_router.AddSendRtpModule(&module, remb_candidate);
611*d9f75844SAndroid Build Coastguard Worker 
612*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_estimate = 456;
613*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
614*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(module, SetRemb(bitrate_estimate, ssrcs));
615*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
616*d9f75844SAndroid Build Coastguard Worker 
617*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
618*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveSendRtpModule(&module);
619*d9f75844SAndroid Build Coastguard Worker }
620*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,NonCandidateReceiveRtpModuleNotUsedForRemb)621*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest, NonCandidateReceiveRtpModuleNotUsedForRemb) {
622*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
623*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
624*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
625*d9f75844SAndroid Build Coastguard Worker 
626*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = false;
627*d9f75844SAndroid Build Coastguard Worker 
628*d9f75844SAndroid Build Coastguard Worker   packet_router.AddReceiveRtpModule(&module, remb_candidate);
629*d9f75844SAndroid Build Coastguard Worker 
630*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_estimate = 456;
631*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
632*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(module, SetRemb(_, _)).Times(0);
633*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
634*d9f75844SAndroid Build Coastguard Worker 
635*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
636*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveReceiveRtpModule(&module);
637*d9f75844SAndroid Build Coastguard Worker }
638*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,CandidateReceiveRtpModuleUsedForRemb)639*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest, CandidateReceiveRtpModuleUsedForRemb) {
640*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
641*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
642*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> module;
643*d9f75844SAndroid Build Coastguard Worker 
644*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = true;
645*d9f75844SAndroid Build Coastguard Worker 
646*d9f75844SAndroid Build Coastguard Worker   packet_router.AddReceiveRtpModule(&module, remb_candidate);
647*d9f75844SAndroid Build Coastguard Worker 
648*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_estimate = 456;
649*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
650*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(module, SetRemb(bitrate_estimate, ssrcs));
651*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
652*d9f75844SAndroid Build Coastguard Worker 
653*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
654*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveReceiveRtpModule(&module);
655*d9f75844SAndroid Build Coastguard Worker }
656*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,SendCandidatePreferredOverReceiveCandidate_SendModuleAddedFirst)657*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest,
658*d9f75844SAndroid Build Coastguard Worker      SendCandidatePreferredOverReceiveCandidate_SendModuleAddedFirst) {
659*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
660*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
661*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> send_module;
662*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> receive_module;
663*d9f75844SAndroid Build Coastguard Worker 
664*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = true;
665*d9f75844SAndroid Build Coastguard Worker 
666*d9f75844SAndroid Build Coastguard Worker   // Send module added - activated.
667*d9f75844SAndroid Build Coastguard Worker   packet_router.AddSendRtpModule(&send_module, remb_candidate);
668*d9f75844SAndroid Build Coastguard Worker 
669*d9f75844SAndroid Build Coastguard Worker   // Receive module added - the send module remains the active one.
670*d9f75844SAndroid Build Coastguard Worker   packet_router.AddReceiveRtpModule(&receive_module, remb_candidate);
671*d9f75844SAndroid Build Coastguard Worker 
672*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_estimate = 456;
673*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
674*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(send_module, SetRemb(bitrate_estimate, ssrcs));
675*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(receive_module, SetRemb(_, _)).Times(0);
676*d9f75844SAndroid Build Coastguard Worker 
677*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
678*d9f75844SAndroid Build Coastguard Worker 
679*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
680*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveReceiveRtpModule(&receive_module);
681*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveSendRtpModule(&send_module);
682*d9f75844SAndroid Build Coastguard Worker }
683*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,SendCandidatePreferredOverReceiveCandidate_ReceiveModuleAddedFirst)684*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest,
685*d9f75844SAndroid Build Coastguard Worker      SendCandidatePreferredOverReceiveCandidate_ReceiveModuleAddedFirst) {
686*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
687*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
688*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> send_module;
689*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> receive_module;
690*d9f75844SAndroid Build Coastguard Worker 
691*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = true;
692*d9f75844SAndroid Build Coastguard Worker 
693*d9f75844SAndroid Build Coastguard Worker   // Receive module added - activated.
694*d9f75844SAndroid Build Coastguard Worker   packet_router.AddReceiveRtpModule(&receive_module, remb_candidate);
695*d9f75844SAndroid Build Coastguard Worker 
696*d9f75844SAndroid Build Coastguard Worker   // Send module added - replaces receive module as active.
697*d9f75844SAndroid Build Coastguard Worker   packet_router.AddSendRtpModule(&send_module, remb_candidate);
698*d9f75844SAndroid Build Coastguard Worker 
699*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_estimate = 456;
700*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
701*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(send_module, SetRemb(bitrate_estimate, ssrcs));
702*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(receive_module, SetRemb(_, _)).Times(0);
703*d9f75844SAndroid Build Coastguard Worker 
704*d9f75844SAndroid Build Coastguard Worker   clock.AdvanceTime(TimeDelta::Millis(1000));
705*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
706*d9f75844SAndroid Build Coastguard Worker 
707*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
708*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveReceiveRtpModule(&receive_module);
709*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveSendRtpModule(&send_module);
710*d9f75844SAndroid Build Coastguard Worker }
711*d9f75844SAndroid Build Coastguard Worker 
TEST(PacketRouterRembTest,ReceiveModuleTakesOverWhenLastSendModuleRemoved)712*d9f75844SAndroid Build Coastguard Worker TEST(PacketRouterRembTest, ReceiveModuleTakesOverWhenLastSendModuleRemoved) {
713*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedFakeClock clock;
714*d9f75844SAndroid Build Coastguard Worker   PacketRouter packet_router;
715*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> send_module;
716*d9f75844SAndroid Build Coastguard Worker   NiceMock<MockRtpRtcpInterface> receive_module;
717*d9f75844SAndroid Build Coastguard Worker 
718*d9f75844SAndroid Build Coastguard Worker   constexpr bool remb_candidate = true;
719*d9f75844SAndroid Build Coastguard Worker 
720*d9f75844SAndroid Build Coastguard Worker   // Send module active, receive module inactive.
721*d9f75844SAndroid Build Coastguard Worker   packet_router.AddSendRtpModule(&send_module, remb_candidate);
722*d9f75844SAndroid Build Coastguard Worker   packet_router.AddReceiveRtpModule(&receive_module, remb_candidate);
723*d9f75844SAndroid Build Coastguard Worker 
724*d9f75844SAndroid Build Coastguard Worker   // Send module removed - receive module becomes active.
725*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveSendRtpModule(&send_module);
726*d9f75844SAndroid Build Coastguard Worker   constexpr uint32_t bitrate_estimate = 456;
727*d9f75844SAndroid Build Coastguard Worker   const std::vector<uint32_t> ssrcs = {1234};
728*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(send_module, SetRemb(_, _)).Times(0);
729*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(receive_module, SetRemb(bitrate_estimate, ssrcs));
730*d9f75844SAndroid Build Coastguard Worker   packet_router.SendRemb(bitrate_estimate, ssrcs);
731*d9f75844SAndroid Build Coastguard Worker 
732*d9f75844SAndroid Build Coastguard Worker   // Test tear-down
733*d9f75844SAndroid Build Coastguard Worker   packet_router.RemoveReceiveRtpModule(&receive_module);
734*d9f75844SAndroid Build Coastguard Worker }
735*d9f75844SAndroid Build Coastguard Worker 
736*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
737