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