1 // Copyright 2020 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/sender.h"
6 
7 #include <stdint.h>
8 
9 #include <algorithm>
10 #include <array>
11 #include <chrono>
12 #include <limits>
13 #include <map>
14 #include <set>
15 #include <utility>
16 #include <vector>
17 
18 #include "absl/types/optional.h"
19 #include "absl/types/span.h"
20 #include "cast/streaming/compound_rtcp_builder.h"
21 #include "cast/streaming/constants.h"
22 #include "cast/streaming/encoded_frame.h"
23 #include "cast/streaming/frame_collector.h"
24 #include "cast/streaming/frame_crypto.h"
25 #include "cast/streaming/frame_id.h"
26 #include "cast/streaming/mock_environment.h"
27 #include "cast/streaming/packet_util.h"
28 #include "cast/streaming/rtcp_session.h"
29 #include "cast/streaming/rtp_defines.h"
30 #include "cast/streaming/rtp_packet_parser.h"
31 #include "cast/streaming/sender_packet_router.h"
32 #include "cast/streaming/sender_report_parser.h"
33 #include "cast/streaming/session_config.h"
34 #include "cast/streaming/ssrc.h"
35 #include "cast/streaming/testing/simple_socket_subscriber.h"
36 #include "gmock/gmock.h"
37 #include "gtest/gtest.h"
38 #include "platform/test/fake_clock.h"
39 #include "platform/test/fake_task_runner.h"
40 #include "util/alarm.h"
41 #include "util/chrono_helpers.h"
42 #include "util/yet_another_bit_vector.h"
43 
44 using testing::_;
45 using testing::AtLeast;
46 using testing::Invoke;
47 using testing::InvokeWithoutArgs;
48 using testing::Mock;
49 using testing::NiceMock;
50 using testing::Return;
51 using testing::Sequence;
52 
53 namespace openscreen {
54 namespace cast {
55 namespace {
56 
57 // Sender configuration.
58 constexpr Ssrc kSenderSsrc = 1;
59 constexpr Ssrc kReceiverSsrc = 2;
60 constexpr int kRtpTimebase = 48000;
61 constexpr milliseconds kTargetPlayoutDelay{400};
62 constexpr auto kAesKey =
63     std::array<uint8_t, 16>{{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
64                              0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}};
65 constexpr auto kCastIvMask =
66     std::array<uint8_t, 16>{{0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
67                              0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00}};
68 constexpr RtpPayloadType kRtpPayloadType = RtpPayloadType::kVideoVp8;
69 
70 // The number of RTP ticks advanced per frame, for 100 FPS media.
71 constexpr int kRtpTicksPerFrame = kRtpTimebase / 100;
72 
73 // The number of milliseconds advanced per frame, for 100 FPS media.
74 constexpr milliseconds kFrameDuration{1000 / 100};
75 static_assert(kFrameDuration < (kTargetPlayoutDelay / 10),
76               "Kickstart test assumes frame duration is far less than the "
77               "playout delay.");
78 
79 // An Encoded frame that also holds onto its own copy of data.
80 struct EncodedFrameWithBuffer : public EncodedFrame {
81   // |EncodedFrame::data| always points inside buffer.begin()...buffer.end().
82   std::vector<uint8_t> buffer;
83 };
84 
85 // SenderPacketRouter configuration for these tests.
86 constexpr int kNumPacketsPerBurst = 20;
87 constexpr milliseconds kBurstInterval{10};
88 
89 // An arbitrary value, subtracted from "now," to specify the reference_time on
90 // frames that are about to be enqueued. This simulates that capture+encode
91 // happened in the past, before Sender::EnqueueFrame() is called.
92 constexpr milliseconds kCaptureDelay{11};
93 
94 // In some tests, the computed time values could be off a little bit due to
95 // imprecision in certain wire-format timestamp types. The following macro
96 // behaves just like Gtest's EXPECT_NEAR(), but works with all the time types
97 // too.
98 #define EXPECT_NEARLY_EQUAL(duration_a, duration_b, epsilon) \
99   if ((duration_a) >= (duration_b)) {                        \
100     EXPECT_LE((duration_a), (duration_b) + (epsilon));       \
101   } else {                                                   \
102     EXPECT_GE((duration_a), (duration_b) - (epsilon));       \
103   }
104 
OverrideRtpTimestamp(int frame_count,EncodedFrame * frame,int fps)105 void OverrideRtpTimestamp(int frame_count, EncodedFrame* frame, int fps) {
106   const int ticks = frame_count * kRtpTimebase / fps;
107   frame->rtp_timestamp = RtpTimeTicks() + RtpTimeDelta::FromTicks(ticks);
108 }
109 
110 // Simulates UDP/IPv6 traffic in one direction (from Sender→Receiver, or
111 // Receiver→Sender), with a settable amount of delay.
112 class SimulatedNetworkPipe {
113  public:
SimulatedNetworkPipe(TaskRunner * task_runner,Environment::PacketConsumer * remote)114   SimulatedNetworkPipe(TaskRunner* task_runner,
115                        Environment::PacketConsumer* remote)
116       : task_runner_(task_runner), remote_(remote) {
117     // Create a fake IPv6 address using the "documentative purposes" prefix
118     // concatenated with the |this| pointer.
119     std::array<uint16_t, 8> hextets{};
120     hextets[0] = 0x2001;
121     hextets[1] = 0x0db8;
122     auto* const this_pointer = this;
123     static_assert(sizeof(this_pointer) <= (6 * sizeof(uint16_t)), "");
124     memcpy(&hextets[2], &this_pointer, sizeof(this_pointer));
125     local_endpoint_ = IPEndpoint{IPAddress(hextets), 2344};
126   }
127 
local_endpoint() const128   const IPEndpoint& local_endpoint() const { return local_endpoint_; }
129 
network_delay() const130   Clock::duration network_delay() const { return network_delay_; }
set_network_delay(Clock::duration delay)131   void set_network_delay(Clock::duration delay) { network_delay_ = delay; }
132 
133   // The caller needs to spin the task runner before |packet| will reach the
134   // other side.
StartPacketTransmission(std::vector<uint8_t> packet)135   void StartPacketTransmission(std::vector<uint8_t> packet) {
136     task_runner_->PostTaskWithDelay(
137         [this, packet = std::move(packet)]() mutable {
138           remote_->OnReceivedPacket(local_endpoint_, FakeClock::now(),
139                                     std::move(packet));
140         },
141         network_delay_);
142   }
143 
144  private:
145   TaskRunner* const task_runner_;
146   Environment::PacketConsumer* const remote_;
147 
148   IPEndpoint local_endpoint_;
149 
150   // The amount of time for the packet to transmit over this simulated network
151   // pipe. Defaults to zero to simplify the tests that don't care about delays.
152   Clock::duration network_delay_{};
153 };
154 
155 // Processes packets from the Sender under test, allowing unit tests to set
156 // expectations for parsed RTP or RTCP packets, to confirm proper behavior of
157 // the Sender.
158 class MockReceiver : public Environment::PacketConsumer {
159  public:
MockReceiver(SimulatedNetworkPipe * pipe_to_sender)160   explicit MockReceiver(SimulatedNetworkPipe* pipe_to_sender)
161       : pipe_to_sender_(pipe_to_sender),
162         rtcp_session_(kSenderSsrc, kReceiverSsrc, FakeClock::now()),
163         sender_report_parser_(&rtcp_session_),
164         rtcp_builder_(&rtcp_session_),
165         rtp_parser_(kSenderSsrc),
166         crypto_(kAesKey, kCastIvMask) {
167     rtcp_builder_.SetPlayoutDelay(kTargetPlayoutDelay);
168   }
169 
170   ~MockReceiver() override = default;
171 
172   // Simulate the Receiver ACK'ing all frames up to and including the
173   // |new_checkpoint|.
SetCheckpointFrame(FrameId new_checkpoint)174   void SetCheckpointFrame(FrameId new_checkpoint) {
175     OSP_CHECK_GE(new_checkpoint, rtcp_builder_.checkpoint_frame());
176     rtcp_builder_.SetCheckpointFrame(new_checkpoint);
177   }
178 
179   // Automatically advances the checkpoint based on what is found in
180   // |complete_frames_|, returning true if the checkpoint moved forward.
AutoAdvanceCheckpoint()181   bool AutoAdvanceCheckpoint() {
182     const FrameId old_checkpoint = rtcp_builder_.checkpoint_frame();
183     FrameId new_checkpoint = old_checkpoint;
184     for (auto it = complete_frames_.upper_bound(old_checkpoint);
185          it != complete_frames_.end(); ++it) {
186       if (it->first != new_checkpoint + 1) {
187         break;
188       }
189       ++new_checkpoint;
190     }
191     if (new_checkpoint > old_checkpoint) {
192       rtcp_builder_.SetCheckpointFrame(new_checkpoint);
193       return true;
194     }
195     return false;
196   }
197 
SetPictureLossIndicator(bool picture_is_lost)198   void SetPictureLossIndicator(bool picture_is_lost) {
199     rtcp_builder_.SetPictureLossIndicator(picture_is_lost);
200   }
201 
SetReceiverReport(StatusReportId reply_for,RtcpReportBlock::Delay processing_delay)202   void SetReceiverReport(StatusReportId reply_for,
203                          RtcpReportBlock::Delay processing_delay) {
204     RtcpReportBlock receiver_report;
205     receiver_report.ssrc = kSenderSsrc;
206     receiver_report.last_status_report_id = reply_for;
207     receiver_report.delay_since_last_report = processing_delay;
208     rtcp_builder_.IncludeReceiverReportInNextPacket(receiver_report);
209   }
210 
SetNacksAndAcks(std::vector<PacketNack> packet_nacks,std::vector<FrameId> frame_acks)211   void SetNacksAndAcks(std::vector<PacketNack> packet_nacks,
212                        std::vector<FrameId> frame_acks) {
213     rtcp_builder_.IncludeFeedbackInNextPacket(std::move(packet_nacks),
214                                               std::move(frame_acks));
215   }
216 
217   // Builds and sends a RTCP packet containing one or more of: checkpoint, PLI,
218   // Receiver Report, NACKs, ACKs.
TransmitRtcpFeedbackPacket()219   void TransmitRtcpFeedbackPacket() {
220     uint8_t buffer[kMaxRtpPacketSizeForIpv6UdpOnEthernet];
221     const absl::Span<uint8_t> packet =
222         rtcp_builder_.BuildPacket(FakeClock::now(), buffer);
223     pipe_to_sender_->StartPacketTransmission(
224         std::vector<uint8_t>(packet.begin(), packet.end()));
225   }
226 
227   // Used by tests to simulate the Receiver not seeing specific packets come in
228   // from the network (e.g., because the network dropped the packets).
SetIgnoreList(std::vector<PacketNack> ignore_list)229   void SetIgnoreList(std::vector<PacketNack> ignore_list) {
230     ignore_list_ = ignore_list;
231   }
232 
233   // Environment::PacketConsumer implementation.
234   //
235   // Called to process a packet from the Sender, simulating basic RTP frame
236   // collection and Sender Report parsing/handling.
OnReceivedPacket(const IPEndpoint & source,Clock::time_point arrival_time,std::vector<uint8_t> packet)237   void OnReceivedPacket(const IPEndpoint& source,
238                         Clock::time_point arrival_time,
239                         std::vector<uint8_t> packet) override {
240     const auto type_and_ssrc = InspectPacketForRouting(packet);
241     EXPECT_NE(ApparentPacketType::UNKNOWN, type_and_ssrc.first);
242     EXPECT_EQ(kSenderSsrc, type_and_ssrc.second);
243     if (type_and_ssrc.first == ApparentPacketType::RTP) {
244       const absl::optional<RtpPacketParser::ParseResult> part_of_frame =
245           rtp_parser_.Parse(packet);
246       ASSERT_TRUE(part_of_frame);
247 
248       // Return early if simulating packet drops over the network.
249       if (std::find_if(ignore_list_.begin(), ignore_list_.end(),
250                        [&](const PacketNack& baddie) {
251                          return (
252                              baddie.frame_id == part_of_frame->frame_id &&
253                              (baddie.packet_id == kAllPacketsLost ||
254                               baddie.packet_id == part_of_frame->packet_id));
255                        }) != ignore_list_.end()) {
256         return;
257       }
258 
259       OnRtpPacket(*part_of_frame);
260       CollectRtpPacket(*part_of_frame, std::move(packet));
261     } else if (type_and_ssrc.first == ApparentPacketType::RTCP) {
262       absl::optional<SenderReportParser::SenderReportWithId> report =
263           sender_report_parser_.Parse(packet);
264       ASSERT_TRUE(report);
265       OnSenderReport(*report);
266     }
267   }
268 
TakeCompleteFrames()269   std::map<FrameId, EncodedFrameWithBuffer> TakeCompleteFrames() {
270     std::map<FrameId, EncodedFrameWithBuffer> result;
271     result.swap(complete_frames_);
272     return result;
273   }
274 
275   // Tests set expectations on these mocks to monitor events of interest, and/or
276   // invoke additional behaviors.
277   MOCK_METHOD1(OnRtpPacket,
278                void(const RtpPacketParser::ParseResult& parsed_packet));
279   MOCK_METHOD1(OnFrameComplete, void(FrameId frame_id));
280   MOCK_METHOD1(OnSenderReport,
281                void(const SenderReportParser::SenderReportWithId& report));
282 
283  private:
284   // Collects the individual RTP packets until a whole frame can be formed, then
285   // calls OnFrameComplete(). Ignores extra RTP packets that are no longer
286   // needed.
CollectRtpPacket(const RtpPacketParser::ParseResult & part_of_frame,std::vector<uint8_t> packet)287   void CollectRtpPacket(const RtpPacketParser::ParseResult& part_of_frame,
288                         std::vector<uint8_t> packet) {
289     const FrameId frame_id = part_of_frame.frame_id;
290     if (complete_frames_.find(frame_id) != complete_frames_.end()) {
291       return;
292     }
293     FrameCollector& collector = incomplete_frames_[frame_id];
294     collector.set_frame_id(frame_id);
295     EXPECT_TRUE(collector.CollectRtpPacket(part_of_frame, &packet));
296     if (!collector.is_complete()) {
297       return;
298     }
299     const EncryptedFrame& encrypted = collector.PeekAtAssembledFrame();
300     EncodedFrameWithBuffer* const decrypted = &complete_frames_[frame_id];
301     // Note: Not setting decrypted->reference_time here since the logic around
302     // calculating the playout time is rather complex, and is definitely outside
303     // the scope of the testing being done in this module. Instead, end-to-end
304     // testing should exist elsewhere to confirm frame play-out times with real
305     // Receivers.
306     decrypted->buffer.resize(FrameCrypto::GetPlaintextSize(encrypted));
307     decrypted->data = absl::Span<uint8_t>(decrypted->buffer);
308     crypto_.Decrypt(encrypted, decrypted);
309     incomplete_frames_.erase(frame_id);
310     OnFrameComplete(frame_id);
311   }
312 
313   SimulatedNetworkPipe* const pipe_to_sender_;
314   RtcpSession rtcp_session_;
315   SenderReportParser sender_report_parser_;
316   CompoundRtcpBuilder rtcp_builder_;
317   RtpPacketParser rtp_parser_;
318   FrameCrypto crypto_;
319 
320   std::vector<PacketNack> ignore_list_;
321   std::map<FrameId, FrameCollector> incomplete_frames_;
322   std::map<FrameId, EncodedFrameWithBuffer> complete_frames_;
323 };
324 
325 class MockObserver : public Sender::Observer {
326  public:
327   MOCK_METHOD1(OnFrameCanceled, void(FrameId frame_id));
328   MOCK_METHOD0(OnPictureLost, void());
329 };
330 
331 class SenderTest : public testing::Test {
332  public:
SenderTest()333   SenderTest()
334       : fake_clock_(Clock::now()),
335         task_runner_(&fake_clock_),
336         sender_environment_(&FakeClock::now, &task_runner_),
337         sender_packet_router_(&sender_environment_,
338                               kNumPacketsPerBurst,
339                               kBurstInterval),
340         sender_(&sender_environment_,
341                 &sender_packet_router_,
342                 {/* .sender_ssrc = */ kSenderSsrc,
343                  /* .receiver_ssrc = */ kReceiverSsrc,
344                  /* .rtp_timebase = */ kRtpTimebase,
345                  /* .channels = */ 2,
346                  /* .target_playout_delay = */ kTargetPlayoutDelay,
347                  /* .aes_secret_key = */ kAesKey,
348                  /* .aes_iv_mask = */ kCastIvMask,
349                  /* .is_pli_enabled = */ true},
350                 kRtpPayloadType),
351         receiver_to_sender_pipe_(&task_runner_, &sender_packet_router_),
352         receiver_(&receiver_to_sender_pipe_),
353         sender_to_receiver_pipe_(&task_runner_, &receiver_) {
354     sender_environment_.SetSocketSubscriber(&socket_subscriber_);
355     sender_environment_.set_remote_endpoint(
356         receiver_to_sender_pipe_.local_endpoint());
357     ON_CALL(sender_environment_, SendPacket(_))
__anon6b5c04f90402(absl::Span<const uint8_t> packet) 358         .WillByDefault(Invoke([this](absl::Span<const uint8_t> packet) {
359           sender_to_receiver_pipe_.StartPacketTransmission(
360               std::vector<uint8_t>(packet.begin(), packet.end()));
361         }));
362   }
363 
364   ~SenderTest() override = default;
365 
sender()366   Sender* sender() { return &sender_; }
receiver()367   MockReceiver* receiver() { return &receiver_; }
368 
SetReceiverToSenderNetworkDelay(Clock::duration delay)369   void SetReceiverToSenderNetworkDelay(Clock::duration delay) {
370     receiver_to_sender_pipe_.set_network_delay(delay);
371   }
372 
SetSenderToReceiverNetworkDelay(Clock::duration delay)373   void SetSenderToReceiverNetworkDelay(Clock::duration delay) {
374     sender_to_receiver_pipe_.set_network_delay(delay);
375   }
376 
SimulateExecution(Clock::duration how_long=Clock::duration::zero ())377   void SimulateExecution(Clock::duration how_long = Clock::duration::zero()) {
378     fake_clock_.Advance(how_long);
379   }
380 
PopulateFramePayloadBuffer(int seed,int num_bytes,std::vector<uint8_t> * payload)381   static void PopulateFramePayloadBuffer(int seed,
382                                          int num_bytes,
383                                          std::vector<uint8_t>* payload) {
384     payload->clear();
385     payload->reserve(num_bytes);
386     for (int i = 0; i < num_bytes; ++i) {
387       payload->push_back(static_cast<uint8_t>(seed + i));
388     }
389   }
390 
PopulateFrameWithDefaults(FrameId frame_id,Clock::time_point reference_time,int seed,int num_payload_bytes,EncodedFrameWithBuffer * frame)391   static void PopulateFrameWithDefaults(FrameId frame_id,
392                                         Clock::time_point reference_time,
393                                         int seed,
394                                         int num_payload_bytes,
395                                         EncodedFrameWithBuffer* frame) {
396     frame->dependency = (frame_id == FrameId::first())
397                             ? EncodedFrame::KEY_FRAME
398                             : EncodedFrame::DEPENDS_ON_ANOTHER;
399     frame->frame_id = frame_id;
400     frame->referenced_frame_id = frame->frame_id;
401     if (frame_id != FrameId::first()) {
402       --frame->referenced_frame_id;
403     }
404     frame->rtp_timestamp =
405         RtpTimeTicks() + (RtpTimeDelta::FromTicks(kRtpTicksPerFrame) *
406                           (frame_id - FrameId::first()));
407     frame->reference_time = reference_time;
408     PopulateFramePayloadBuffer(seed, num_payload_bytes, &frame->buffer);
409     frame->data = absl::Span<uint8_t>(frame->buffer);
410   }
411 
412   // Confirms that all |sent_frames| exist in |received_frames|, with identical
413   // data and metadata.
ExpectFramesReceivedCorrectly(absl::Span<EncodedFrameWithBuffer> sent_frames,const std::map<FrameId,EncodedFrameWithBuffer> received_frames)414   static void ExpectFramesReceivedCorrectly(
415       absl::Span<EncodedFrameWithBuffer> sent_frames,
416       const std::map<FrameId, EncodedFrameWithBuffer> received_frames) {
417     ASSERT_EQ(sent_frames.size(), received_frames.size());
418 
419     for (const EncodedFrameWithBuffer& sent_frame : sent_frames) {
420       SCOPED_TRACE(testing::Message()
421                    << "Checking sent frame " << sent_frame.frame_id);
422       const auto received_it = received_frames.find(sent_frame.frame_id);
423       if (received_it == received_frames.end()) {
424         ADD_FAILURE() << "Did not receive frame.";
425         continue;
426       }
427       const EncodedFrame& received_frame = received_it->second;
428       EXPECT_EQ(sent_frame.dependency, received_frame.dependency);
429       EXPECT_EQ(sent_frame.referenced_frame_id,
430                 received_frame.referenced_frame_id);
431       EXPECT_EQ(sent_frame.rtp_timestamp, received_frame.rtp_timestamp);
432       EXPECT_TRUE(sent_frame.data == received_frame.data);
433     }
434   }
435 
436  private:
437   FakeClock fake_clock_;
438   FakeTaskRunner task_runner_;
439   NiceMock<MockEnvironment> sender_environment_;
440   SenderPacketRouter sender_packet_router_;
441   Sender sender_;
442   SimulatedNetworkPipe receiver_to_sender_pipe_;
443   NiceMock<MockReceiver> receiver_;
444   SimulatedNetworkPipe sender_to_receiver_pipe_;
445   SimpleSubscriber socket_subscriber_;
446 };
447 
448 // Tests that the Sender can send EncodedFrames over an ideal network (i.e., low
449 // latency, no loss), and does so without having to transmit the same packet
450 // twice.
TEST_F(SenderTest,SendsFramesEfficiently)451 TEST_F(SenderTest, SendsFramesEfficiently) {
452   constexpr milliseconds kOneWayNetworkDelay{1};
453   SetSenderToReceiverNetworkDelay(kOneWayNetworkDelay);
454   SetReceiverToSenderNetworkDelay(kOneWayNetworkDelay);
455 
456   // Expect that each packet is only sent once.
457   std::set<std::pair<FrameId, FramePacketId>> received_packets;
458   EXPECT_CALL(*receiver(), OnRtpPacket(_))
459       .WillRepeatedly(
460           Invoke([&](const RtpPacketParser::ParseResult& parsed_packet) {
461             std::pair<FrameId, FramePacketId> id(parsed_packet.frame_id,
462                                                  parsed_packet.packet_id);
463             const auto insert_result = received_packets.insert(id);
464             EXPECT_TRUE(insert_result.second)
465                 << "Received duplicate packet: " << id.first << ':'
466                 << static_cast<int>(id.second);
467           }));
468 
469   // Simulate normal frame ACK'ing behavior.
470   ON_CALL(*receiver(), OnFrameComplete(_)).WillByDefault(InvokeWithoutArgs([&] {
471     if (receiver()->AutoAdvanceCheckpoint()) {
472       receiver()->TransmitRtcpFeedbackPacket();
473     }
474   }));
475 
476   NiceMock<MockObserver> observer;
477   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first())).Times(1);
478   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 1)).Times(1);
479   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 2)).Times(1);
480   sender()->SetObserver(&observer);
481 
482   EncodedFrameWithBuffer frames[3];
483   constexpr int kFrameDataSizes[] = {8196, 12, 1900};
484   for (int i = 0; i < 3; ++i) {
485     if (i == 0) {
486       EXPECT_TRUE(sender()->NeedsKeyFrame());
487     } else {
488       EXPECT_FALSE(sender()->NeedsKeyFrame());
489     }
490     PopulateFrameWithDefaults(FrameId::first() + i,
491                               FakeClock::now() - kCaptureDelay, 0xbf - i,
492                               kFrameDataSizes[i], &frames[i]);
493     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
494     SimulateExecution(kFrameDuration);
495   }
496   SimulateExecution(kTargetPlayoutDelay);
497 
498   ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
499 }
500 
501 // Tests that the Sender correctly computes the current in-flight media
502 // duration, a backlog signal for clients.
TEST_F(SenderTest,ComputesInFlightMediaDuration)503 TEST_F(SenderTest, ComputesInFlightMediaDuration) {
504   // With no frames enqueued, the in-flight media duration should be zero.
505   EXPECT_EQ(Clock::duration::zero(),
506             sender()->GetInFlightMediaDuration(RtpTimeTicks()));
507   EXPECT_EQ(Clock::duration::zero(),
508             sender()->GetInFlightMediaDuration(
509                 RtpTimeTicks() + RtpTimeDelta::FromTicks(kRtpTicksPerFrame)));
510 
511   // Enqueue a frame.
512   EncodedFrameWithBuffer frame;
513   PopulateFrameWithDefaults(FrameId::first(), FakeClock::now(), 0,
514                             13 /* bytes */, &frame);
515   ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
516 
517   // Now, the in-flight media duration should depend on the RTP timestamp of the
518   // next frame.
519   EXPECT_EQ(kFrameDuration, sender()->GetInFlightMediaDuration(
520                                 frame.rtp_timestamp +
521                                 RtpTimeDelta::FromTicks(kRtpTicksPerFrame)));
522   EXPECT_EQ(10 * kFrameDuration,
523             sender()->GetInFlightMediaDuration(
524                 frame.rtp_timestamp +
525                 RtpTimeDelta::FromTicks(10 * kRtpTicksPerFrame)));
526 }
527 
528 // Tests that the Sender computes the maximum in-flight media duration based on
529 // its analysis of current network conditions. By implication, this demonstrates
530 // that the Sender is also measuring the network round-trip time.
TEST_F(SenderTest,RespondsToNetworkLatencyChanges)531 TEST_F(SenderTest, RespondsToNetworkLatencyChanges) {
532   // The expected maximum error in time calculations is one tick of the RTCP
533   // report block's delay type.
534   constexpr auto kEpsilon = to_nanoseconds(RtcpReportBlock::Delay(1));
535 
536   // Before the Sender has the necessary information to compute the network
537   // round-trip time, GetMaxInFlightMediaDuration() will return half the target
538   // playout delay.
539   EXPECT_NEARLY_EQUAL(kTargetPlayoutDelay / 2,
540                       sender()->GetMaxInFlightMediaDuration(), kEpsilon);
541 
542   // No network is perfect. Simulate different one-way network delays.
543   constexpr milliseconds kOutboundDelay{2};
544   constexpr milliseconds kInboundDelay{4};
545   constexpr milliseconds kRoundTripDelay = kOutboundDelay + kInboundDelay;
546   SetSenderToReceiverNetworkDelay(kOutboundDelay);
547   SetReceiverToSenderNetworkDelay(kInboundDelay);
548 
549   // Enqueue a frame in the Sender to start emitting periodic RTCP reports.
550   {
551     EncodedFrameWithBuffer frame;
552     PopulateFrameWithDefaults(FrameId::first(), FakeClock::now(), 0,
553                               1 /* byte */, &frame);
554     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
555   }
556 
557   // Run one network round-trip from Sender→Receiver→Sender.
558   StatusReportId sender_report_id{};
559   EXPECT_CALL(*receiver(), OnSenderReport(_))
560       .WillOnce(Invoke(
561           [&](const SenderReportParser::SenderReportWithId& sender_report) {
562             sender_report_id = sender_report.report_id;
563           }));
564   // Simulate the passage of time for the Sender Report to reach the Receiver.
565   SimulateExecution(kOutboundDelay);
566   // The Receiver should have received the Sender Report at this point.
567   Mock::VerifyAndClearExpectations(receiver());
568   ASSERT_NE(StatusReportId{}, sender_report_id);
569   // Simulate the passage of time in the Receiver doing "other tasks" before
570   // replying back to the Sender. This delay is included in the Receiver Report
571   // so that the Sender can isolate the delays caused by the network.
572   constexpr milliseconds kReceiverProcessingDelay{2};
573   SimulateExecution(kReceiverProcessingDelay);
574   // Create the Receiver Report "reply," and simulate it being sent across the
575   // network, back to the Sender.
576   receiver()->SetReceiverReport(
577       sender_report_id, std::chrono::duration_cast<RtcpReportBlock::Delay>(
578                             kReceiverProcessingDelay));
579   receiver()->TransmitRtcpFeedbackPacket();
580   SimulateExecution(kInboundDelay);
581 
582   // At this point, the Sender should have computed the network round-trip time,
583   // and so GetMaxInFlightMediaDuration() will return half the target playout
584   // delay PLUS half the network round-trip time.
585   EXPECT_NEARLY_EQUAL(kTargetPlayoutDelay / 2 + kRoundTripDelay / 2,
586                       sender()->GetMaxInFlightMediaDuration(), kEpsilon);
587 
588   // Increase the outbound delay, which will increase the total round-trip time.
589   constexpr milliseconds kIncreasedOutboundDelay{6};
590   constexpr milliseconds kIncreasedRoundTripDelay =
591       kIncreasedOutboundDelay + kInboundDelay;
592   SetSenderToReceiverNetworkDelay(kIncreasedOutboundDelay);
593 
594   // With increased network delay, run several more network round-trips. Expect
595   // the Sender to gradually converge towards the new network round-trip time.
596   constexpr int kNumReportIntervals = 50;
597   EXPECT_CALL(*receiver(), OnSenderReport(_))
598       .Times(kNumReportIntervals)
599       .WillRepeatedly(Invoke(
600           [&](const SenderReportParser::SenderReportWithId& sender_report) {
601             receiver()->SetReceiverReport(sender_report.report_id,
602                                           RtcpReportBlock::Delay::zero());
603             receiver()->TransmitRtcpFeedbackPacket();
604           }));
605   Clock::duration last_max = sender()->GetMaxInFlightMediaDuration();
606   for (int i = 0; i < kNumReportIntervals; ++i) {
607     SimulateExecution(kRtcpReportInterval);
608     const Clock::duration updated_value =
609         sender()->GetMaxInFlightMediaDuration();
610     EXPECT_LE(last_max, updated_value);
611     last_max = updated_value;
612   }
613   EXPECT_NEARLY_EQUAL(kTargetPlayoutDelay / 2 + kIncreasedRoundTripDelay / 2,
614                       sender()->GetMaxInFlightMediaDuration(), kEpsilon);
615 }
616 
617 // Tests that the Sender rejects frames if too large a span of FrameIds would be
618 // in-flight at once.
TEST_F(SenderTest,RejectsEnqueuingBeforeProtocolDesignLimit)619 TEST_F(SenderTest, RejectsEnqueuingBeforeProtocolDesignLimit) {
620   // For this test, use 1000 FPS. This makes the frames all one millisecond
621   // apart to avoid triggering the media-duration rejection logic.
622   constexpr int kFramesPerSecond = 1000;
623   constexpr milliseconds kFrameDuration{1};
624 
625   // Send the absolute design-limit maximum number of frames.
626   int frame_count = 0;
627   for (; frame_count < kMaxUnackedFrames; ++frame_count) {
628     EncodedFrameWithBuffer frame;
629     PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
630                               13 /* bytes */, &frame);
631     OverrideRtpTimestamp(frame_count, &frame, kFramesPerSecond);
632     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
633     SimulateExecution(kFrameDuration);
634   }
635 
636   // Now, attempting to enqueue just one more frame should fail.
637   EncodedFrameWithBuffer one_frame_too_much;
638   PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
639                             13 /* bytes */, &one_frame_too_much);
640   OverrideRtpTimestamp(frame_count++, &one_frame_too_much, kFramesPerSecond);
641   EXPECT_EQ(Sender::REACHED_ID_SPAN_LIMIT,
642             sender()->EnqueueFrame(one_frame_too_much));
643   SimulateExecution(kFrameDuration);
644 
645   // Now, simulate the Receiver ACKing the first frame, and enqueuing should
646   // then succeed again.
647   receiver()->SetCheckpointFrame(FrameId::first());
648   receiver()->TransmitRtcpFeedbackPacket();
649   SimulateExecution();  // RTCP transmitted to Sender.
650   EXPECT_EQ(Sender::OK, sender()->EnqueueFrame(one_frame_too_much));
651   SimulateExecution(kFrameDuration);
652 
653   // Finally, attempting to enqueue another frame should fail again.
654   EncodedFrameWithBuffer another_frame_too_much;
655   PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
656                             13 /* bytes */, &another_frame_too_much);
657   OverrideRtpTimestamp(frame_count++, &another_frame_too_much,
658                        kFramesPerSecond);
659   EXPECT_EQ(Sender::REACHED_ID_SPAN_LIMIT,
660             sender()->EnqueueFrame(another_frame_too_much));
661   SimulateExecution(kFrameDuration);
662 }
663 
TEST_F(SenderTest,CanCancelAllInFlightFrames)664 TEST_F(SenderTest, CanCancelAllInFlightFrames) {
665   NiceMock<MockObserver> observer;
666   sender()->SetObserver(&observer);
667 
668   // Send the absolute design-limit maximum number of frames.
669   for (int i = 0; i < kMaxUnackedFrames; ++i) {
670     EncodedFrameWithBuffer frame;
671     PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
672                               13 /* bytes */, &frame);
673     OverrideRtpTimestamp(i, &frame, 1000 /* fps */);
674     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
675     SimulateExecution(kFrameDuration);
676   }
677 
678   EXPECT_CALL(observer, OnFrameCanceled(_)).Times(kMaxUnackedFrames);
679   sender()->CancelInFlightData();
680 }
681 
682 // Tests that the Sender rejects frames if too-long a media duration is
683 // in-flight. This is the Sender's primary flow control mechanism.
TEST_F(SenderTest,RejectsEnqueuingIfTooLongMediaDurationIsInFlight)684 TEST_F(SenderTest, RejectsEnqueuingIfTooLongMediaDurationIsInFlight) {
685   // For this test, use 20 FPS. This makes all frames 50 ms apart, which should
686   // make it easy to trigger the media-duration rejection logic.
687   constexpr int kFramesPerSecond = 20;
688   constexpr milliseconds kFrameDuration{50};
689 
690   // Enqueue frames until one is rejected because the in-flight duration would
691   // be too high.
692   EncodedFrameWithBuffer frame;
693   int frame_count = 0;
694   for (; frame_count < kMaxUnackedFrames; ++frame_count) {
695     PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
696                               13 /* bytes */, &frame);
697     OverrideRtpTimestamp(frame_count, &frame, kFramesPerSecond);
698     const auto result = sender()->EnqueueFrame(frame);
699     SimulateExecution(kFrameDuration);
700     if (result == Sender::MAX_DURATION_IN_FLIGHT) {
701       break;
702     }
703     ASSERT_EQ(Sender::OK, result);
704   }
705 
706   // Now, simulate the Receiver ACKing the first frame, and enqueuing should
707   // then succeed again.
708   receiver()->SetCheckpointFrame(FrameId::first());
709   receiver()->TransmitRtcpFeedbackPacket();
710   SimulateExecution();  // RTCP transmitted to Sender.
711   EXPECT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
712   SimulateExecution(kFrameDuration);
713 
714   // However, attempting to enqueue another frame should fail again.
715   EncodedFrameWithBuffer one_frame_too_much;
716   PopulateFrameWithDefaults(sender()->GetNextFrameId(), FakeClock::now(), 0,
717                             13 /* bytes */, &one_frame_too_much);
718   OverrideRtpTimestamp(++frame_count, &one_frame_too_much, kFramesPerSecond);
719   EXPECT_EQ(Sender::MAX_DURATION_IN_FLIGHT,
720             sender()->EnqueueFrame(one_frame_too_much));
721   SimulateExecution(kFrameDuration);
722 }
723 
724 // Tests that the Sender propagates the Receiver's picture loss indicator to the
725 // Observer::OnPictureLost(), and via calls to NeedsKeyFrame(); but only when
726 // producing a key frame is absolutely necessary.
TEST_F(SenderTest,ManagesReceiverPictureLossWorkflow)727 TEST_F(SenderTest, ManagesReceiverPictureLossWorkflow) {
728   NiceMock<MockObserver> observer;
729   sender()->SetObserver(&observer);
730 
731   // Send three frames...
732   EncodedFrameWithBuffer frames[6];
733   for (int i = 0; i < 3; ++i) {
734     if (i == 0) {
735       EXPECT_TRUE(sender()->NeedsKeyFrame());
736     } else {
737       EXPECT_FALSE(sender()->NeedsKeyFrame());
738     }
739     PopulateFrameWithDefaults(FrameId::first() + i,
740                               FakeClock::now() - kCaptureDelay, 0,
741                               24 /* bytes */, &frames[i]);
742     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
743     SimulateExecution(kFrameDuration);
744   }
745   SimulateExecution(kTargetPlayoutDelay);
746 
747   // Simulate the Receiver ACK'ing the first three frames.
748   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first())).Times(1);
749   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 1)).Times(1);
750   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 2)).Times(1);
751   EXPECT_CALL(observer, OnPictureLost()).Times(0);
752   receiver()->SetCheckpointFrame(frames[2].frame_id);
753   receiver()->TransmitRtcpFeedbackPacket();
754   SimulateExecution();  // RTCP transmitted to Sender.
755   Mock::VerifyAndClearExpectations(&observer);
756 
757   // Simulate something going wrong in the Receiver, and have it report picture
758   // loss to the Sender. The Sender should then propagate this to its Observer
759   // and return true when NeedsKeyFrame() is called.
760   EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
761   EXPECT_CALL(observer, OnPictureLost()).Times(1);
762   EXPECT_FALSE(sender()->NeedsKeyFrame());
763   receiver()->SetPictureLossIndicator(true);
764   receiver()->TransmitRtcpFeedbackPacket();
765   SimulateExecution();  // RTCP transmitted to Sender.
766   Mock::VerifyAndClearExpectations(&observer);
767   EXPECT_TRUE(sender()->NeedsKeyFrame());
768 
769   // Send a non-key frame, and expect NeedsKeyFrame() still returns true. The
770   // Observer is not re-notified. This accounts for the case where a client's
771   // media encoder had frames in its processing pipeline before NeedsKeyFrame()
772   // began returning true.
773   EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
774   EXPECT_CALL(observer, OnPictureLost()).Times(0);
775   EncodedFrameWithBuffer& nonkey_frame = frames[3];
776   PopulateFrameWithDefaults(FrameId::first() + 3,
777                             FakeClock::now() - kCaptureDelay, 0, 24 /* bytes */,
778                             &nonkey_frame);
779   ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(nonkey_frame));
780   SimulateExecution(kFrameDuration);
781   Mock::VerifyAndClearExpectations(&observer);
782   EXPECT_TRUE(sender()->NeedsKeyFrame());
783 
784   // Now send a key frame, and expect NeedsKeyFrame() returns false. Note that
785   // the Receiver hasn't cleared the PLI condition, but the Sender knows more
786   // key frames won't be needed.
787   EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
788   EXPECT_CALL(observer, OnPictureLost()).Times(0);
789   EncodedFrameWithBuffer& recovery_frame = frames[4];
790   PopulateFrameWithDefaults(FrameId::first() + 4,
791                             FakeClock::now() - kCaptureDelay, 0, 24 /* bytes */,
792                             &recovery_frame);
793   recovery_frame.dependency = EncodedFrame::KEY_FRAME;
794   recovery_frame.referenced_frame_id = recovery_frame.frame_id;
795   ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(recovery_frame));
796   SimulateExecution(kFrameDuration);
797   Mock::VerifyAndClearExpectations(&observer);
798   EXPECT_FALSE(sender()->NeedsKeyFrame());
799 
800   // Let's say the Receiver hasn't received the key frame yet, and it reports
801   // its picture loss again to the Sender. Observer::OnPictureLost() should not
802   // be called, and NeedsKeyFrame() should NOT return true, because the Sender
803   // knows the Receiver hasn't acknowledged the key frame (just sent) yet.
804   EXPECT_CALL(observer, OnFrameCanceled(nonkey_frame.frame_id)).Times(1);
805   EXPECT_CALL(observer, OnPictureLost()).Times(0);
806   receiver()->SetCheckpointFrame(nonkey_frame.frame_id);
807   receiver()->SetPictureLossIndicator(true);
808   receiver()->TransmitRtcpFeedbackPacket();
809   SimulateExecution();  // RTCP transmitted to Sender.
810   Mock::VerifyAndClearExpectations(&observer);
811   EXPECT_FALSE(sender()->NeedsKeyFrame());
812 
813   // Now, simulate the Receiver getting the key frame, but NOT recovering. This
814   // should cause Observer::OnPictureLost() to be called, and cause
815   // NeedsKeyFrame() to return true again.
816   EXPECT_CALL(observer, OnFrameCanceled(recovery_frame.frame_id)).Times(1);
817   EXPECT_CALL(observer, OnPictureLost()).Times(1);
818   receiver()->SetCheckpointFrame(recovery_frame.frame_id);
819   receiver()->SetPictureLossIndicator(true);
820   receiver()->TransmitRtcpFeedbackPacket();
821   SimulateExecution();  // RTCP transmitted to Sender.
822   Mock::VerifyAndClearExpectations(&observer);
823   EXPECT_TRUE(sender()->NeedsKeyFrame());
824 
825   // Send another key frame, and expect NeedsKeyFrame() returns false.
826   EXPECT_CALL(observer, OnFrameCanceled(_)).Times(0);
827   EXPECT_CALL(observer, OnPictureLost()).Times(0);
828   EncodedFrameWithBuffer& another_recovery_frame = frames[5];
829   PopulateFrameWithDefaults(FrameId::first() + 5,
830                             FakeClock::now() - kCaptureDelay, 0, 24 /* bytes */,
831                             &another_recovery_frame);
832   another_recovery_frame.dependency = EncodedFrame::KEY_FRAME;
833   another_recovery_frame.referenced_frame_id = another_recovery_frame.frame_id;
834   ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(another_recovery_frame));
835   SimulateExecution(kFrameDuration);
836   Mock::VerifyAndClearExpectations(&observer);
837   EXPECT_FALSE(sender()->NeedsKeyFrame());
838 
839   // Now, simulate the Receiver recovering. It will report this to the Sender,
840   // and NeedsKeyFrame() will still return false.
841   EXPECT_CALL(observer, OnFrameCanceled(another_recovery_frame.frame_id))
842       .Times(1);
843   EXPECT_CALL(observer, OnPictureLost()).Times(0);
844   receiver()->SetCheckpointFrame(another_recovery_frame.frame_id);
845   receiver()->SetPictureLossIndicator(false);
846   receiver()->TransmitRtcpFeedbackPacket();
847   SimulateExecution();  // RTCP transmitted to Sender.
848   Mock::VerifyAndClearExpectations(&observer);
849   EXPECT_FALSE(sender()->NeedsKeyFrame());
850 
851   ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
852 }
853 
854 // Tests that the Receiver should get a Sender Report just before the first RTP
855 // packet, and at regular intervals thereafter. The Sender Report contains the
856 // lip-sync information necessary for play-out timing.
TEST_F(SenderTest,ProvidesSenderReports)857 TEST_F(SenderTest, ProvidesSenderReports) {
858   std::vector<SenderReportParser::SenderReportWithId> sender_reports;
859   Sequence packet_sequence;
860   EXPECT_CALL(*receiver(), OnSenderReport(_))
861       .InSequence(packet_sequence)
862       .WillOnce(
863           Invoke([&](const SenderReportParser::SenderReportWithId& report) {
864             sender_reports.push_back(report);
865           }))
866       .RetiresOnSaturation();
867   EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(1).InSequence(packet_sequence);
868   EXPECT_CALL(*receiver(), OnSenderReport(_))
869       .Times(3)
870       .InSequence(packet_sequence)
871       .WillRepeatedly(
872           Invoke([&](const SenderReportParser::SenderReportWithId& report) {
873             sender_reports.push_back(report);
874           }));
875 
876   EncodedFrameWithBuffer frame;
877   constexpr int kFrameDataSize = 250;
878   PopulateFrameWithDefaults(FrameId::first(), FakeClock::now(), 0,
879                             kFrameDataSize, &frame);
880   ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frame));
881   SimulateExecution();  // Should send one Sender Report + one RTP packet.
882   EXPECT_EQ(size_t{1}, sender_reports.size());
883 
884   // Have the Receiver ACK the frame to prevent retransmitting the RTP packet.
885   receiver()->SetCheckpointFrame(FrameId::first());
886   receiver()->TransmitRtcpFeedbackPacket();
887   SimulateExecution();  // RTCP transmitted to Sender.
888 
889   // Advance through three more reporting intervals. One Sender Report should be
890   // sent each interval, making a total of 4 reports sent.
891   constexpr auto kThreeReportIntervals = 3 * kRtcpReportInterval;
892   SimulateExecution(kThreeReportIntervals);  // Three more Sender Reports.
893   ASSERT_EQ(size_t{4}, sender_reports.size());
894 
895   // The first report should contain the same timestamps as the frame because
896   // the Clock did not advance. Also, its packet count and octet count fields
897   // should be zero since the report was sent before the RTP packet.
898   EXPECT_EQ(frame.reference_time, sender_reports.front().reference_time);
899   EXPECT_EQ(frame.rtp_timestamp, sender_reports.front().rtp_timestamp);
900   EXPECT_EQ(uint32_t{0}, sender_reports.front().send_packet_count);
901   EXPECT_EQ(uint32_t{0}, sender_reports.front().send_octet_count);
902 
903   // The last report should contain the timestamps extrapolated into the future
904   // because the Clock did move forward. Also, the packet count and octet fields
905   // should now be non-zero because the report was sent after the RTP packet.
906   EXPECT_EQ(frame.reference_time + kThreeReportIntervals,
907             sender_reports.back().reference_time);
908   EXPECT_EQ(frame.rtp_timestamp +
909                 RtpTimeDelta::FromDuration(kThreeReportIntervals, kRtpTimebase),
910             sender_reports.back().rtp_timestamp);
911   EXPECT_EQ(uint32_t{1}, sender_reports.back().send_packet_count);
912   EXPECT_EQ(uint32_t{kFrameDataSize}, sender_reports.back().send_octet_count);
913 }
914 
915 // Tests that the Sender provides Kickstart packets whenever the Receiver may
916 // not know about new frames.
TEST_F(SenderTest,ProvidesKickstartPacketsIfReceiverDoesNotACK)917 TEST_F(SenderTest, ProvidesKickstartPacketsIfReceiverDoesNotACK) {
918   // Have the Receiver move the checkpoint forward only for the first frame, and
919   // none of the later frames. This will force the Sender to eventually send a
920   // Kickstart packet.
921   ON_CALL(*receiver(), OnFrameComplete(_))
922       .WillByDefault(Invoke([&](FrameId frame_id) {
923         if (frame_id == FrameId::first()) {
924           receiver()->SetCheckpointFrame(FrameId::first());
925           receiver()->TransmitRtcpFeedbackPacket();
926         }
927       }));
928 
929   // Send three frames, paced to the media.
930   EncodedFrameWithBuffer frames[3];
931   for (int i = 0; i < 3; ++i) {
932     PopulateFrameWithDefaults(FrameId::first() + i,
933                               FakeClock::now() - kCaptureDelay, i,
934                               48 /* bytes */, &frames[i]);
935     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
936     SimulateExecution(kFrameDuration);
937   }
938 
939   // Now, do nothing for a while. Because the Receiver isn't moving the
940   // checkpoint forward, the Sender will have sent all the RTP packets at least
941   // once, and then will start sending just Kickstart packets.
942   SimulateExecution(kTargetPlayoutDelay);
943 
944   // Keep doing nothing for a while, and confirm the Sender is just sending the
945   // same Kickstart packet over and over. The Kickstart packet is supposed to be
946   // the last packet of the latest frame.
947   std::set<std::pair<FrameId, FramePacketId>> unique_received_packet_ids;
948   EXPECT_CALL(*receiver(), OnRtpPacket(_))
949       .WillRepeatedly(
950           Invoke([&](const RtpPacketParser::ParseResult& parsed_packet) {
951             unique_received_packet_ids.emplace(parsed_packet.frame_id,
952                                                parsed_packet.packet_id);
953           }));
954   SimulateExecution(kTargetPlayoutDelay);
955   Mock::VerifyAndClearExpectations(receiver());
956   EXPECT_EQ(size_t{1}, unique_received_packet_ids.size());
957   EXPECT_EQ(frames[2].frame_id, unique_received_packet_ids.begin()->first);
958 
959   // Now, simulate the Receiver ACKing all the frames.
960   receiver()->SetCheckpointFrame(frames[2].frame_id);
961   receiver()->TransmitRtcpFeedbackPacket();
962   SimulateExecution();  // RTCP transmitted to Sender.
963 
964   // With all the frames sent, the Sender should not be transmitting anything.
965   EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(0);
966   SimulateExecution(10 * kTargetPlayoutDelay);
967 
968   ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
969 }
970 
971 // Tests that the Sender only retransmits packets specifically NACK'ed by the
972 // Receiver.
TEST_F(SenderTest,ResendsIndividuallyNackedPackets)973 TEST_F(SenderTest, ResendsIndividuallyNackedPackets) {
974   // Populate the frame data in each frame with enough bytes to force at least
975   // three RTP packets per frame.
976   constexpr int kFrameDataSize = 3 * kMaxRtpPacketSizeForIpv6UdpOnEthernet;
977 
978   // Use a 1ms network delay in each direction to make the sequence of events
979   // clearer in this test.
980   constexpr milliseconds kOneWayNetworkDelay{1};
981   SetSenderToReceiverNetworkDelay(kOneWayNetworkDelay);
982   SetReceiverToSenderNetworkDelay(kOneWayNetworkDelay);
983 
984   // Simulate that three specific packets will be dropped by the network, one
985   // from each frame (about to be sent).
986   const std::vector<PacketNack> dropped_packets{
987       {FrameId::first(), FramePacketId{2}},
988       {FrameId::first() + 1, FramePacketId{1}},
989       {FrameId::first() + 2, FramePacketId{0}},
990   };
991   receiver()->SetIgnoreList(dropped_packets);
992 
993   // Send three frames, paced to the media. The Receiver won't completely
994   // receive any of these frames due to dropped packets.
995   EXPECT_CALL(*receiver(), OnFrameComplete(_)).Times(0);
996   EncodedFrameWithBuffer frames[3];
997   for (int i = 0; i < 3; ++i) {
998     PopulateFrameWithDefaults(FrameId::first() + i,
999                               FakeClock::now() - kCaptureDelay, i,
1000                               kFrameDataSize, &frames[i]);
1001     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
1002     SimulateExecution(kFrameDuration);
1003   }
1004   SimulateExecution(kTargetPlayoutDelay);
1005   Mock::VerifyAndClearExpectations(receiver());
1006   EXPECT_EQ(3, sender()->GetInFlightFrameCount());
1007 
1008   // The Receiver NACKs the three dropped packets...
1009   receiver()->SetNacksAndAcks(dropped_packets, {});
1010   receiver()->TransmitRtcpFeedbackPacket();
1011 
1012   // In the meantime, the network recovers (i.e., no more dropped packets)...
1013   receiver()->SetIgnoreList({});
1014 
1015   // The NACKs reach the Sender, and it acts on them by retransmitting.
1016   SimulateExecution(kOneWayNetworkDelay);
1017 
1018   // As each retransmitted packet arrives at the Receiver, advance the
1019   // checkpoint forward to notify the Sender of frames that are now completely
1020   // received. Also, confirm that only the three specifically-NACK'ed packets
1021   // were retransmitted.
1022   EXPECT_CALL(*receiver(), OnFrameComplete(_))
1023       .Times(3)
1024       .WillRepeatedly(InvokeWithoutArgs([&] {
1025         if (receiver()->AutoAdvanceCheckpoint()) {
1026           receiver()->TransmitRtcpFeedbackPacket();
1027         }
1028       }));
1029   EXPECT_CALL(*receiver(), OnRtpPacket(_))
1030       .Times(3)
1031       .WillRepeatedly(Invoke([&](const RtpPacketParser::ParseResult& packet) {
1032         EXPECT_FALSE(std::find(dropped_packets.begin(), dropped_packets.end(),
1033                                PacketNack{packet.frame_id, packet.packet_id}) ==
1034                      dropped_packets.end());
1035       }));
1036   SimulateExecution(kOneWayNetworkDelay);
1037   Mock::VerifyAndClearExpectations(receiver());
1038 
1039   // The Receiver checkpoint feedback(s) travel back to the Sender, and there
1040   // should no longer be any frames in-flight.
1041   SimulateExecution(kOneWayNetworkDelay);
1042   EXPECT_EQ(0, sender()->GetInFlightFrameCount());
1043 
1044   // The Sender should not be transmitting anything from now on since all frames
1045   // are known to have been completely received.
1046   EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(0);
1047   SimulateExecution(10 * kTargetPlayoutDelay);
1048 
1049   ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
1050 }
1051 
1052 // Tests that the Sender retransmits an entire frame if the Receiver requests it
1053 // (i.e., a full frame NACK), but does not retransmit any packets for frames
1054 // (before or after) that have been acknowledged.
TEST_F(SenderTest,ResendsMissingFrames)1055 TEST_F(SenderTest, ResendsMissingFrames) {
1056   // Populate the frame data in each frame with enough bytes to force at least
1057   // three RTP packets per frame.
1058   constexpr int kFrameDataSize = 3 * kMaxRtpPacketSizeForIpv6UdpOnEthernet;
1059 
1060   // Use a 1ms network delay in each direction to make the sequence of events
1061   // clearer in this test.
1062   constexpr milliseconds kOneWayNetworkDelay{1};
1063   SetSenderToReceiverNetworkDelay(kOneWayNetworkDelay);
1064   SetReceiverToSenderNetworkDelay(kOneWayNetworkDelay);
1065 
1066   // Simulate that all of the packets for the second frame will be dropped by
1067   // the network, but only the packets for that frame.
1068   const std::vector<PacketNack> dropped_packets{
1069       {FrameId::first() + 1, kAllPacketsLost},
1070   };
1071   receiver()->SetIgnoreList(dropped_packets);
1072 
1073   NiceMock<MockObserver> observer;
1074   sender()->SetObserver(&observer);
1075 
1076   // The expectations below track the story and execute simulated Receiver
1077   // responses. The Sender will have three frames enqueued by its client, and
1078   // then...
1079   //
1080   // The first frame is received and the Receiver ACKs it by moving the
1081   // checkpoint forward.
1082   Sequence completion_sequence;
1083   EXPECT_CALL(*receiver(), OnFrameComplete(FrameId::first()))
1084       .InSequence(completion_sequence)
1085       .WillOnce(InvokeWithoutArgs([&] {
1086         receiver()->SetCheckpointFrame(FrameId::first());
1087         receiver()->TransmitRtcpFeedbackPacket();
1088       }));
1089   // Since all of the packets for the second frame are being dropped, the third
1090   // frame will finish next. The Receiver responds by NACKing the second frame
1091   // and ACKing the third frame. The checkpoint does not move forward because
1092   // the second frame has not been received yet.
1093   //
1094   // NETWORK CHANGE: After the third frame is received, stop dropping packets.
1095   EXPECT_CALL(*receiver(), OnFrameComplete(FrameId::first() + 2))
1096       .InSequence(completion_sequence)
1097       .WillOnce(InvokeWithoutArgs([&] {
1098         receiver()->SetNacksAndAcks(dropped_packets,
1099                                     std::vector<FrameId>{FrameId::first() + 2});
1100         receiver()->TransmitRtcpFeedbackPacket();
1101         receiver()->SetIgnoreList({});
1102       }));
1103   // Finally, the Sender should respond to the whole-frame NACK by re-sending
1104   // all of the packets for the second frame, and so the Receiver should
1105   // completely receive the frame.
1106   EXPECT_CALL(*receiver(), OnFrameComplete(FrameId::first() + 1))
1107       .InSequence(completion_sequence)
1108       .WillOnce(InvokeWithoutArgs([&] {
1109         receiver()->SetCheckpointFrame(FrameId::first() + 2);
1110         receiver()->TransmitRtcpFeedbackPacket();
1111       }));
1112 
1113   // From the Sender's perspective, the Receiver will ACK the first frame, then
1114   // the third frame, then the second frame.
1115   Sequence cancel_sequence;
1116   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first()))
1117       .Times(1)
1118       .InSequence(cancel_sequence);
1119   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 2))
1120       .Times(1)
1121       .InSequence(cancel_sequence);
1122   EXPECT_CALL(observer, OnFrameCanceled(FrameId::first() + 1))
1123       .Times(1)
1124       .InSequence(cancel_sequence);
1125 
1126   // With all the expectations/sequences in-place, let 'er rip!
1127   EncodedFrameWithBuffer frames[3];
1128   for (int i = 0; i < 3; ++i) {
1129     PopulateFrameWithDefaults(FrameId::first() + i,
1130                               FakeClock::now() - kCaptureDelay, i,
1131                               kFrameDataSize, &frames[i]);
1132     ASSERT_EQ(Sender::OK, sender()->EnqueueFrame(frames[i]));
1133     SimulateExecution(kFrameDuration);
1134   }
1135   SimulateExecution(kTargetPlayoutDelay);
1136   Mock::VerifyAndClearExpectations(receiver());
1137   EXPECT_EQ(0, sender()->GetInFlightFrameCount());
1138 
1139   // The Sender should not be transmitting anything from now on since all frames
1140   // are known to have been completely received.
1141   EXPECT_CALL(*receiver(), OnRtpPacket(_)).Times(0);
1142   SimulateExecution(10 * kTargetPlayoutDelay);
1143 
1144   ExpectFramesReceivedCorrectly(frames, receiver()->TakeCompleteFrames());
1145 }
1146 
1147 }  // namespace
1148 }  // namespace cast
1149 }  // namespace openscreen
1150