1 // Copyright 2016 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 "components/mirroring/browser/cast_remoting_sender.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "base/macros.h"
11 #include "base/run_loop.h"
12 #include "base/time/default_tick_clock.h"
13 #include "content/public/test/browser_task_environment.h"
14 #include "media/cast/constants.h"
15 #include "media/cast/net/cast_transport.h"
16 #include "media/cast/test/utility/default_config.h"
17 #include "media/mojo/mojom/remoting.mojom.h"
18 #include "mojo/public/cpp/bindings/remote.h"
19 #include "mojo/public/cpp/system/data_pipe.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace mirroring {
23
24 namespace {
25
26 // Data pipe capacity is 1KB.
27 constexpr int kDataPipeCapacity = 1024;
28
29 // Implements the CastTransport interface to capture output from the
30 // CastRemotingSender.
31 class FakeTransport : public media::cast::CastTransport {
32 public:
FakeTransport()33 FakeTransport() {}
~FakeTransport()34 ~FakeTransport() final {}
35
TakeSentFrames(std::vector<media::cast::EncodedFrame> * frames)36 void TakeSentFrames(std::vector<media::cast::EncodedFrame>* frames) {
37 frames->swap(sent_frames_);
38 sent_frames_.clear();
39 }
40
TakeCanceledFrameIds(std::vector<media::cast::FrameId> * frame_ids)41 void TakeCanceledFrameIds(std::vector<media::cast::FrameId>* frame_ids) {
42 frame_ids->swap(canceled_frame_ids_);
43 canceled_frame_ids_.clear();
44 }
45
WaitForKickstart()46 media::cast::FrameId WaitForKickstart() {
47 base::RunLoop run_loop;
48 kickstarted_callback_ = run_loop.QuitClosure();
49 run_loop.Run();
50 return kickstarted_frame_id_;
51 }
52
53 protected:
InsertFrame(uint32_t ssrc,const media::cast::EncodedFrame & frame)54 void InsertFrame(uint32_t ssrc,
55 const media::cast::EncodedFrame& frame) final {
56 sent_frames_.push_back(frame);
57 }
58
CancelSendingFrames(uint32_t ssrc,const std::vector<media::cast::FrameId> & frame_ids)59 void CancelSendingFrames(
60 uint32_t ssrc,
61 const std::vector<media::cast::FrameId>& frame_ids) final {
62 for (media::cast::FrameId frame_id : frame_ids)
63 canceled_frame_ids_.push_back(frame_id);
64 }
65
ResendFrameForKickstart(uint32_t ssrc,media::cast::FrameId frame_id)66 void ResendFrameForKickstart(uint32_t ssrc,
67 media::cast::FrameId frame_id) final {
68 kickstarted_frame_id_ = frame_id;
69 if (!kickstarted_callback_.is_null())
70 std::move(kickstarted_callback_).Run();
71 }
72
73 // The rest of the interface is not used for these tests.
SendSenderReport(uint32_t ssrc,base::TimeTicks current_time,media::cast::RtpTimeTicks current_time_as_rtp_timestamp)74 void SendSenderReport(
75 uint32_t ssrc,
76 base::TimeTicks current_time,
77 media::cast::RtpTimeTicks current_time_as_rtp_timestamp) final {}
AddValidRtpReceiver(uint32_t rtp_sender_ssrc,uint32_t rtp_receiver_ssrc)78 void AddValidRtpReceiver(uint32_t rtp_sender_ssrc,
79 uint32_t rtp_receiver_ssrc) final {}
InitializeRtpReceiverRtcpBuilder(uint32_t rtp_receiver_ssrc,const media::cast::RtcpTimeData & time_data)80 void InitializeRtpReceiverRtcpBuilder(
81 uint32_t rtp_receiver_ssrc,
82 const media::cast::RtcpTimeData& time_data) final {}
AddCastFeedback(const media::cast::RtcpCastMessage & cast_message,base::TimeDelta target_delay)83 void AddCastFeedback(const media::cast::RtcpCastMessage& cast_message,
84 base::TimeDelta target_delay) final {}
AddPli(const media::cast::RtcpPliMessage & pli_message)85 void AddPli(const media::cast::RtcpPliMessage& pli_message) final {}
AddRtcpEvents(const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents & e)86 void AddRtcpEvents(
87 const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents& e) final {}
AddRtpReceiverReport(const media::cast::RtcpReportBlock & b)88 void AddRtpReceiverReport(const media::cast::RtcpReportBlock& b) final {}
SendRtcpFromRtpReceiver()89 void SendRtcpFromRtpReceiver() final {}
SetOptions(const base::DictionaryValue & options)90 void SetOptions(const base::DictionaryValue& options) final {}
91
92 private:
93 std::vector<media::cast::EncodedFrame> sent_frames_;
94 std::vector<media::cast::FrameId> canceled_frame_ids_;
95
96 base::RepeatingClosure kickstarted_callback_;
97 media::cast::FrameId kickstarted_frame_id_;
98
99 DISALLOW_COPY_AND_ASSIGN(FakeTransport);
100 };
101
102 } // namespace
103
104 class CastRemotingSenderTest : public ::testing::Test {
105 protected:
CastRemotingSenderTest()106 CastRemotingSenderTest()
107 : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP),
108 expecting_error_callback_run_(false) {
109 media::cast::FrameSenderConfig video_config =
110 media::cast::GetDefaultVideoSenderConfig();
111 video_config.rtp_payload_type = media::cast::RtpPayloadType::REMOTE_VIDEO;
112 transport_config_.ssrc = video_config.sender_ssrc;
113 transport_config_.rtp_stream_id = 5;
114 transport_config_.feedback_ssrc = video_config.receiver_ssrc;
115 transport_config_.rtp_payload_type = video_config.rtp_payload_type;
116 transport_config_.aes_key = video_config.aes_key;
117 transport_config_.aes_iv_mask = video_config.aes_iv_mask;
118 remoting_sender_.reset(new CastRemotingSender(
119 &transport_, transport_config_, base::TimeDelta::FromMilliseconds(1),
120 base::BindRepeating(&CastRemotingSenderTest::ReceivedLoggingEvents,
121 base::Unretained(this))));
122 // Give CastRemotingSender a small RTT measurement to prevent kickstart
123 // testing from taking too long.
124 remoting_sender_->OnReceivedRtt(base::TimeDelta::FromMilliseconds(1));
125
126 const MojoCreateDataPipeOptions data_pipe_options{
127 sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1,
128 kDataPipeCapacity};
129 mojo::ScopedDataPipeConsumerHandle consumer_end;
130 CHECK_EQ(MOJO_RESULT_OK,
131 mojo::CreateDataPipe(&data_pipe_options, &producer_end_,
132 &consumer_end));
133
134 CastRemotingSender::FindAndBind(
135 transport_config_.rtp_stream_id, std::move(consumer_end),
136 sender_.BindNewPipeAndPassReceiver(),
137 base::BindOnce(&CastRemotingSenderTest::OnError,
138 base::Unretained(this)));
139
140 RunPendingTasks();
141 }
142
~CastRemotingSenderTest()143 ~CastRemotingSenderTest() override {}
144
TearDown()145 void TearDown() final {
146 remoting_sender_.reset();
147 // Allow any pending tasks to run before destruction.
148 RunPendingTasks();
149 }
150
151 // Allow pending tasks, such as Mojo method calls, to execute.
RunPendingTasks()152 static void RunPendingTasks() { base::RunLoop().RunUntilIdle(); }
153
154 protected:
latest_acked_frame_id() const155 media::cast::FrameId latest_acked_frame_id() const {
156 return remoting_sender_->latest_acked_frame_id_;
157 }
158
NumberOfFramesInFlight()159 int NumberOfFramesInFlight() {
160 return remoting_sender_->NumberOfFramesInFlight();
161 }
162
GetSizeOfNextFrameData()163 size_t GetSizeOfNextFrameData() {
164 return remoting_sender_->next_frame_data_.size();
165 }
166
IsFlowRestartPending() const167 bool IsFlowRestartPending() const {
168 return remoting_sender_->flow_restart_pending_;
169 }
170
ProduceDataChunk(size_t offset,size_t size)171 bool ProduceDataChunk(size_t offset, size_t size) WARN_UNUSED_RESULT {
172 std::vector<uint8_t> fake_chunk(size);
173 for (size_t i = 0; i < size; ++i)
174 fake_chunk[i] = static_cast<uint8_t>(offset + i);
175 uint32_t num_bytes = fake_chunk.size();
176 return producer_end_->WriteData(fake_chunk.data(), &num_bytes,
177 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE) ==
178 MOJO_RESULT_OK;
179 }
180
SendFrame(uint32_t size)181 void SendFrame(uint32_t size) { remoting_sender_->SendFrame(size); }
182
CancelInFlightData()183 void CancelInFlightData() { remoting_sender_->CancelInFlightData(); }
184
TakeSentFrames(std::vector<media::cast::EncodedFrame> * frames)185 void TakeSentFrames(std::vector<media::cast::EncodedFrame>* frames) {
186 transport_.TakeSentFrames(frames);
187 }
188
ExpectOneFrameWasSent(size_t expected_payload_size)189 bool ExpectOneFrameWasSent(size_t expected_payload_size) {
190 std::vector<media::cast::EncodedFrame> frames;
191 transport_.TakeSentFrames(&frames);
192 EXPECT_EQ(1u, frames.size());
193 if (frames.empty())
194 return false;
195 return ExpectCorrectFrameData(expected_payload_size, frames.front());
196 }
197
AckUpToAndIncluding(media::cast::FrameId frame_id)198 void AckUpToAndIncluding(media::cast::FrameId frame_id) {
199 media::cast::RtcpCastMessage cast_feedback(transport_config_.feedback_ssrc);
200 cast_feedback.ack_frame_id = frame_id;
201 remoting_sender_->OnReceivedCastMessage(cast_feedback);
202 }
203
AckOldestInFlightFrames(int count)204 void AckOldestInFlightFrames(int count) {
205 AckUpToAndIncluding(latest_acked_frame_id() + count);
206 }
207
208 // Blocks the caller indefinitely, until a kickstart frame is sent, and then
209 // returns the FrameId of the kickstarted-frame.
WaitForKickstart()210 media::cast::FrameId WaitForKickstart() {
211 return transport_.WaitForKickstart();
212 }
213
ExpectNoFramesCanceled()214 bool ExpectNoFramesCanceled() {
215 std::vector<media::cast::FrameId> frame_ids;
216 transport_.TakeCanceledFrameIds(&frame_ids);
217 return frame_ids.empty();
218 }
219
ExpectFramesCanceled(media::cast::FrameId first_frame_id,media::cast::FrameId last_frame_id)220 bool ExpectFramesCanceled(media::cast::FrameId first_frame_id,
221 media::cast::FrameId last_frame_id) {
222 std::vector<media::cast::FrameId> frame_ids;
223 transport_.TakeCanceledFrameIds(&frame_ids);
224 auto begin = frame_ids.begin();
225 auto end = frame_ids.end();
226 for (auto fid = first_frame_id; fid <= last_frame_id; ++fid) {
227 auto new_end = std::remove(begin, end, fid);
228 if (new_end == end)
229 return false;
230 end = new_end;
231 }
232 return begin == end;
233 }
234
ExpectCorrectFrameData(size_t expected_payload_size,const media::cast::EncodedFrame & frame)235 static bool ExpectCorrectFrameData(size_t expected_payload_size,
236 const media::cast::EncodedFrame& frame) {
237 if (expected_payload_size != frame.data.size()) {
238 ADD_FAILURE() << "Expected frame data size != frame.data.size(): "
239 << expected_payload_size << " vs " << frame.data.size();
240 return false;
241 }
242 for (size_t i = 0; i < expected_payload_size; ++i) {
243 if (static_cast<uint8_t>(frame.data[i]) != static_cast<uint8_t>(i)) {
244 ADD_FAILURE() << "Frame data byte mismatch at offset " << i;
245 return false;
246 }
247 }
248 return true;
249 }
250
ReceivedLoggingEvents(const std::vector<media::cast::FrameEvent> & events)251 void ReceivedLoggingEvents(
252 const std::vector<media::cast::FrameEvent>& events) {
253 EXPECT_FALSE(events.empty());
254 ++num_times_logging_callback_called_;
255 }
256
257 int num_times_logging_callback_called_ = 0;
258
259 private:
OnError()260 void OnError() { CHECK(expecting_error_callback_run_); }
261
262 content::BrowserTaskEnvironment task_environment_;
263 media::cast::CastTransportRtpConfig transport_config_;
264 FakeTransport transport_;
265 std::unique_ptr<CastRemotingSender> remoting_sender_;
266 mojo::Remote<media::mojom::RemotingDataStreamSender> sender_;
267 mojo::ScopedDataPipeProducerHandle producer_end_;
268 bool expecting_error_callback_run_;
269
270 private:
271 DISALLOW_COPY_AND_ASSIGN(CastRemotingSenderTest);
272 };
273
TEST_F(CastRemotingSenderTest,SendsFramesViaMojoDataPipe)274 TEST_F(CastRemotingSenderTest, SendsFramesViaMojoDataPipe) {
275 // One 256-byte chunk pushed through the data pipe to make one frame.
276 ASSERT_TRUE(ProduceDataChunk(0, 256));
277 SendFrame(256);
278 RunPendingTasks();
279 EXPECT_TRUE(ExpectOneFrameWasSent(256));
280 AckOldestInFlightFrames(1);
281 EXPECT_EQ(media::cast::FrameId::first(), latest_acked_frame_id());
282
283 // Four 256-byte chunks pushed through the data pipe to make one frame.
284 SendFrame(1024);
285 for (int i = 0; i < 4; ++i) {
286 ASSERT_TRUE(ProduceDataChunk(i * 256, 256));
287 }
288 RunPendingTasks();
289 EXPECT_TRUE(ExpectOneFrameWasSent(1024));
290 AckOldestInFlightFrames(1);
291 EXPECT_EQ(media::cast::FrameId::first() + 1, latest_acked_frame_id());
292
293 // 10 differently-sized chunks pushed through the data pipe to make one frame
294 // that is larger than the data pipe's total capacity.
295 SendFrame(6665);
296 size_t offset = 0;
297 for (int i = 0; i < 10; ++i) {
298 const size_t chunk_size = 500 + i * 37;
299 ASSERT_TRUE(ProduceDataChunk(offset, chunk_size));
300 RunPendingTasks();
301 offset += chunk_size;
302 }
303 RunPendingTasks();
304 EXPECT_TRUE(ExpectOneFrameWasSent(6665));
305 AckOldestInFlightFrames(1);
306 EXPECT_EQ(media::cast::FrameId::first() + 2, latest_acked_frame_id());
307 }
308
TEST_F(CastRemotingSenderTest,SendsMultipleFramesWithDelayedAcks)309 TEST_F(CastRemotingSenderTest, SendsMultipleFramesWithDelayedAcks) {
310 // Send 4 frames.
311 for (int i = 0; i < 4; ++i) {
312 ASSERT_TRUE(ProduceDataChunk(0, 16));
313 SendFrame(16);
314 }
315 RunPendingTasks();
316 EXPECT_EQ(4, NumberOfFramesInFlight());
317 EXPECT_TRUE(ExpectNoFramesCanceled());
318
319 // Ack one frame.
320 AckOldestInFlightFrames(1);
321 EXPECT_EQ(3, NumberOfFramesInFlight());
322 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
323 media::cast::FrameId::first()));
324
325 // Ack all.
326 AckOldestInFlightFrames(3);
327 EXPECT_EQ(0, NumberOfFramesInFlight());
328 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
329 media::cast::FrameId::first() + 3));
330 }
331
TEST_F(CastRemotingSenderTest,KickstartsIfAckNotTimely)332 TEST_F(CastRemotingSenderTest, KickstartsIfAckNotTimely) {
333 EXPECT_EQ(0, num_times_logging_callback_called_);
334
335 // Send first frame and don't Ack it. Expect the first frame to be
336 // kickstarted.
337 ASSERT_TRUE(ProduceDataChunk(0, 16));
338 SendFrame(16);
339 EXPECT_EQ(media::cast::FrameId::first(), WaitForKickstart());
340 EXPECT_EQ(1, NumberOfFramesInFlight());
341
342 // Send 3 more frames and don't Ack them either. Expect the 4th frame to be
343 // kickstarted.
344 for (int i = 0; i < 3; ++i) {
345 ASSERT_TRUE(ProduceDataChunk(0, 16));
346 SendFrame(16);
347 }
348 EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
349 EXPECT_EQ(4, NumberOfFramesInFlight());
350
351 // Ack the first two frames and wait for another kickstart (for the 4th frame
352 // again).
353 AckOldestInFlightFrames(2);
354 EXPECT_EQ(2, NumberOfFramesInFlight());
355 EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
356
357 // This test takes enough time to trigger the logging callback.
358 EXPECT_GT(num_times_logging_callback_called_, 2);
359 }
360
TEST_F(CastRemotingSenderTest,CancelsUnsentFrame)361 TEST_F(CastRemotingSenderTest, CancelsUnsentFrame) {
362 EXPECT_EQ(0u, GetSizeOfNextFrameData());
363 SendFrame(16);
364 SendFrame(32);
365 CancelInFlightData();
366 RunPendingTasks();
367
368 // Provide the data. Both frames should not be sent out.
369 ASSERT_TRUE(ProduceDataChunk(0, 16));
370 RunPendingTasks();
371 ASSERT_TRUE(ProduceDataChunk(0, 32));
372 RunPendingTasks();
373 EXPECT_EQ(0, NumberOfFramesInFlight());
374
375 // Since no frames were sent, none should have been passed to the
376 // CastTransport, and none should have been canceled.
377 std::vector<media::cast::EncodedFrame> frames;
378 TakeSentFrames(&frames);
379 EXPECT_TRUE(frames.empty());
380 EXPECT_TRUE(ExpectNoFramesCanceled());
381 }
382
383 // http://crbug.com/647423
384 #define MAYBE_CancelsFramesInFlight DISABLED_CancelsFramesInFlight
TEST_F(CastRemotingSenderTest,MAYBE_CancelsFramesInFlight)385 TEST_F(CastRemotingSenderTest, MAYBE_CancelsFramesInFlight) {
386 EXPECT_TRUE(IsFlowRestartPending());
387
388 // Send 10 frames.
389 for (int i = 0; i < 10; ++i) {
390 ASSERT_TRUE(ProduceDataChunk(0, 16));
391 SendFrame(16);
392 }
393 RunPendingTasks();
394 EXPECT_FALSE(IsFlowRestartPending());
395 EXPECT_EQ(10, NumberOfFramesInFlight());
396
397 // Ack the first frame.
398 AckOldestInFlightFrames(1);
399 EXPECT_FALSE(IsFlowRestartPending());
400 EXPECT_EQ(9, NumberOfFramesInFlight());
401 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
402 media::cast::FrameId::first()));
403
404 // Cancel all in-flight data. This should cause the remaining 9 frames to be
405 // canceled.
406 CancelInFlightData();
407 RunPendingTasks();
408 EXPECT_TRUE(IsFlowRestartPending());
409 EXPECT_EQ(0, NumberOfFramesInFlight());
410 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
411 media::cast::FrameId::first() + 9));
412
413 // Send one more frame and ack it.
414 ASSERT_TRUE(ProduceDataChunk(0, 16));
415 SendFrame(16);
416 RunPendingTasks();
417 EXPECT_FALSE(IsFlowRestartPending());
418 EXPECT_EQ(1, NumberOfFramesInFlight());
419 AckOldestInFlightFrames(1);
420 EXPECT_EQ(0, NumberOfFramesInFlight());
421
422 // Check that the dependency metadata was set correctly to indicate a frame
423 // that immediately follows a CancelInFlightData() operation.
424 std::vector<media::cast::EncodedFrame> frames;
425 TakeSentFrames(&frames);
426 ASSERT_EQ(11u, frames.size());
427 for (size_t i = 0; i < 11; ++i) {
428 const media::cast::EncodedFrame& frame = frames[i];
429 EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
430 if (i == 0 || i == 10)
431 EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
432 else
433 EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
434 }
435 }
436
TEST_F(CastRemotingSenderTest,WaitsForDataBeforeConsumingFromDataPipe)437 TEST_F(CastRemotingSenderTest, WaitsForDataBeforeConsumingFromDataPipe) {
438 // Queue up and issue Mojo calls to consume three frames. Since no data has
439 // been pushed into the pipe yet no frames should be sent.
440 for (int i = 0; i < 3; ++i) {
441 SendFrame(4);
442 }
443 RunPendingTasks();
444 EXPECT_TRUE(IsFlowRestartPending());
445 EXPECT_EQ(0, NumberOfFramesInFlight());
446
447 // Push the data for one frame into the data pipe. This should trigger input
448 // processing and allow one frame to be sent.
449 ASSERT_TRUE(ProduceDataChunk(0, 4));
450 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
451 EXPECT_FALSE(IsFlowRestartPending());
452 EXPECT_EQ(1, NumberOfFramesInFlight());
453
454 // Now push the data for the other two frames into the data pipe and expect
455 // two more frames to be sent.
456 ASSERT_TRUE(ProduceDataChunk(0, 4));
457 ASSERT_TRUE(ProduceDataChunk(0, 4));
458 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
459 EXPECT_FALSE(IsFlowRestartPending());
460 EXPECT_EQ(3, NumberOfFramesInFlight());
461 }
462
TEST_F(CastRemotingSenderTest,WaitsForDataThenDiscardsCanceledData)463 TEST_F(CastRemotingSenderTest, WaitsForDataThenDiscardsCanceledData) {
464 // Queue up and issue Mojo calls to consume data chunks and send three
465 // frames. Since no data has been pushed into the pipe yet no frames should be
466 // sent.
467 for (int i = 0; i < 3; ++i) {
468 SendFrame(4);
469 }
470 RunPendingTasks();
471 EXPECT_EQ(0, NumberOfFramesInFlight());
472
473 // Cancel all in-flight data.
474 CancelInFlightData();
475 RunPendingTasks();
476
477 // Now, push the data for one frame into the data pipe. Because of the
478 // cancellation, no frames should be sent.
479 ASSERT_TRUE(ProduceDataChunk(0, 4));
480 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
481 EXPECT_EQ(0, NumberOfFramesInFlight());
482
483 // Now push the data for the other two frames into the data pipe and still no
484 // frames should be sent.
485 ASSERT_TRUE(ProduceDataChunk(0, 4));
486 ASSERT_TRUE(ProduceDataChunk(0, 4));
487 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
488 EXPECT_EQ(0, NumberOfFramesInFlight());
489
490 // Now issue calls to send another frame and then push the data for it into
491 // the data pipe. Expect to see the frame gets sent since it was provided
492 // after the CancelInFlightData().
493 SendFrame(4);
494 RunPendingTasks();
495 EXPECT_EQ(0, NumberOfFramesInFlight());
496 ASSERT_TRUE(ProduceDataChunk(0, 4));
497 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
498 EXPECT_EQ(1, NumberOfFramesInFlight());
499 }
500
TEST_F(CastRemotingSenderTest,StopsConsumingWhileTooManyFramesAreInFlight)501 TEST_F(CastRemotingSenderTest, StopsConsumingWhileTooManyFramesAreInFlight) {
502 EXPECT_TRUE(IsFlowRestartPending());
503
504 // Send out the maximum possible number of unacked frames, but don't ack any
505 // yet.
506 for (int i = 0; i < media::cast::kMaxUnackedFrames; ++i) {
507 ASSERT_TRUE(ProduceDataChunk(0, 4));
508 SendFrame(4);
509 }
510 RunPendingTasks();
511 EXPECT_FALSE(IsFlowRestartPending());
512 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
513 // Note: All frames should have been sent to the Transport, and so
514 // CastRemotingSender's single-frame data buffer should be empty.
515 EXPECT_EQ(0u, GetSizeOfNextFrameData());
516
517 // When the client provides one more frame, CastRemotingSender will begin
518 // queuing input operations instead of sending the the frame to the
519 // CastTransport.
520 ASSERT_TRUE(ProduceDataChunk(0, 4));
521 SendFrame(4);
522 RunPendingTasks();
523 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
524 // Note: The unsent frame resides in CastRemotingSender's single-frame data
525 // buffer.
526 EXPECT_EQ(4u, GetSizeOfNextFrameData());
527
528 // Ack the the first frame and expect sending to resume, with one more frame
529 // being sent to the CastTransport.
530 AckOldestInFlightFrames(1);
531 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
532 // Note: Only one frame was backlogged, and so CastRemotingSender's
533 // single-frame data buffer should be empty.
534 EXPECT_EQ(0u, GetSizeOfNextFrameData());
535
536 // Attempting to send another frame will once again cause CastRemotingSender
537 // to queue input operations.
538 ASSERT_TRUE(ProduceDataChunk(0, 4));
539 SendFrame(4);
540 RunPendingTasks();
541 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
542 // Note: Once again, CastRemotingSender's single-frame data buffer contains an
543 // unsent frame.
544 EXPECT_EQ(4u, GetSizeOfNextFrameData());
545
546 // Send more frames: Some number of frames will queue-up inside the Mojo data
547 // pipe (the exact number depends on the data pipe's capacity, and how Mojo
548 // manages memory internally). At some point, attempting to produce and push
549 // another frame will fail because the data pipe is full.
550 int num_frames_in_data_pipe = 0;
551 while (ProduceDataChunk(0, 768)) {
552 ++num_frames_in_data_pipe;
553 SendFrame(768);
554 RunPendingTasks();
555 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
556 // Note: CastRemotingSender's single-frame data buffer should still contain
557 // the unsent 4-byte frame.
558 EXPECT_EQ(4u, GetSizeOfNextFrameData());
559 }
560 EXPECT_LT(0, num_frames_in_data_pipe);
561
562 // Ack one frame at a time until the backlog in the Mojo data pipe has
563 // cleared.
564 int remaining_frames_in_data_pipe = num_frames_in_data_pipe;
565 while (remaining_frames_in_data_pipe > 0) {
566 AckOldestInFlightFrames(1);
567 RunPendingTasks();
568 --remaining_frames_in_data_pipe;
569 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
570 EXPECT_EQ(768u, GetSizeOfNextFrameData());
571 }
572
573 // Ack one more frame. There should no longer be a backlog on the input side
574 // of things.
575 AckOldestInFlightFrames(1);
576 RunPendingTasks(); // No additional Mojo method calls should be made here.
577 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
578 // The single-frame data buffer should be empty to indicate no input backlog.
579 EXPECT_EQ(0u, GetSizeOfNextFrameData());
580
581 // Ack all but one frame.
582 AckOldestInFlightFrames(NumberOfFramesInFlight() - 1);
583 EXPECT_EQ(1, NumberOfFramesInFlight());
584 // ..and one more frame can be sent immediately.
585 ASSERT_TRUE(ProduceDataChunk(0, 4));
586 SendFrame(4);
587 RunPendingTasks();
588 EXPECT_EQ(2, NumberOfFramesInFlight());
589 // ...and ack these last two frames.
590 AckOldestInFlightFrames(2);
591 EXPECT_EQ(0, NumberOfFramesInFlight());
592
593 // Finally, examine all frames that were sent to the CastTransport, and
594 // confirm their metadata and data is valid.
595 std::vector<media::cast::EncodedFrame> frames;
596 TakeSentFrames(&frames);
597 const size_t total_frames_sent =
598 media::cast::kMaxUnackedFrames + 2 + num_frames_in_data_pipe + 1;
599 ASSERT_EQ(total_frames_sent, frames.size());
600 media::cast::RtpTimeTicks last_rtp_timestamp =
601 media::cast::RtpTimeTicks() - media::cast::RtpTimeDelta::FromTicks(1);
602 for (size_t i = 0; i < total_frames_sent; ++i) {
603 const media::cast::EncodedFrame& frame = frames[i];
604 EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
605 if (i == 0) {
606 EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
607 EXPECT_EQ(media::cast::FrameId::first() + i, frame.referenced_frame_id);
608 } else {
609 EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
610 EXPECT_EQ(media::cast::FrameId::first() + i - 1,
611 frame.referenced_frame_id);
612 }
613
614 // RTP timestamp must be monotonically increasing.
615 EXPECT_GT(frame.rtp_timestamp, last_rtp_timestamp);
616 last_rtp_timestamp = frame.rtp_timestamp;
617
618 size_t expected_frame_size = 4;
619 if ((i >= media::cast::kMaxUnackedFrames + 2u) &&
620 (i < media::cast::kMaxUnackedFrames + 2u + num_frames_in_data_pipe)) {
621 expected_frame_size = 768;
622 }
623 EXPECT_TRUE(ExpectCorrectFrameData(expected_frame_size, frame));
624 }
625 }
626
627 } // namespace mirroring
628