xref: /aosp_15_r20/external/openscreen/cast/streaming/receiver_unittest.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "cast/streaming/receiver.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include <stdint.h>
8*3f982cf4SFabien Sanglard 
9*3f982cf4SFabien Sanglard #include <algorithm>
10*3f982cf4SFabien Sanglard #include <array>
11*3f982cf4SFabien Sanglard #include <utility>
12*3f982cf4SFabien Sanglard #include <vector>
13*3f982cf4SFabien Sanglard 
14*3f982cf4SFabien Sanglard #include "absl/types/span.h"
15*3f982cf4SFabien Sanglard #include "cast/streaming/compound_rtcp_parser.h"
16*3f982cf4SFabien Sanglard #include "cast/streaming/constants.h"
17*3f982cf4SFabien Sanglard #include "cast/streaming/encoded_frame.h"
18*3f982cf4SFabien Sanglard #include "cast/streaming/frame_crypto.h"
19*3f982cf4SFabien Sanglard #include "cast/streaming/mock_environment.h"
20*3f982cf4SFabien Sanglard #include "cast/streaming/receiver_packet_router.h"
21*3f982cf4SFabien Sanglard #include "cast/streaming/rtcp_common.h"
22*3f982cf4SFabien Sanglard #include "cast/streaming/rtcp_session.h"
23*3f982cf4SFabien Sanglard #include "cast/streaming/rtp_defines.h"
24*3f982cf4SFabien Sanglard #include "cast/streaming/rtp_packetizer.h"
25*3f982cf4SFabien Sanglard #include "cast/streaming/rtp_time.h"
26*3f982cf4SFabien Sanglard #include "cast/streaming/sender_report_builder.h"
27*3f982cf4SFabien Sanglard #include "cast/streaming/session_config.h"
28*3f982cf4SFabien Sanglard #include "cast/streaming/ssrc.h"
29*3f982cf4SFabien Sanglard #include "cast/streaming/testing/simple_socket_subscriber.h"
30*3f982cf4SFabien Sanglard #include "gmock/gmock.h"
31*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
32*3f982cf4SFabien Sanglard #include "platform/api/time.h"
33*3f982cf4SFabien Sanglard #include "platform/api/udp_socket.h"
34*3f982cf4SFabien Sanglard #include "platform/base/error.h"
35*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h"
36*3f982cf4SFabien Sanglard #include "platform/base/udp_packet.h"
37*3f982cf4SFabien Sanglard #include "platform/test/fake_clock.h"
38*3f982cf4SFabien Sanglard #include "platform/test/fake_task_runner.h"
39*3f982cf4SFabien Sanglard #include "util/chrono_helpers.h"
40*3f982cf4SFabien Sanglard #include "util/osp_logging.h"
41*3f982cf4SFabien Sanglard 
42*3f982cf4SFabien Sanglard using testing::_;
43*3f982cf4SFabien Sanglard using testing::AtLeast;
44*3f982cf4SFabien Sanglard using testing::Gt;
45*3f982cf4SFabien Sanglard using testing::Invoke;
46*3f982cf4SFabien Sanglard using testing::SaveArg;
47*3f982cf4SFabien Sanglard 
48*3f982cf4SFabien Sanglard namespace openscreen {
49*3f982cf4SFabien Sanglard namespace cast {
50*3f982cf4SFabien Sanglard namespace {
51*3f982cf4SFabien Sanglard 
52*3f982cf4SFabien Sanglard // Receiver configuration.
53*3f982cf4SFabien Sanglard 
54*3f982cf4SFabien Sanglard constexpr Ssrc kSenderSsrc = 1;
55*3f982cf4SFabien Sanglard constexpr Ssrc kReceiverSsrc = 2;
56*3f982cf4SFabien Sanglard constexpr int kRtpTimebase = 48000;
57*3f982cf4SFabien Sanglard constexpr milliseconds kTargetPlayoutDelay{100};
58*3f982cf4SFabien Sanglard constexpr auto kAesKey =
59*3f982cf4SFabien Sanglard     std::array<uint8_t, 16>{{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
60*3f982cf4SFabien Sanglard                              0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}};
61*3f982cf4SFabien Sanglard constexpr auto kCastIvMask =
62*3f982cf4SFabien Sanglard     std::array<uint8_t, 16>{{0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
63*3f982cf4SFabien Sanglard                              0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00}};
64*3f982cf4SFabien Sanglard 
65*3f982cf4SFabien Sanglard constexpr milliseconds kTargetPlayoutDelayChange{800};
66*3f982cf4SFabien Sanglard // Additional configuration for the Sender.
67*3f982cf4SFabien Sanglard constexpr RtpPayloadType kRtpPayloadType = RtpPayloadType::kVideoVp8;
68*3f982cf4SFabien Sanglard constexpr int kMaxRtpPacketSize = 64;
69*3f982cf4SFabien Sanglard 
70*3f982cf4SFabien Sanglard // A simulated one-way network delay, and round-trip network delay.
71*3f982cf4SFabien Sanglard constexpr auto kOneWayNetworkDelay = milliseconds(3);
72*3f982cf4SFabien Sanglard constexpr auto kRoundTripNetworkDelay = 2 * kOneWayNetworkDelay;
73*3f982cf4SFabien Sanglard static_assert(kRoundTripNetworkDelay < kTargetPlayoutDelay &&
74*3f982cf4SFabien Sanglard                   kRoundTripNetworkDelay < kTargetPlayoutDelayChange,
75*3f982cf4SFabien Sanglard               "Network delay must be smaller than target playout delay.");
76*3f982cf4SFabien Sanglard 
77*3f982cf4SFabien Sanglard // An EncodedFrame for unit testing, one of a sequence of simulated frames, each
78*3f982cf4SFabien Sanglard // of 10 ms duration. The first frame will be a key frame; and any later frames
79*3f982cf4SFabien Sanglard // will be non-key, dependent on the prior frame. Frame 5 (the 6th frame in the
80*3f982cf4SFabien Sanglard // zero-based sequence) will include a target playout delay change, an increase
81*3f982cf4SFabien Sanglard // to 800 ms. Frames with different IDs will contain vary in their payload data
82*3f982cf4SFabien Sanglard // size, but are always 3 or more packets' worth of data.
83*3f982cf4SFabien Sanglard struct SimulatedFrame : public EncodedFrame {
84*3f982cf4SFabien Sanglard   static constexpr milliseconds kFrameDuration = milliseconds(10);
85*3f982cf4SFabien Sanglard   static constexpr milliseconds kTargetPlayoutDelayChange = milliseconds(800);
86*3f982cf4SFabien Sanglard 
87*3f982cf4SFabien Sanglard   static constexpr int kPlayoutChangeAtFrame = 5;
88*3f982cf4SFabien Sanglard 
SimulatedFrameopenscreen::cast::__anon38b807a30111::SimulatedFrame89*3f982cf4SFabien Sanglard   SimulatedFrame(Clock::time_point first_frame_reference_time, int which) {
90*3f982cf4SFabien Sanglard     frame_id = FrameId::first() + which;
91*3f982cf4SFabien Sanglard     if (which == 0) {
92*3f982cf4SFabien Sanglard       dependency = EncodedFrame::KEY_FRAME;
93*3f982cf4SFabien Sanglard       referenced_frame_id = frame_id;
94*3f982cf4SFabien Sanglard     } else {
95*3f982cf4SFabien Sanglard       dependency = EncodedFrame::DEPENDS_ON_ANOTHER;
96*3f982cf4SFabien Sanglard       referenced_frame_id = frame_id - 1;
97*3f982cf4SFabien Sanglard     }
98*3f982cf4SFabien Sanglard     rtp_timestamp =
99*3f982cf4SFabien Sanglard         GetRtpStartTime() +
100*3f982cf4SFabien Sanglard         RtpTimeDelta::FromDuration(kFrameDuration * which, kRtpTimebase);
101*3f982cf4SFabien Sanglard     reference_time = first_frame_reference_time + kFrameDuration * which;
102*3f982cf4SFabien Sanglard     if (which == kPlayoutChangeAtFrame) {
103*3f982cf4SFabien Sanglard       new_playout_delay = kTargetPlayoutDelayChange;
104*3f982cf4SFabien Sanglard     }
105*3f982cf4SFabien Sanglard     constexpr int kAdditionalBytesEachSuccessiveFrame = 3;
106*3f982cf4SFabien Sanglard     buffer_.resize(3 * kMaxRtpPacketSize +
107*3f982cf4SFabien Sanglard                    which * kAdditionalBytesEachSuccessiveFrame);
108*3f982cf4SFabien Sanglard     for (size_t i = 0; i < buffer_.size(); ++i) {
109*3f982cf4SFabien Sanglard       buffer_[i] = static_cast<uint8_t>(which + static_cast<int>(i));
110*3f982cf4SFabien Sanglard     }
111*3f982cf4SFabien Sanglard     data = absl::Span<uint8_t>(buffer_);
112*3f982cf4SFabien Sanglard   }
113*3f982cf4SFabien Sanglard 
GetRtpStartTimeopenscreen::cast::__anon38b807a30111::SimulatedFrame114*3f982cf4SFabien Sanglard   static RtpTimeTicks GetRtpStartTime() {
115*3f982cf4SFabien Sanglard     return RtpTimeTicks::FromTimeSinceOrigin(seconds(0), kRtpTimebase);
116*3f982cf4SFabien Sanglard   }
117*3f982cf4SFabien Sanglard 
GetExpectedPlayoutDelayopenscreen::cast::__anon38b807a30111::SimulatedFrame118*3f982cf4SFabien Sanglard   static milliseconds GetExpectedPlayoutDelay(int which) {
119*3f982cf4SFabien Sanglard     return (which < kPlayoutChangeAtFrame) ? kTargetPlayoutDelay
120*3f982cf4SFabien Sanglard                                            : kTargetPlayoutDelayChange;
121*3f982cf4SFabien Sanglard   }
122*3f982cf4SFabien Sanglard 
123*3f982cf4SFabien Sanglard  private:
124*3f982cf4SFabien Sanglard   std::vector<uint8_t> buffer_;
125*3f982cf4SFabien Sanglard };
126*3f982cf4SFabien Sanglard 
127*3f982cf4SFabien Sanglard // static
128*3f982cf4SFabien Sanglard constexpr milliseconds SimulatedFrame::kFrameDuration;
129*3f982cf4SFabien Sanglard constexpr milliseconds SimulatedFrame::kTargetPlayoutDelayChange;
130*3f982cf4SFabien Sanglard constexpr int SimulatedFrame::kPlayoutChangeAtFrame;
131*3f982cf4SFabien Sanglard 
132*3f982cf4SFabien Sanglard // Processes packets from the Receiver under test, as a real Sender might, and
133*3f982cf4SFabien Sanglard // allows the unit tests to set expectations on events of interest to confirm
134*3f982cf4SFabien Sanglard // proper behavior of the Receiver.
135*3f982cf4SFabien Sanglard class MockSender : public CompoundRtcpParser::Client {
136*3f982cf4SFabien Sanglard  public:
MockSender(TaskRunner * task_runner,UdpSocket::Client * receiver)137*3f982cf4SFabien Sanglard   MockSender(TaskRunner* task_runner, UdpSocket::Client* receiver)
138*3f982cf4SFabien Sanglard       : task_runner_(task_runner),
139*3f982cf4SFabien Sanglard         receiver_(receiver),
140*3f982cf4SFabien Sanglard         sender_endpoint_{
141*3f982cf4SFabien Sanglard             // Use a random IPv6 address in the range reserved for
142*3f982cf4SFabien Sanglard             // "documentation purposes." Thus, the following is a fake address
143*3f982cf4SFabien Sanglard             // that should be blocked by the OS (and all network packet
144*3f982cf4SFabien Sanglard             // routers). But, these tests don't use real sockets, so...
145*3f982cf4SFabien Sanglard             IPAddress::Parse("2001:db8:0d93:69c2:fd1a:49a6:a7c0:e8a6").value(),
146*3f982cf4SFabien Sanglard             2344},
147*3f982cf4SFabien Sanglard         rtcp_session_(kSenderSsrc, kReceiverSsrc, FakeClock::now()),
148*3f982cf4SFabien Sanglard         sender_report_builder_(&rtcp_session_),
149*3f982cf4SFabien Sanglard         rtcp_parser_(&rtcp_session_, this),
150*3f982cf4SFabien Sanglard         crypto_(kAesKey, kCastIvMask),
151*3f982cf4SFabien Sanglard         rtp_packetizer_(kRtpPayloadType, kSenderSsrc, kMaxRtpPacketSize) {}
152*3f982cf4SFabien Sanglard 
153*3f982cf4SFabien Sanglard   ~MockSender() override = default;
154*3f982cf4SFabien Sanglard 
set_max_feedback_frame_id(FrameId f)155*3f982cf4SFabien Sanglard   void set_max_feedback_frame_id(FrameId f) { max_feedback_frame_id_ = f; }
156*3f982cf4SFabien Sanglard 
157*3f982cf4SFabien Sanglard   // Called by the test procedures to generate a Sender Report containing the
158*3f982cf4SFabien Sanglard   // given lip-sync timestamps, and send it to the Receiver. The caller must
159*3f982cf4SFabien Sanglard   // spin the TaskRunner for the RTCP packet to be delivered to the Receiver.
SendSenderReport(Clock::time_point reference_time,RtpTimeTicks rtp_timestamp)160*3f982cf4SFabien Sanglard   StatusReportId SendSenderReport(Clock::time_point reference_time,
161*3f982cf4SFabien Sanglard                                   RtpTimeTicks rtp_timestamp) {
162*3f982cf4SFabien Sanglard     // Generate the Sender Report RTCP packet.
163*3f982cf4SFabien Sanglard     uint8_t buffer[kMaxRtpPacketSizeForIpv4UdpOnEthernet];
164*3f982cf4SFabien Sanglard     RtcpSenderReport sender_report;
165*3f982cf4SFabien Sanglard     sender_report.reference_time = reference_time;
166*3f982cf4SFabien Sanglard     sender_report.rtp_timestamp = rtp_timestamp;
167*3f982cf4SFabien Sanglard     const auto packet_and_report_id =
168*3f982cf4SFabien Sanglard         sender_report_builder_.BuildPacket(sender_report, buffer);
169*3f982cf4SFabien Sanglard 
170*3f982cf4SFabien Sanglard     // Send the RTCP packet as a UdpPacket directly to the Receiver instance.
171*3f982cf4SFabien Sanglard     UdpPacket packet_to_send(packet_and_report_id.first.begin(),
172*3f982cf4SFabien Sanglard                              packet_and_report_id.first.end());
173*3f982cf4SFabien Sanglard     packet_to_send.set_source(sender_endpoint_);
174*3f982cf4SFabien Sanglard     task_runner_->PostTaskWithDelay(
175*3f982cf4SFabien Sanglard         [receiver = receiver_, packet = std::move(packet_to_send)]() mutable {
176*3f982cf4SFabien Sanglard           receiver->OnRead(nullptr, ErrorOr<UdpPacket>(std::move(packet)));
177*3f982cf4SFabien Sanglard         },
178*3f982cf4SFabien Sanglard         kOneWayNetworkDelay);
179*3f982cf4SFabien Sanglard 
180*3f982cf4SFabien Sanglard     return packet_and_report_id.second;
181*3f982cf4SFabien Sanglard   }
182*3f982cf4SFabien Sanglard 
183*3f982cf4SFabien Sanglard   // Sets which frame is currently being sent by this MockSender. Test code must
184*3f982cf4SFabien Sanglard   // call SendRtpPackets() to send the packets.
SetFrameBeingSent(const EncodedFrame & frame)185*3f982cf4SFabien Sanglard   void SetFrameBeingSent(const EncodedFrame& frame) {
186*3f982cf4SFabien Sanglard     frame_being_sent_ = crypto_.Encrypt(frame);
187*3f982cf4SFabien Sanglard   }
188*3f982cf4SFabien Sanglard 
189*3f982cf4SFabien Sanglard   // Returns a vector containing each packet ID once (of the current frame being
190*3f982cf4SFabien Sanglard   // sent). |permutation| controls the sort order of the vector: zero will
191*3f982cf4SFabien Sanglard   // provide all the packet IDs in order, and greater values will provide them
192*3f982cf4SFabien Sanglard   // in a different, predictable order.
GetAllPacketIds(int permutation)193*3f982cf4SFabien Sanglard   std::vector<FramePacketId> GetAllPacketIds(int permutation) {
194*3f982cf4SFabien Sanglard     const int num_packets =
195*3f982cf4SFabien Sanglard         rtp_packetizer_.ComputeNumberOfPackets(frame_being_sent_);
196*3f982cf4SFabien Sanglard     OSP_CHECK_GT(num_packets, 0);
197*3f982cf4SFabien Sanglard     std::vector<FramePacketId> ids;
198*3f982cf4SFabien Sanglard     ids.reserve(num_packets);
199*3f982cf4SFabien Sanglard     const FramePacketId last_packet_id =
200*3f982cf4SFabien Sanglard         static_cast<FramePacketId>(num_packets - 1);
201*3f982cf4SFabien Sanglard     for (FramePacketId packet_id = 0; packet_id <= last_packet_id;
202*3f982cf4SFabien Sanglard          ++packet_id) {
203*3f982cf4SFabien Sanglard       ids.push_back(packet_id);
204*3f982cf4SFabien Sanglard     }
205*3f982cf4SFabien Sanglard     for (int i = 0; i < permutation; ++i) {
206*3f982cf4SFabien Sanglard       std::next_permutation(ids.begin(), ids.end());
207*3f982cf4SFabien Sanglard     }
208*3f982cf4SFabien Sanglard     return ids;
209*3f982cf4SFabien Sanglard   }
210*3f982cf4SFabien Sanglard 
211*3f982cf4SFabien Sanglard   // Send the specified packets of the current frame being sent.
SendRtpPackets(const std::vector<FramePacketId> & packets_to_send)212*3f982cf4SFabien Sanglard   void SendRtpPackets(const std::vector<FramePacketId>& packets_to_send) {
213*3f982cf4SFabien Sanglard     uint8_t buffer[kMaxRtpPacketSize];
214*3f982cf4SFabien Sanglard     for (FramePacketId packet_id : packets_to_send) {
215*3f982cf4SFabien Sanglard       const auto span =
216*3f982cf4SFabien Sanglard           rtp_packetizer_.GeneratePacket(frame_being_sent_, packet_id, buffer);
217*3f982cf4SFabien Sanglard       UdpPacket packet_to_send(span.begin(), span.end());
218*3f982cf4SFabien Sanglard       packet_to_send.set_source(sender_endpoint_);
219*3f982cf4SFabien Sanglard       task_runner_->PostTaskWithDelay(
220*3f982cf4SFabien Sanglard           [receiver = receiver_, packet = std::move(packet_to_send)]() mutable {
221*3f982cf4SFabien Sanglard             receiver->OnRead(nullptr, ErrorOr<UdpPacket>(std::move(packet)));
222*3f982cf4SFabien Sanglard           },
223*3f982cf4SFabien Sanglard           kOneWayNetworkDelay);
224*3f982cf4SFabien Sanglard     }
225*3f982cf4SFabien Sanglard   }
226*3f982cf4SFabien Sanglard 
227*3f982cf4SFabien Sanglard   // Called to process a packet from the Receiver.
OnPacketFromReceiver(absl::Span<const uint8_t> packet)228*3f982cf4SFabien Sanglard   void OnPacketFromReceiver(absl::Span<const uint8_t> packet) {
229*3f982cf4SFabien Sanglard     EXPECT_TRUE(rtcp_parser_.Parse(packet, max_feedback_frame_id_));
230*3f982cf4SFabien Sanglard   }
231*3f982cf4SFabien Sanglard 
232*3f982cf4SFabien Sanglard   // CompoundRtcpParser::Client implementation: Tests set expectations on these
233*3f982cf4SFabien Sanglard   // mocks to confirm that the receiver is providing the right data to the
234*3f982cf4SFabien Sanglard   // sender in its RTCP packets.
235*3f982cf4SFabien Sanglard   MOCK_METHOD1(OnReceiverReferenceTimeAdvanced,
236*3f982cf4SFabien Sanglard                void(Clock::time_point reference_time));
237*3f982cf4SFabien Sanglard   MOCK_METHOD1(OnReceiverReport, void(const RtcpReportBlock& receiver_report));
238*3f982cf4SFabien Sanglard   MOCK_METHOD0(OnReceiverIndicatesPictureLoss, void());
239*3f982cf4SFabien Sanglard   MOCK_METHOD2(OnReceiverCheckpoint,
240*3f982cf4SFabien Sanglard                void(FrameId frame_id, milliseconds playout_delay));
241*3f982cf4SFabien Sanglard   MOCK_METHOD1(OnReceiverHasFrames, void(std::vector<FrameId> acks));
242*3f982cf4SFabien Sanglard   MOCK_METHOD1(OnReceiverIsMissingPackets, void(std::vector<PacketNack> nacks));
243*3f982cf4SFabien Sanglard 
244*3f982cf4SFabien Sanglard  private:
245*3f982cf4SFabien Sanglard   TaskRunner* const task_runner_;
246*3f982cf4SFabien Sanglard   UdpSocket::Client* const receiver_;
247*3f982cf4SFabien Sanglard   const IPEndpoint sender_endpoint_;
248*3f982cf4SFabien Sanglard   RtcpSession rtcp_session_;
249*3f982cf4SFabien Sanglard   SenderReportBuilder sender_report_builder_;
250*3f982cf4SFabien Sanglard   CompoundRtcpParser rtcp_parser_;
251*3f982cf4SFabien Sanglard   FrameCrypto crypto_;
252*3f982cf4SFabien Sanglard   RtpPacketizer rtp_packetizer_;
253*3f982cf4SFabien Sanglard   FrameId max_feedback_frame_id_ = FrameId::first() + kMaxUnackedFrames;
254*3f982cf4SFabien Sanglard 
255*3f982cf4SFabien Sanglard   EncryptedFrame frame_being_sent_;
256*3f982cf4SFabien Sanglard };
257*3f982cf4SFabien Sanglard 
258*3f982cf4SFabien Sanglard class MockConsumer : public Receiver::Consumer {
259*3f982cf4SFabien Sanglard  public:
260*3f982cf4SFabien Sanglard   MOCK_METHOD1(OnFramesReady, void(int next_frame_buffer_size));
261*3f982cf4SFabien Sanglard };
262*3f982cf4SFabien Sanglard 
263*3f982cf4SFabien Sanglard class ReceiverTest : public testing::Test {
264*3f982cf4SFabien Sanglard  public:
ReceiverTest()265*3f982cf4SFabien Sanglard   ReceiverTest()
266*3f982cf4SFabien Sanglard       : clock_(Clock::now()),
267*3f982cf4SFabien Sanglard         task_runner_(&clock_),
268*3f982cf4SFabien Sanglard         env_(&FakeClock::now, &task_runner_),
269*3f982cf4SFabien Sanglard         packet_router_(&env_),
270*3f982cf4SFabien Sanglard         receiver_(&env_,
271*3f982cf4SFabien Sanglard                   &packet_router_,
272*3f982cf4SFabien Sanglard                   {/* .sender_ssrc = */ kSenderSsrc,
273*3f982cf4SFabien Sanglard                    /* .receiver_ssrc = */ kReceiverSsrc,
274*3f982cf4SFabien Sanglard                    /* .rtp_timebase = */ kRtpTimebase,
275*3f982cf4SFabien Sanglard                    /* .channels = */ 2,
276*3f982cf4SFabien Sanglard                    /* .target_playout_delay = */ kTargetPlayoutDelay,
277*3f982cf4SFabien Sanglard                    /* .aes_secret_key = */ kAesKey,
278*3f982cf4SFabien Sanglard                    /* .aes_iv_mask = */ kCastIvMask,
279*3f982cf4SFabien Sanglard                    /* .is_pli_enabled = */ true}),
280*3f982cf4SFabien Sanglard         sender_(&task_runner_, &env_) {
281*3f982cf4SFabien Sanglard     env_.SetSocketSubscriber(&socket_subscriber_);
282*3f982cf4SFabien Sanglard     ON_CALL(env_, SendPacket(_))
__anon38b807a30402(absl::Span<const uint8_t> packet) 283*3f982cf4SFabien Sanglard         .WillByDefault(Invoke([this](absl::Span<const uint8_t> packet) {
284*3f982cf4SFabien Sanglard           task_runner_.PostTaskWithDelay(
285*3f982cf4SFabien Sanglard               [sender = &sender_, copy_of_packet = std::vector<uint8_t>(
286*3f982cf4SFabien Sanglard                                       packet.begin(), packet.end())]() mutable {
287*3f982cf4SFabien Sanglard                 sender->OnPacketFromReceiver(std::move(copy_of_packet));
288*3f982cf4SFabien Sanglard               },
289*3f982cf4SFabien Sanglard               kOneWayNetworkDelay);
290*3f982cf4SFabien Sanglard         }));
291*3f982cf4SFabien Sanglard     receiver_.SetConsumer(&consumer_);
292*3f982cf4SFabien Sanglard   }
293*3f982cf4SFabien Sanglard 
294*3f982cf4SFabien Sanglard   ~ReceiverTest() override = default;
295*3f982cf4SFabien Sanglard 
receiver()296*3f982cf4SFabien Sanglard   Receiver* receiver() { return &receiver_; }
sender()297*3f982cf4SFabien Sanglard   MockSender* sender() { return &sender_; }
consumer()298*3f982cf4SFabien Sanglard   MockConsumer* consumer() { return &consumer_; }
299*3f982cf4SFabien Sanglard 
AdvanceClockAndRunTasks(Clock::duration delta)300*3f982cf4SFabien Sanglard   void AdvanceClockAndRunTasks(Clock::duration delta) { clock_.Advance(delta); }
RunTasksUntilIdle()301*3f982cf4SFabien Sanglard   void RunTasksUntilIdle() { task_runner_.RunTasksUntilIdle(); }
302*3f982cf4SFabien Sanglard 
303*3f982cf4SFabien Sanglard   // Sends the initial Sender Report with lip-sync timing information to
304*3f982cf4SFabien Sanglard   // "unblock" the Receiver, and confirms the Receiver immediately replies with
305*3f982cf4SFabien Sanglard   // a corresponding Receiver Report.
ExchangeInitialReportPackets()306*3f982cf4SFabien Sanglard   void ExchangeInitialReportPackets() {
307*3f982cf4SFabien Sanglard     const Clock::time_point start_time = FakeClock::now();
308*3f982cf4SFabien Sanglard     sender_.SendSenderReport(start_time, SimulatedFrame::GetRtpStartTime());
309*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(
310*3f982cf4SFabien Sanglard         kOneWayNetworkDelay);  // Transmit report to Receiver.
311*3f982cf4SFabien Sanglard     // The Receiver will immediately reply with a Receiver Report.
312*3f982cf4SFabien Sanglard     EXPECT_CALL(sender_,
313*3f982cf4SFabien Sanglard                 OnReceiverCheckpoint(FrameId::leader(), kTargetPlayoutDelay))
314*3f982cf4SFabien Sanglard         .Times(1);
315*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(kOneWayNetworkDelay);  // Transmit reply to Sender.
316*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(&sender_);
317*3f982cf4SFabien Sanglard   }
318*3f982cf4SFabien Sanglard 
319*3f982cf4SFabien Sanglard   // Consume one frame from the Receiver, and verify that it is the same as the
320*3f982cf4SFabien Sanglard   // |sent_frame|. Exception: The |reference_time| is the playout time on the
321*3f982cf4SFabien Sanglard   // Receiver's end, while it refers to the capture time on the Sender's end.
ConsumeAndVerifyFrame(const SimulatedFrame & sent_frame)322*3f982cf4SFabien Sanglard   void ConsumeAndVerifyFrame(const SimulatedFrame& sent_frame) {
323*3f982cf4SFabien Sanglard     SCOPED_TRACE(testing::Message() << "for frame " << sent_frame.frame_id);
324*3f982cf4SFabien Sanglard 
325*3f982cf4SFabien Sanglard     const int payload_size = receiver()->AdvanceToNextFrame();
326*3f982cf4SFabien Sanglard     ASSERT_NE(Receiver::kNoFramesReady, payload_size);
327*3f982cf4SFabien Sanglard     std::vector<uint8_t> buffer(payload_size);
328*3f982cf4SFabien Sanglard     EncodedFrame received_frame =
329*3f982cf4SFabien Sanglard         receiver()->ConsumeNextFrame(absl::Span<uint8_t>(buffer));
330*3f982cf4SFabien Sanglard 
331*3f982cf4SFabien Sanglard     EXPECT_EQ(sent_frame.dependency, received_frame.dependency);
332*3f982cf4SFabien Sanglard     EXPECT_EQ(sent_frame.frame_id, received_frame.frame_id);
333*3f982cf4SFabien Sanglard     EXPECT_EQ(sent_frame.referenced_frame_id,
334*3f982cf4SFabien Sanglard               received_frame.referenced_frame_id);
335*3f982cf4SFabien Sanglard     EXPECT_EQ(sent_frame.rtp_timestamp, received_frame.rtp_timestamp);
336*3f982cf4SFabien Sanglard     EXPECT_EQ(sent_frame.reference_time + kOneWayNetworkDelay +
337*3f982cf4SFabien Sanglard                   SimulatedFrame::GetExpectedPlayoutDelay(sent_frame.frame_id -
338*3f982cf4SFabien Sanglard                                                           FrameId::first()),
339*3f982cf4SFabien Sanglard               received_frame.reference_time);
340*3f982cf4SFabien Sanglard     EXPECT_EQ(sent_frame.new_playout_delay, received_frame.new_playout_delay);
341*3f982cf4SFabien Sanglard     EXPECT_EQ(sent_frame.data, received_frame.data);
342*3f982cf4SFabien Sanglard   }
343*3f982cf4SFabien Sanglard 
344*3f982cf4SFabien Sanglard   // Consume zero or more frames from the Receiver, verifying that they are the
345*3f982cf4SFabien Sanglard   // same as the SimulatedFrame that was sent.
ConsumeAndVerifyFrames(int first,int last,Clock::time_point start_time)346*3f982cf4SFabien Sanglard   void ConsumeAndVerifyFrames(int first,
347*3f982cf4SFabien Sanglard                               int last,
348*3f982cf4SFabien Sanglard                               Clock::time_point start_time) {
349*3f982cf4SFabien Sanglard     for (int i = first; i <= last; ++i) {
350*3f982cf4SFabien Sanglard       ConsumeAndVerifyFrame(SimulatedFrame(start_time, i));
351*3f982cf4SFabien Sanglard     }
352*3f982cf4SFabien Sanglard   }
353*3f982cf4SFabien Sanglard 
354*3f982cf4SFabien Sanglard  private:
355*3f982cf4SFabien Sanglard   FakeClock clock_;
356*3f982cf4SFabien Sanglard   FakeTaskRunner task_runner_;
357*3f982cf4SFabien Sanglard   testing::NiceMock<MockEnvironment> env_;
358*3f982cf4SFabien Sanglard   ReceiverPacketRouter packet_router_;
359*3f982cf4SFabien Sanglard   Receiver receiver_;
360*3f982cf4SFabien Sanglard   testing::NiceMock<MockSender> sender_;
361*3f982cf4SFabien Sanglard   testing::NiceMock<MockConsumer> consumer_;
362*3f982cf4SFabien Sanglard   SimpleSubscriber socket_subscriber_;
363*3f982cf4SFabien Sanglard };
364*3f982cf4SFabien Sanglard 
365*3f982cf4SFabien Sanglard // Tests that the Receiver processes RTCP packets correctly and sends RTCP
366*3f982cf4SFabien Sanglard // reports at regular intervals.
TEST_F(ReceiverTest,ReceivesAndSendsRtcpPackets)367*3f982cf4SFabien Sanglard TEST_F(ReceiverTest, ReceivesAndSendsRtcpPackets) {
368*3f982cf4SFabien Sanglard   // Sender-side expectations, after the Receiver has processed the first Sender
369*3f982cf4SFabien Sanglard   // Report.
370*3f982cf4SFabien Sanglard   Clock::time_point receiver_reference_time{};
371*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverReferenceTimeAdvanced(_))
372*3f982cf4SFabien Sanglard       .WillOnce(SaveArg<0>(&receiver_reference_time));
373*3f982cf4SFabien Sanglard   RtcpReportBlock receiver_report;
374*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverReport(_))
375*3f982cf4SFabien Sanglard       .WillOnce(SaveArg<0>(&receiver_report));
376*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(),
377*3f982cf4SFabien Sanglard               OnReceiverCheckpoint(FrameId::leader(), kTargetPlayoutDelay))
378*3f982cf4SFabien Sanglard       .Times(1);
379*3f982cf4SFabien Sanglard 
380*3f982cf4SFabien Sanglard   // Have the MockSender send a Sender Report with lip-sync timing information.
381*3f982cf4SFabien Sanglard   const Clock::time_point sender_reference_time = FakeClock::now();
382*3f982cf4SFabien Sanglard   const RtpTimeTicks sender_rtp_timestamp =
383*3f982cf4SFabien Sanglard       RtpTimeTicks::FromTimeSinceOrigin(seconds(1), kRtpTimebase);
384*3f982cf4SFabien Sanglard   const StatusReportId sender_report_id =
385*3f982cf4SFabien Sanglard       sender()->SendSenderReport(sender_reference_time, sender_rtp_timestamp);
386*3f982cf4SFabien Sanglard 
387*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
388*3f982cf4SFabien Sanglard 
389*3f982cf4SFabien Sanglard   // Expect the MockSender got back a Receiver Report that includes its SSRC and
390*3f982cf4SFabien Sanglard   // the last Sender Report ID.
391*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
392*3f982cf4SFabien Sanglard   EXPECT_EQ(kSenderSsrc, receiver_report.ssrc);
393*3f982cf4SFabien Sanglard   EXPECT_EQ(sender_report_id, receiver_report.last_status_report_id);
394*3f982cf4SFabien Sanglard 
395*3f982cf4SFabien Sanglard   // Confirm the clock offset math: Since the Receiver and MockSender share the
396*3f982cf4SFabien Sanglard   // same underlying FakeClock, the Receiver should be ahead of the Sender,
397*3f982cf4SFabien Sanglard   // which reflects the simulated one-way network packet travel time (of the
398*3f982cf4SFabien Sanglard   // Sender Report).
399*3f982cf4SFabien Sanglard   //
400*3f982cf4SFabien Sanglard   // Note: The offset can be affected by the lossy conversion when going to and
401*3f982cf4SFabien Sanglard   // from the wire-format NtpTimestamps. See the unit tests in
402*3f982cf4SFabien Sanglard   // ntp_time_unittest.cc for further discussion.
403*3f982cf4SFabien Sanglard   constexpr auto kAllowedNtpRoundingError = microseconds(2);
404*3f982cf4SFabien Sanglard   EXPECT_NEAR(
405*3f982cf4SFabien Sanglard       to_microseconds(kOneWayNetworkDelay).count(),
406*3f982cf4SFabien Sanglard       to_microseconds(receiver_reference_time - sender_reference_time).count(),
407*3f982cf4SFabien Sanglard       kAllowedNtpRoundingError.count());
408*3f982cf4SFabien Sanglard 
409*3f982cf4SFabien Sanglard   // Without the Sender doing anything, the Receiver should continue providing
410*3f982cf4SFabien Sanglard   // RTCP reports at regular intervals. Simulate three intervals of time,
411*3f982cf4SFabien Sanglard   // verifying that the Receiver did send reports.
412*3f982cf4SFabien Sanglard   Clock::time_point last_receiver_reference_time = receiver_reference_time;
413*3f982cf4SFabien Sanglard   for (int i = 0; i < 3; ++i) {
414*3f982cf4SFabien Sanglard     receiver_reference_time = Clock::time_point();
415*3f982cf4SFabien Sanglard     EXPECT_CALL(*sender(), OnReceiverReferenceTimeAdvanced(_))
416*3f982cf4SFabien Sanglard         .WillRepeatedly(SaveArg<0>(&receiver_reference_time));
417*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(kRtcpReportInterval);
418*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(sender());
419*3f982cf4SFabien Sanglard     EXPECT_LT(last_receiver_reference_time, receiver_reference_time);
420*3f982cf4SFabien Sanglard     last_receiver_reference_time = receiver_reference_time;
421*3f982cf4SFabien Sanglard   }
422*3f982cf4SFabien Sanglard }
423*3f982cf4SFabien Sanglard 
424*3f982cf4SFabien Sanglard // Tests that the Receiver processes RTP packets, which might arrive in-order or
425*3f982cf4SFabien Sanglard // out of order, but such that each frame is completely received in-order. Also,
426*3f982cf4SFabien Sanglard // confirms that target playout delay changes are processed/applied correctly.
TEST_F(ReceiverTest,ReceivesFramesInOrder)427*3f982cf4SFabien Sanglard TEST_F(ReceiverTest, ReceivesFramesInOrder) {
428*3f982cf4SFabien Sanglard   const Clock::time_point start_time = FakeClock::now();
429*3f982cf4SFabien Sanglard   ExchangeInitialReportPackets();
430*3f982cf4SFabien Sanglard 
431*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(10);
432*3f982cf4SFabien Sanglard   for (int i = 0; i <= 9; ++i) {
433*3f982cf4SFabien Sanglard     EXPECT_CALL(*sender(), OnReceiverCheckpoint(
434*3f982cf4SFabien Sanglard                                FrameId::first() + i,
435*3f982cf4SFabien Sanglard                                SimulatedFrame::GetExpectedPlayoutDelay(i)))
436*3f982cf4SFabien Sanglard         .Times(1);
437*3f982cf4SFabien Sanglard     EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);
438*3f982cf4SFabien Sanglard 
439*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
440*3f982cf4SFabien Sanglard     // Send the frame's packets in-order half the time, out-of-order the other
441*3f982cf4SFabien Sanglard     // half.
442*3f982cf4SFabien Sanglard     const int permutation = (i % 2) ? i : 0;
443*3f982cf4SFabien Sanglard     sender()->SendRtpPackets(sender()->GetAllPacketIds(permutation));
444*3f982cf4SFabien Sanglard 
445*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
446*3f982cf4SFabien Sanglard 
447*3f982cf4SFabien Sanglard     // The Receiver should immediately ACK once it has received all the RTP
448*3f982cf4SFabien Sanglard     // packets to complete the frame.
449*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(sender());
450*3f982cf4SFabien Sanglard 
451*3f982cf4SFabien Sanglard     // Advance to next frame transmission time.
452*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration -
453*3f982cf4SFabien Sanglard                             kRoundTripNetworkDelay);
454*3f982cf4SFabien Sanglard   }
455*3f982cf4SFabien Sanglard 
456*3f982cf4SFabien Sanglard   // When the Receiver has all of the frames and they are complete, it should
457*3f982cf4SFabien Sanglard   // send out a low-frequency periodic RTCP "ping." Verify that there is one and
458*3f982cf4SFabien Sanglard   // only one "ping" sent when the clock moves forward by one default report
459*3f982cf4SFabien Sanglard   // interval during a period of inactivity.
460*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::first() + 9,
461*3f982cf4SFabien Sanglard                                               kTargetPlayoutDelayChange))
462*3f982cf4SFabien Sanglard       .Times(1);
463*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kRtcpReportInterval);
464*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
465*3f982cf4SFabien Sanglard 
466*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrames(0, 9, start_time);
467*3f982cf4SFabien Sanglard   EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
468*3f982cf4SFabien Sanglard }
469*3f982cf4SFabien Sanglard 
470*3f982cf4SFabien Sanglard // Tests that the Receiver processes RTP packets, can receive frames out of
471*3f982cf4SFabien Sanglard // order, and issues the appropriate ACK/NACK feedback to the Sender as it
472*3f982cf4SFabien Sanglard // realizes what it has and what it's missing.
TEST_F(ReceiverTest,ReceivesFramesOutOfOrder)473*3f982cf4SFabien Sanglard TEST_F(ReceiverTest, ReceivesFramesOutOfOrder) {
474*3f982cf4SFabien Sanglard   const Clock::time_point start_time = FakeClock::now();
475*3f982cf4SFabien Sanglard   ExchangeInitialReportPackets();
476*3f982cf4SFabien Sanglard 
477*3f982cf4SFabien Sanglard   constexpr static int kOutOfOrderFrames[] = {3, 4, 2, 0, 1};
478*3f982cf4SFabien Sanglard   for (int i : kOutOfOrderFrames) {
479*3f982cf4SFabien Sanglard     // Expectations are different as each frame is sent and received.
480*3f982cf4SFabien Sanglard     switch (i) {
481*3f982cf4SFabien Sanglard       case 3: {
482*3f982cf4SFabien Sanglard         // Note that frame 4 will not yet be known to the Receiver, and so it
483*3f982cf4SFabien Sanglard         // should not be mentioned in any of the feedback for this case.
484*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::leader(),
485*3f982cf4SFabien Sanglard                                                     kTargetPlayoutDelay))
486*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
487*3f982cf4SFabien Sanglard         EXPECT_CALL(
488*3f982cf4SFabien Sanglard             *sender(),
489*3f982cf4SFabien Sanglard             OnReceiverHasFrames(std::vector<FrameId>({FrameId::first() + 3})))
490*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
491*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(),
492*3f982cf4SFabien Sanglard                     OnReceiverIsMissingPackets(std::vector<PacketNack>({
493*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first(), kAllPacketsLost},
494*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first() + 1, kAllPacketsLost},
495*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first() + 2, kAllPacketsLost},
496*3f982cf4SFabien Sanglard                     })))
497*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
498*3f982cf4SFabien Sanglard         EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
499*3f982cf4SFabien Sanglard         break;
500*3f982cf4SFabien Sanglard       }
501*3f982cf4SFabien Sanglard 
502*3f982cf4SFabien Sanglard       case 4: {
503*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::leader(),
504*3f982cf4SFabien Sanglard                                                     kTargetPlayoutDelay))
505*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
506*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(),
507*3f982cf4SFabien Sanglard                     OnReceiverHasFrames(std::vector<FrameId>(
508*3f982cf4SFabien Sanglard                         {FrameId::first() + 3, FrameId::first() + 4})))
509*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
510*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(),
511*3f982cf4SFabien Sanglard                     OnReceiverIsMissingPackets(std::vector<PacketNack>({
512*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first(), kAllPacketsLost},
513*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first() + 1, kAllPacketsLost},
514*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first() + 2, kAllPacketsLost},
515*3f982cf4SFabien Sanglard                     })))
516*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
517*3f982cf4SFabien Sanglard         EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
518*3f982cf4SFabien Sanglard         break;
519*3f982cf4SFabien Sanglard       }
520*3f982cf4SFabien Sanglard 
521*3f982cf4SFabien Sanglard       case 2: {
522*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::leader(),
523*3f982cf4SFabien Sanglard                                                     kTargetPlayoutDelay))
524*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
525*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverHasFrames(std::vector<FrameId>(
526*3f982cf4SFabien Sanglard                                    {FrameId::first() + 2, FrameId::first() + 3,
527*3f982cf4SFabien Sanglard                                     FrameId::first() + 4})))
528*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
529*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(),
530*3f982cf4SFabien Sanglard                     OnReceiverIsMissingPackets(std::vector<PacketNack>({
531*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first(), kAllPacketsLost},
532*3f982cf4SFabien Sanglard                         PacketNack{FrameId::first() + 1, kAllPacketsLost},
533*3f982cf4SFabien Sanglard                     })))
534*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
535*3f982cf4SFabien Sanglard         EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
536*3f982cf4SFabien Sanglard         break;
537*3f982cf4SFabien Sanglard       }
538*3f982cf4SFabien Sanglard 
539*3f982cf4SFabien Sanglard       case 0: {
540*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(),
541*3f982cf4SFabien Sanglard                     OnReceiverCheckpoint(FrameId::first(), kTargetPlayoutDelay))
542*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
543*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverHasFrames(std::vector<FrameId>(
544*3f982cf4SFabien Sanglard                                    {FrameId::first() + 2, FrameId::first() + 3,
545*3f982cf4SFabien Sanglard                                     FrameId::first() + 4})))
546*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
547*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(),
548*3f982cf4SFabien Sanglard                     OnReceiverIsMissingPackets(std::vector<PacketNack>(
549*3f982cf4SFabien Sanglard                         {PacketNack{FrameId::first() + 1, kAllPacketsLost}})))
550*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
551*3f982cf4SFabien Sanglard         EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
552*3f982cf4SFabien Sanglard         break;
553*3f982cf4SFabien Sanglard       }
554*3f982cf4SFabien Sanglard 
555*3f982cf4SFabien Sanglard       case 1: {
556*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::first() + 4,
557*3f982cf4SFabien Sanglard                                                     kTargetPlayoutDelay))
558*3f982cf4SFabien Sanglard             .Times(AtLeast(1));
559*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverHasFrames(_)).Times(0);
560*3f982cf4SFabien Sanglard         EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);
561*3f982cf4SFabien Sanglard         EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
562*3f982cf4SFabien Sanglard         break;
563*3f982cf4SFabien Sanglard       }
564*3f982cf4SFabien Sanglard 
565*3f982cf4SFabien Sanglard       default:
566*3f982cf4SFabien Sanglard         OSP_NOTREACHED();
567*3f982cf4SFabien Sanglard     }
568*3f982cf4SFabien Sanglard 
569*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
570*3f982cf4SFabien Sanglard     sender()->SendRtpPackets(sender()->GetAllPacketIds(i));
571*3f982cf4SFabien Sanglard 
572*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
573*3f982cf4SFabien Sanglard 
574*3f982cf4SFabien Sanglard     // While there are known incomplete frames, the Receiver should send RTCP
575*3f982cf4SFabien Sanglard     // packets more frequently than the default "ping" interval. Thus, advancing
576*3f982cf4SFabien Sanglard     // the clock by this much should result in several feedback reports
577*3f982cf4SFabien Sanglard     // transmitted to the Sender.
578*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(kRtcpReportInterval - kRoundTripNetworkDelay);
579*3f982cf4SFabien Sanglard 
580*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(sender());
581*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(consumer());
582*3f982cf4SFabien Sanglard   }
583*3f982cf4SFabien Sanglard 
584*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrames(0, 4, start_time);
585*3f982cf4SFabien Sanglard   EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
586*3f982cf4SFabien Sanglard }
587*3f982cf4SFabien Sanglard 
588*3f982cf4SFabien Sanglard // Tests that the Receiver will respond to a key frame request from its client
589*3f982cf4SFabien Sanglard // by sending a Picture Loss Indicator (PLI) to the Sender, and then will
590*3f982cf4SFabien Sanglard // automatically stop sending the PLI once a key frame has been received.
TEST_F(ReceiverTest,RequestsKeyFrameToRectifyPictureLoss)591*3f982cf4SFabien Sanglard TEST_F(ReceiverTest, RequestsKeyFrameToRectifyPictureLoss) {
592*3f982cf4SFabien Sanglard   const Clock::time_point start_time = FakeClock::now();
593*3f982cf4SFabien Sanglard   ExchangeInitialReportPackets();
594*3f982cf4SFabien Sanglard 
595*3f982cf4SFabien Sanglard   // Send and Receive three frames in-order, normally.
596*3f982cf4SFabien Sanglard   for (int i = 0; i <= 2; ++i) {
597*3f982cf4SFabien Sanglard     EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
598*3f982cf4SFabien Sanglard     EXPECT_CALL(*sender(),
599*3f982cf4SFabien Sanglard                 OnReceiverCheckpoint(FrameId::first() + i, kTargetPlayoutDelay))
600*3f982cf4SFabien Sanglard         .Times(1);
601*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
602*3f982cf4SFabien Sanglard     sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
603*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
604*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(sender());
605*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(consumer());
606*3f982cf4SFabien Sanglard     // Advance to next frame transmission time.
607*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration -
608*3f982cf4SFabien Sanglard                             kRoundTripNetworkDelay);
609*3f982cf4SFabien Sanglard   }
610*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrames(0, 2, start_time);
611*3f982cf4SFabien Sanglard 
612*3f982cf4SFabien Sanglard   // Simulate the Consumer requesting a key frame after picture loss (e.g., a
613*3f982cf4SFabien Sanglard   // decoder failure). Ensure the Sender is immediately notified.
614*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(1);
615*3f982cf4SFabien Sanglard   receiver()->RequestKeyFrame();
616*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kOneWayNetworkDelay);  // Propagate request to Sender.
617*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
618*3f982cf4SFabien Sanglard 
619*3f982cf4SFabien Sanglard   // The Sender sends another frame that is not a key frame and, upon receipt,
620*3f982cf4SFabien Sanglard   // the Receiver should repeat its "cry" for a key frame.
621*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
622*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(),
623*3f982cf4SFabien Sanglard               OnReceiverCheckpoint(FrameId::first() + 3, kTargetPlayoutDelay))
624*3f982cf4SFabien Sanglard       .Times(1);
625*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(AtLeast(1));
626*3f982cf4SFabien Sanglard   sender()->SetFrameBeingSent(SimulatedFrame(start_time, 3));
627*3f982cf4SFabien Sanglard   sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
628*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration - kOneWayNetworkDelay);
629*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
630*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
631*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrames(3, 3, start_time);
632*3f982cf4SFabien Sanglard 
633*3f982cf4SFabien Sanglard   // Finally, the Sender responds to the PLI condition by sending a key frame.
634*3f982cf4SFabien Sanglard   // Confirm the Receiver has stopped indicating picture loss after having
635*3f982cf4SFabien Sanglard   // received the key frame.
636*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
637*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(),
638*3f982cf4SFabien Sanglard               OnReceiverCheckpoint(FrameId::first() + 4, kTargetPlayoutDelay))
639*3f982cf4SFabien Sanglard       .Times(1);
640*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(0);
641*3f982cf4SFabien Sanglard   SimulatedFrame key_frame(start_time, 4);
642*3f982cf4SFabien Sanglard   key_frame.dependency = EncodedFrame::KEY_FRAME;
643*3f982cf4SFabien Sanglard   key_frame.referenced_frame_id = key_frame.frame_id;
644*3f982cf4SFabien Sanglard   sender()->SetFrameBeingSent(key_frame);
645*3f982cf4SFabien Sanglard   sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
646*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
647*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
648*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
649*3f982cf4SFabien Sanglard 
650*3f982cf4SFabien Sanglard   // The client has not yet consumed the key frame, so any calls to
651*3f982cf4SFabien Sanglard   // RequestKeyFrame() should not set the PLI condition again.
652*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(0);
653*3f982cf4SFabien Sanglard   receiver()->RequestKeyFrame();
654*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kOneWayNetworkDelay);
655*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
656*3f982cf4SFabien Sanglard 
657*3f982cf4SFabien Sanglard   // After consuming the requested key frame, the client should be able to set
658*3f982cf4SFabien Sanglard   // the PLI condition again with another RequestKeyFrame() call.
659*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrame(key_frame);
660*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(1);
661*3f982cf4SFabien Sanglard   receiver()->RequestKeyFrame();
662*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kOneWayNetworkDelay);
663*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
664*3f982cf4SFabien Sanglard }
665*3f982cf4SFabien Sanglard 
TEST_F(ReceiverTest,PLICanBeDisabled)666*3f982cf4SFabien Sanglard TEST_F(ReceiverTest, PLICanBeDisabled) {
667*3f982cf4SFabien Sanglard   receiver()->SetPliEnabledForTesting(false);
668*3f982cf4SFabien Sanglard 
669*3f982cf4SFabien Sanglard #if OSP_DCHECK_IS_ON()
670*3f982cf4SFabien Sanglard   EXPECT_DEATH(receiver()->RequestKeyFrame(), ".*PLI is not enabled.*");
671*3f982cf4SFabien Sanglard #else
672*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverIndicatesPictureLoss()).Times(0);
673*3f982cf4SFabien Sanglard   receiver()->RequestKeyFrame();
674*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kOneWayNetworkDelay);
675*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
676*3f982cf4SFabien Sanglard #endif
677*3f982cf4SFabien Sanglard }
678*3f982cf4SFabien Sanglard 
679*3f982cf4SFabien Sanglard // Tests that the Receiver will start dropping packets once its frame queue is
680*3f982cf4SFabien Sanglard // full (i.e., when the consumer is not pulling them out of the queue). Since
681*3f982cf4SFabien Sanglard // the Receiver will stop ACK'ing frames, the Sender will become stalled.
TEST_F(ReceiverTest,EatsItsFill)682*3f982cf4SFabien Sanglard TEST_F(ReceiverTest, EatsItsFill) {
683*3f982cf4SFabien Sanglard   const Clock::time_point start_time = FakeClock::now();
684*3f982cf4SFabien Sanglard   ExchangeInitialReportPackets();
685*3f982cf4SFabien Sanglard 
686*3f982cf4SFabien Sanglard   // Send and Receive the maximum possible number of frames in-order, normally.
687*3f982cf4SFabien Sanglard   for (int i = 0; i < kMaxUnackedFrames; ++i) {
688*3f982cf4SFabien Sanglard     EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
689*3f982cf4SFabien Sanglard     EXPECT_CALL(*sender(), OnReceiverCheckpoint(
690*3f982cf4SFabien Sanglard                                FrameId::first() + i,
691*3f982cf4SFabien Sanglard                                SimulatedFrame::GetExpectedPlayoutDelay(i)))
692*3f982cf4SFabien Sanglard         .Times(1);
693*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(SimulatedFrame(start_time, i));
694*3f982cf4SFabien Sanglard     sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
695*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
696*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(sender());
697*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(consumer());
698*3f982cf4SFabien Sanglard   }
699*3f982cf4SFabien Sanglard 
700*3f982cf4SFabien Sanglard   // Sending one more frame should be ignored. Over and over. None of the
701*3f982cf4SFabien Sanglard   // feedback reports from the Receiver should indicate it is collecting packets
702*3f982cf4SFabien Sanglard   // for future frames.
703*3f982cf4SFabien Sanglard   int ignored_frame = kMaxUnackedFrames;
704*3f982cf4SFabien Sanglard   for (int i = 0; i < 5; ++i) {
705*3f982cf4SFabien Sanglard     EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
706*3f982cf4SFabien Sanglard     EXPECT_CALL(*sender(),
707*3f982cf4SFabien Sanglard                 OnReceiverCheckpoint(FrameId::first() + (ignored_frame - 1),
708*3f982cf4SFabien Sanglard                                      kTargetPlayoutDelayChange))
709*3f982cf4SFabien Sanglard         .Times(AtLeast(0));
710*3f982cf4SFabien Sanglard     EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);
711*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(SimulatedFrame(start_time, ignored_frame));
712*3f982cf4SFabien Sanglard     sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
713*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
714*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(sender());
715*3f982cf4SFabien Sanglard     testing::Mock::VerifyAndClearExpectations(consumer());
716*3f982cf4SFabien Sanglard   }
717*3f982cf4SFabien Sanglard 
718*3f982cf4SFabien Sanglard   // Consume only one frame, and confirm the Receiver allows only one frame more
719*3f982cf4SFabien Sanglard   // to be received.
720*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrames(0, 0, start_time);
721*3f982cf4SFabien Sanglard   int no_longer_ignored_frame = ignored_frame;
722*3f982cf4SFabien Sanglard   ++ignored_frame;
723*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(AtLeast(1));
724*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(),
725*3f982cf4SFabien Sanglard               OnReceiverCheckpoint(FrameId::first() + no_longer_ignored_frame,
726*3f982cf4SFabien Sanglard                                    kTargetPlayoutDelayChange))
727*3f982cf4SFabien Sanglard       .Times(AtLeast(1));
728*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverIsMissingPackets(_)).Times(0);
729*3f982cf4SFabien Sanglard   // This frame should be received successfully.
730*3f982cf4SFabien Sanglard   sender()->SetFrameBeingSent(
731*3f982cf4SFabien Sanglard       SimulatedFrame(start_time, no_longer_ignored_frame));
732*3f982cf4SFabien Sanglard   sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
733*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
734*3f982cf4SFabien Sanglard   // This second frame should be ignored, however.
735*3f982cf4SFabien Sanglard   sender()->SetFrameBeingSent(SimulatedFrame(start_time, ignored_frame));
736*3f982cf4SFabien Sanglard   sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
737*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
738*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
739*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
740*3f982cf4SFabien Sanglard }
741*3f982cf4SFabien Sanglard 
742*3f982cf4SFabien Sanglard // Tests that incomplete frames that would be played-out too late are dropped,
743*3f982cf4SFabien Sanglard // but only as inter-frame data dependency requirements permit, and only if no
744*3f982cf4SFabien Sanglard // target playout delay change information would have been missed.
TEST_F(ReceiverTest,DropsLateFrames)745*3f982cf4SFabien Sanglard TEST_F(ReceiverTest, DropsLateFrames) {
746*3f982cf4SFabien Sanglard   const Clock::time_point start_time = FakeClock::now();
747*3f982cf4SFabien Sanglard   ExchangeInitialReportPackets();
748*3f982cf4SFabien Sanglard 
749*3f982cf4SFabien Sanglard   // Before any packets have been sent/received, the Receiver should indicate no
750*3f982cf4SFabien Sanglard   // frames are ready.
751*3f982cf4SFabien Sanglard   EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
752*3f982cf4SFabien Sanglard 
753*3f982cf4SFabien Sanglard   // Set a ridiculously-large estimated player processing time so that the logic
754*3f982cf4SFabien Sanglard   // thinks every frame going to play out too late.
755*3f982cf4SFabien Sanglard   receiver()->SetPlayerProcessingTime(seconds(3));
756*3f982cf4SFabien Sanglard 
757*3f982cf4SFabien Sanglard   // In this test there are eight frames total:
758*3f982cf4SFabien Sanglard   //   - Frame 0: Key frame.
759*3f982cf4SFabien Sanglard   //   - Frames 1-4: Non-key frames.
760*3f982cf4SFabien Sanglard   //   - Frame 5: Non-key frame that contains a target playout delay change.
761*3f982cf4SFabien Sanglard   //   - Frame 6: Key frame.
762*3f982cf4SFabien Sanglard   //   - Frame 7: Non-key frame.
763*3f982cf4SFabien Sanglard   ASSERT_EQ(SimulatedFrame::kPlayoutChangeAtFrame, 5);
764*3f982cf4SFabien Sanglard   SimulatedFrame frames[8] = {{start_time, 0}, {start_time, 1}, {start_time, 2},
765*3f982cf4SFabien Sanglard                               {start_time, 3}, {start_time, 4}, {start_time, 5},
766*3f982cf4SFabien Sanglard                               {start_time, 6}, {start_time, 7}};
767*3f982cf4SFabien Sanglard   frames[6].dependency = EncodedFrame::KEY_FRAME;
768*3f982cf4SFabien Sanglard   frames[6].referenced_frame_id = frames[6].frame_id;
769*3f982cf4SFabien Sanglard 
770*3f982cf4SFabien Sanglard   // Send just packet 1 (NOT packet 0) of all the frames. The Receiver should
771*3f982cf4SFabien Sanglard   // never notify the consumer via the callback, nor report that any frames are
772*3f982cf4SFabien Sanglard   // ready, because none of the frames have been completely received.
773*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
774*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
775*3f982cf4SFabien Sanglard   for (int i = 0; i <= 7; ++i) {
776*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(frames[i]);
777*3f982cf4SFabien Sanglard     // Assumption: There are at least three packets in each frame, else the test
778*3f982cf4SFabien Sanglard     // is not exercising the logic meaningfully.
779*3f982cf4SFabien Sanglard     ASSERT_LE(size_t{3}, sender()->GetAllPacketIds(0).size());
780*3f982cf4SFabien Sanglard     sender()->SendRtpPackets({FramePacketId{1}});
781*3f982cf4SFabien Sanglard     AdvanceClockAndRunTasks(SimulatedFrame::kFrameDuration);
782*3f982cf4SFabien Sanglard   }
783*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
784*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
785*3f982cf4SFabien Sanglard   EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
786*3f982cf4SFabien Sanglard 
787*3f982cf4SFabien Sanglard   // Send all the packets of Frame 6 (the second key frame) and Frame 7. The
788*3f982cf4SFabien Sanglard   // Receiver still cannot drop any frames because it has not seen packet 0 of
789*3f982cf4SFabien Sanglard   // every prior frame. In other words, it cannot ignore any possibility of a
790*3f982cf4SFabien Sanglard   // target playout delay change from the Sender.
791*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
792*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
793*3f982cf4SFabien Sanglard   for (int i = 6; i <= 7; ++i) {
794*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(frames[i]);
795*3f982cf4SFabien Sanglard     sender()->SendRtpPackets(sender()->GetAllPacketIds(0));
796*3f982cf4SFabien Sanglard   }
797*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
798*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
799*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
800*3f982cf4SFabien Sanglard   EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
801*3f982cf4SFabien Sanglard 
802*3f982cf4SFabien Sanglard   // Send packet 0 for all but Frame 5, which contains a target playout delay
803*3f982cf4SFabien Sanglard   // change. All but the last two frames will still be incomplete. The Receiver
804*3f982cf4SFabien Sanglard   // still cannot drop any frames because it doesn't know whether Frame 5 had a
805*3f982cf4SFabien Sanglard   // target playout delay change.
806*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
807*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
808*3f982cf4SFabien Sanglard   for (int i = 0; i <= 7; ++i) {
809*3f982cf4SFabien Sanglard     if (i == 5) {
810*3f982cf4SFabien Sanglard       continue;
811*3f982cf4SFabien Sanglard     }
812*3f982cf4SFabien Sanglard     sender()->SetFrameBeingSent(frames[i]);
813*3f982cf4SFabien Sanglard     sender()->SendRtpPackets({FramePacketId{0}});
814*3f982cf4SFabien Sanglard   }
815*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
816*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
817*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
818*3f982cf4SFabien Sanglard   EXPECT_EQ(Receiver::kNoFramesReady, receiver()->AdvanceToNextFrame());
819*3f982cf4SFabien Sanglard 
820*3f982cf4SFabien Sanglard   // Finally, send packet 0 for Frame 5. Now, the Receiver will drop every frame
821*3f982cf4SFabien Sanglard   // before the completely-received second key frame, as they are all still
822*3f982cf4SFabien Sanglard   // incomplete and will play-out too late. When it drops the frames, it will
823*3f982cf4SFabien Sanglard   // notify the sender of the new checkpoint so that it stops trying to
824*3f982cf4SFabien Sanglard   // re-transmit the dropped frames.
825*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
826*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverCheckpoint(FrameId::first() + 7,
827*3f982cf4SFabien Sanglard                                               kTargetPlayoutDelayChange))
828*3f982cf4SFabien Sanglard       .Times(1);
829*3f982cf4SFabien Sanglard   sender()->SetFrameBeingSent(frames[5]);
830*3f982cf4SFabien Sanglard   sender()->SendRtpPackets({FramePacketId{0}});
831*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kRoundTripNetworkDelay);
832*3f982cf4SFabien Sanglard   // Note: Consuming Frame 6 will trigger the checkpoint advancement, since the
833*3f982cf4SFabien Sanglard   // call to AdvanceToNextFrame() contains the frame skipping/dropping logic.
834*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrame(frames[6]);
835*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
836*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
837*3f982cf4SFabien Sanglard 
838*3f982cf4SFabien Sanglard   // After consuming Frame 6, the Receiver knows Frame 7 is also available and
839*3f982cf4SFabien Sanglard   // should have scheduled an immediate task to notify the Consumer of this.
840*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(Gt(0))).Times(1);
841*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kOneWayNetworkDelay);
842*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
843*3f982cf4SFabien Sanglard 
844*3f982cf4SFabien Sanglard   // Now consume Frame 7. This shouldn't trigger any further checkpoint
845*3f982cf4SFabien Sanglard   // advancement.
846*3f982cf4SFabien Sanglard   EXPECT_CALL(*consumer(), OnFramesReady(_)).Times(0);
847*3f982cf4SFabien Sanglard   EXPECT_CALL(*sender(), OnReceiverCheckpoint(_, _)).Times(0);
848*3f982cf4SFabien Sanglard   ConsumeAndVerifyFrame(frames[7]);
849*3f982cf4SFabien Sanglard   AdvanceClockAndRunTasks(kOneWayNetworkDelay);
850*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(consumer());
851*3f982cf4SFabien Sanglard   testing::Mock::VerifyAndClearExpectations(sender());
852*3f982cf4SFabien Sanglard }
853*3f982cf4SFabien Sanglard 
854*3f982cf4SFabien Sanglard }  // namespace
855*3f982cf4SFabien Sanglard }  // namespace cast
856*3f982cf4SFabien Sanglard }  // namespace openscreen
857