Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: chrome/browser/media/cast_remoting_sender_unittest.cc

Issue 2310753002: Media Remoting: Data/Control plumbing between renderer and Media Router. (Closed)
Patch Set: REBASE. Plus, merge with CastRemotingSender and add more unit tests. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
xjz 2016/09/15 18:01:49 Great job! Awesome tests!!! :)
4 4
5 #include "chrome/browser/media/cast_remoting_sender.h" 5 #include "chrome/browser/media/cast_remoting_sender.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback_helpers.h"
10 #include "base/compiler_specific.h"
8 #include "base/macros.h" 11 #include "base/macros.h"
9 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
10 #include "base/test/simple_test_tick_clock.h" 13 #include "base/run_loop.h"
11 #include "media/base/fake_single_thread_task_runner.h" 14 #include "base/time/default_tick_clock.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
12 #include "media/cast/cast_environment.h" 16 #include "media/cast/cast_environment.h"
13 #include "media/cast/constants.h" 17 #include "media/cast/constants.h"
14 #include "media/cast/logging/simple_event_subscriber.h" 18 #include "media/cast/net/cast_transport.h"
15 #include "media/cast/net/cast_transport_config.h"
16 #include "media/cast/net/cast_transport_impl.h"
17 #include "media/cast/net/pacing/paced_sender.h"
18 #include "media/cast/test/utility/default_config.h" 19 #include "media/cast/test/utility/default_config.h"
19 #include "testing/gmock/include/gmock/gmock.h" 20 #include "media/mojo/interfaces/remoting.mojom.h"
21 #include "mojo/public/cpp/system/data_pipe.h"
20 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
21 23
22 namespace cast { 24 namespace cast {
23 25
24 namespace { 26 namespace {
25 27
26 // Number of bytes in each faked frame. 28 // Data pipe capacity is 1KB.
27 constexpr int kFrameSize = 5000; 29 constexpr int kDataPipeCapacity = 1024;
28 30
29 class TestPacketSender : public media::cast::PacketTransport { 31 // Implements the CastTransport interface to capture output from the
32 // CastRemotingSender.
33 class FakeTransport : public media::cast::CastTransport {
30 public: 34 public:
31 TestPacketSender() 35 FakeTransport() {}
32 : number_of_rtp_packets_(0), number_of_rtcp_packets_(0), paused_(false) {} 36 ~FakeTransport() final {}
33 37
34 // A singular packet implies a RTCP packet. 38 void TakeSentFrames(std::vector<media::cast::EncodedFrame>* frames) {
35 bool SendPacket(media::cast::PacketRef packet, 39 frames->swap(sent_frames_);
36 const base::Closure& cb) final { 40 sent_frames_.clear();
37 if (paused_) {
38 stored_packet_ = packet;
39 callback_ = cb;
40 return false;
41 }
42 if (media::cast::IsRtcpPacket(&packet->data[0], packet->data.size())) {
43 ++number_of_rtcp_packets_;
44 } else {
45 ++number_of_rtp_packets_;
46 }
47 return true;
48 } 41 }
49 42
50 int64_t GetBytesSent() final { return 0; } 43 void TakeCanceledFrameIds(std::vector<media::cast::FrameId>* frame_ids) {
51 44 frame_ids->swap(canceled_frame_ids_);
52 void StartReceiving(const media::cast::PacketReceiverCallbackWithStatus& 45 canceled_frame_ids_.clear();
53 packet_receiver) final {}
54
55 void StopReceiving() final {}
56
57 int number_of_rtp_packets() const { return number_of_rtp_packets_; }
58
59 int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }
60
61 void SetPause(bool paused) {
62 paused_ = paused;
63 if (!paused && stored_packet_.get()) {
64 SendPacket(stored_packet_, callback_);
65 callback_.Run();
66 }
67 } 46 }
68 47
48 media::cast::FrameId WaitForKickstart() {
49 base::RunLoop run_loop;
50 kickstarted_callback_ = run_loop.QuitClosure();
51 run_loop.Run();
52 return kickstarted_frame_id_;
53 }
54
55 protected:
56 void InsertFrame(uint32_t ssrc,
57 const media::cast::EncodedFrame& frame) final {
58 sent_frames_.push_back(frame);
59 }
60
61 void CancelSendingFrames(
62 uint32_t ssrc, const std::vector<media::cast::FrameId>& frame_ids) final {
63 for (media::cast::FrameId frame_id : frame_ids)
64 canceled_frame_ids_.push_back(frame_id);
65 }
66
67 void ResendFrameForKickstart(uint32_t ssrc,
68 media::cast::FrameId frame_id) final {
69 kickstarted_frame_id_ = frame_id;
70 if (!kickstarted_callback_.is_null())
71 base::ResetAndReturn(&kickstarted_callback_).Run();
72 }
73
74 // The rest of the interface is not used for these tests.
75 void SendSenderReport(
76 uint32_t ssrc, base::TimeTicks current_time,
77 media::cast::RtpTimeTicks current_time_as_rtp_timestamp) final {}
78 void AddValidRtpReceiver(uint32_t rtp_sender_ssrc,
79 uint32_t rtp_receiver_ssrc) final {}
80 void InitializeRtpReceiverRtcpBuilder(
81 uint32_t rtp_receiver_ssrc,
82 const media::cast::RtcpTimeData& time_data) final {}
83 void AddCastFeedback(const media::cast::RtcpCastMessage& cast_message,
84 base::TimeDelta target_delay) final {}
85 void AddPli(const media::cast::RtcpPliMessage& pli_message) final {}
86 void AddRtcpEvents(
87 const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents& e) final {}
88 void AddRtpReceiverReport(const media::cast::RtcpReportBlock& b) final {}
89 void SendRtcpFromRtpReceiver() final {}
90 void SetOptions(const base::DictionaryValue& options) final {}
91
69 private: 92 private:
70 int number_of_rtp_packets_; 93 const scoped_refptr<media::cast::CastEnvironment> cast_environment_;
71 int number_of_rtcp_packets_; 94 std::vector<media::cast::EncodedFrame> sent_frames_;
72 bool paused_; 95 std::vector<media::cast::FrameId> canceled_frame_ids_;
73 base::Closure callback_;
74 media::cast::PacketRef stored_packet_;
75 96
76 DISALLOW_COPY_AND_ASSIGN(TestPacketSender); 97 base::Closure kickstarted_callback_;
77 }; 98 media::cast::FrameId kickstarted_frame_id_;
78 99
79 class DummyClient : public media::cast::CastTransport::Client { 100 DISALLOW_COPY_AND_ASSIGN(FakeTransport);
80 public:
81 DummyClient() {}
82
83 void OnStatusChanged(media::cast::CastTransportStatus status) final {
84 EXPECT_EQ(media::cast::TRANSPORT_STREAM_INITIALIZED, status);
85 };
86 void OnLoggingEventsReceived(
87 std::unique_ptr<std::vector<media::cast::FrameEvent>> frame_events,
88 std::unique_ptr<std::vector<media::cast::PacketEvent>> packet_events)
89 final {}
90 void ProcessRtpPacket(std::unique_ptr<media::cast::Packet> packet) final {}
91
92 DISALLOW_COPY_AND_ASSIGN(DummyClient);
93 }; 101 };
94 102
95 } // namespace 103 } // namespace
96 104
97 class CastRemotingSenderTest : public ::testing::Test { 105 class CastRemotingSenderTest : public ::testing::Test {
98 protected: 106 protected:
99 CastRemotingSenderTest() 107 CastRemotingSenderTest()
100 : testing_clock_(new base::SimpleTestTickClock()), 108 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
101 task_runner_(new media::FakeSingleThreadTaskRunner(testing_clock_)), 109 cast_environment_(new media::cast::CastEnvironment(
102 cast_environment_( 110 base::WrapUnique(new base::DefaultTickClock()),
103 new media::cast::CastEnvironment(base::WrapUnique(testing_clock_), 111 base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr)),
104 task_runner_, 112 expecting_error_callback_run_(false) {
105 task_runner_, 113
106 task_runner_)) {
107 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
108 transport_ = new TestPacketSender();
109 transport_sender_.reset(new media::cast::CastTransportImpl(
110 testing_clock_, base::TimeDelta(), base::MakeUnique<DummyClient>(),
111 base::WrapUnique(transport_), task_runner_));
112 media::cast::FrameSenderConfig video_config = 114 media::cast::FrameSenderConfig video_config =
113 media::cast::GetDefaultVideoSenderConfig(); 115 media::cast::GetDefaultVideoSenderConfig();
114 video_config.rtp_payload_type = media::cast::RtpPayloadType::REMOTE_VIDEO; 116 video_config.rtp_payload_type = media::cast::RtpPayloadType::REMOTE_VIDEO;
115 media::cast::CastTransportRtpConfig transport_config; 117 transport_config_.ssrc = video_config.sender_ssrc;
116 transport_config.ssrc = video_config.sender_ssrc; 118 transport_config_.rtp_stream_id = 5;
117 transport_config.rtp_stream_id = 5; 119 transport_config_.feedback_ssrc = video_config.receiver_ssrc;
118 transport_config.feedback_ssrc = video_config.receiver_ssrc; 120 transport_config_.rtp_payload_type = video_config.rtp_payload_type;
119 transport_config.rtp_payload_type = video_config.rtp_payload_type; 121 transport_config_.aes_key = video_config.aes_key;
120 transport_config.aes_key = video_config.aes_key; 122 transport_config_.aes_iv_mask = video_config.aes_iv_mask;
121 transport_config.aes_iv_mask = video_config.aes_iv_mask;
122 remoting_sender_.reset(new CastRemotingSender( 123 remoting_sender_.reset(new CastRemotingSender(
123 cast_environment_, transport_sender_.get(), transport_config)); 124 cast_environment_, &transport_, transport_config_));
124 task_runner_->RunTasks(); 125 // Give CastRemotingSender a small RTT measurement to prevent kickstart
126 // testing from taking too long.
127 remoting_sender_->OnReceivedRtt(base::TimeDelta::FromMilliseconds(1));
128
129 const MojoCreateDataPipeOptions data_pipe_options{
130 sizeof(MojoCreateDataPipeOptions),
131 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1, kDataPipeCapacity };
132 mojo::ScopedDataPipeConsumerHandle consumer_end;
133 CHECK_EQ(MOJO_RESULT_OK,
134 mojo::CreateDataPipe(&data_pipe_options, &producer_end_,
135 &consumer_end));
136
137 CastRemotingSender::FindAndBind(
138 transport_config_.rtp_stream_id, std::move(consumer_end),
139 GetProxy(&sender_),
140 base::Bind(&CastRemotingSenderTest::OnError, base::Unretained(this)));
141
142 RunPendingTasks();
125 } 143 }
126 144
127 ~CastRemotingSenderTest() override {} 145 ~CastRemotingSenderTest() override {}
128 146
129 void TearDown() final { 147 void TearDown() final {
130 remoting_sender_.reset(); 148 remoting_sender_.reset();
131 task_runner_->RunTasks(); 149 // Allow any pending tasks to run before destruction.
132 } 150 RunPendingTasks();
133 151 }
134 void InsertFrame() { 152
135 remoting_sender_->next_frame_data_.resize(kFrameSize); 153 // Allow pending tasks, such as Mojo method calls, to execute.
136 remoting_sender_->SendFrame(); 154 static void RunPendingTasks() {
137 } 155 base::RunLoop().RunUntilIdle();
138 156 }
139 void OnReceivedCastMessage( 157
140 const media::cast::RtcpCastMessage& cast_feedback) { 158 protected:
141 remoting_sender_->OnReceivedCastMessage(cast_feedback); 159 media::cast::FrameId latest_acked_frame_id() const {
160 return remoting_sender_->latest_acked_frame_id_;
142 } 161 }
143 162
144 int NumberOfFramesInFlight() { 163 int NumberOfFramesInFlight() {
145 return remoting_sender_->NumberOfFramesInFlight(); 164 return remoting_sender_->NumberOfFramesInFlight();
146 } 165 }
147 166
148 void CancelFramesInFlight() { remoting_sender_->CancelFramesInFlight(); } 167 size_t GetSizeOfNextFrameData() {
149 168 return remoting_sender_->next_frame_data_.size();
150 base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment. 169 }
151 const scoped_refptr<media::FakeSingleThreadTaskRunner> task_runner_; 170
171 bool IsFlowControlInRestartingState() const {
172 return remoting_sender_->flow_control_state_ ==
173 CastRemotingSender::RESTARTING;
174 }
175 bool IsFlowControlInConsumingState() const {
176 return remoting_sender_->flow_control_state_ ==
177 CastRemotingSender::CONSUMING;
178 }
179 bool IsFlowControlInPausedState() const {
180 return remoting_sender_->flow_control_state_ ==
181 CastRemotingSender::CONSUME_PAUSED;
182 }
183
184 bool ProduceDataChunk(size_t offset, size_t size) WARN_UNUSED_RESULT {
185 std::vector<uint8_t> fake_chunk(size);
186 for (size_t i = 0; i < size; ++i)
187 fake_chunk[i] = static_cast<uint8_t>(offset + i);
188 uint32_t num_bytes = fake_chunk.size();
189 return mojo::WriteDataRaw(
190 producer_end_.get(), fake_chunk.data(), &num_bytes,
191 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE) == MOJO_RESULT_OK;
192 }
193
194 void PostMojoCallTask_ConsumeDataChunk(size_t offset, size_t size,
195 size_t total_payload_size) {
196 sender_->ConsumeDataChunk(offset, size, total_payload_size);
197 }
198
199 void PostMojoCallTask_SendFrame() {
200 sender_->SendFrame();
201 }
202
203 void PostMojoCallTask_CancelInFlightData() { sender_->CancelInFlightData(); }
204
205 void TakeSentFrames(std::vector<media::cast::EncodedFrame>* frames) {
206 transport_.TakeSentFrames(frames);
207 }
208
209 bool ExpectOneFrameWasSent(size_t expected_payload_size) {
210 std::vector<media::cast::EncodedFrame> frames;
211 transport_.TakeSentFrames(&frames);
212 EXPECT_EQ(1u, frames.size());
213 if (frames.empty())
214 return false;
215 return ExpectCorrectFrameData(expected_payload_size, frames.front());
216 }
217
218 void AckUpToAndIncluding(media::cast::FrameId frame_id) {
219 media::cast::RtcpCastMessage cast_feedback(transport_config_.feedback_ssrc);
220 cast_feedback.ack_frame_id = frame_id;
221 remoting_sender_->OnReceivedCastMessage(cast_feedback);
222 }
223
224 void AckOldestInFlightFrames(int count) {
225 AckUpToAndIncluding(latest_acked_frame_id() + count);
226 }
227
228 // Blocks the caller indefinitely, until a kickstart frame is sent, and then
229 // returns the FrameId of the kickstarted-frame.
230 media::cast::FrameId WaitForKickstart() {
231 return transport_.WaitForKickstart();
232 }
233
234 bool ExpectNoFramesCanceled() {
235 std::vector<media::cast::FrameId> frame_ids;
236 transport_.TakeCanceledFrameIds(&frame_ids);
237 return frame_ids.empty();
238 }
239
240 bool ExpectFramesCanceled(media::cast::FrameId first_frame_id,
241 media::cast::FrameId last_frame_id) {
242 std::vector<media::cast::FrameId> frame_ids;
243 transport_.TakeCanceledFrameIds(&frame_ids);
244 auto begin = frame_ids.begin();
245 auto end = frame_ids.end();
246 for (auto fid = first_frame_id; fid <= last_frame_id; ++fid) {
247 auto new_end = std::remove(begin, end, fid);
248 if (new_end == end)
249 return false;
250 end = new_end;
251 }
252 return begin == end;
253 }
254
255 static bool ExpectCorrectFrameData(size_t expected_payload_size,
256 const media::cast::EncodedFrame& frame) {
257 if (expected_payload_size != frame.data.size()) {
258 ADD_FAILURE() << "Expected frame data size != frame.data.size(): "
259 << expected_payload_size << " vs " << frame.data.size();
260 return false;
261 }
262 for (size_t i = 0; i < expected_payload_size; ++i) {
263 if (static_cast<uint8_t>(frame.data[i]) != static_cast<uint8_t>(i)) {
264 ADD_FAILURE() << "Frame data byte mismatch at offset " << i;
265 return false;
266 }
267 }
268 return true;
269 }
270
271 private:
272 void OnError() {
273 CHECK(expecting_error_callback_run_);
274 }
275
276 content::TestBrowserThreadBundle thread_bundle_;
152 const scoped_refptr<media::cast::CastEnvironment> cast_environment_; 277 const scoped_refptr<media::cast::CastEnvironment> cast_environment_;
153 TestPacketSender* transport_; // Owned by CastTransport. 278 media::cast::CastTransportRtpConfig transport_config_;
154 std::unique_ptr<media::cast::CastTransportImpl> transport_sender_; 279 FakeTransport transport_;
155 std::unique_ptr<CastRemotingSender> remoting_sender_; 280 std::unique_ptr<CastRemotingSender> remoting_sender_;
281 media::mojom::RemotingDataStreamSenderPtr sender_;
282 mojo::ScopedDataPipeProducerHandle producer_end_;
283 bool expecting_error_callback_run_;
156 284
157 private: 285 private:
158 DISALLOW_COPY_AND_ASSIGN(CastRemotingSenderTest); 286 DISALLOW_COPY_AND_ASSIGN(CastRemotingSenderTest);
159 }; 287 };
160 288
161 TEST_F(CastRemotingSenderTest, SendAndAckEncodedFrame) { 289 TEST_F(CastRemotingSenderTest, SendsFramesViaMojoInterface) {
162 // Send a fake video frame that will be decomposed into 4 packets. 290 // One 256-byte chunk pushed through the data pipe to make one frame.
163 InsertFrame(); 291 ASSERT_TRUE(ProduceDataChunk(0, 256));
164 task_runner_->RunTasks(); 292 PostMojoCallTask_ConsumeDataChunk(0, 256, 256);
165 EXPECT_EQ(4, transport_->number_of_rtp_packets()); 293 PostMojoCallTask_SendFrame();
294 RunPendingTasks();
295 EXPECT_TRUE(ExpectOneFrameWasSent(256));
296 AckOldestInFlightFrames(1);
297 EXPECT_EQ(media::cast::FrameId::first(), latest_acked_frame_id());
298
299 // Four 256-byte chunks pushed through the data pipe to make one frame.
300 for (int i = 0; i < 4; ++i) {
301 ASSERT_TRUE(ProduceDataChunk(i * 256, 256));
302 PostMojoCallTask_ConsumeDataChunk(i * 256, 256, 1024);
303 }
304 PostMojoCallTask_SendFrame();
305 RunPendingTasks();
306 EXPECT_TRUE(ExpectOneFrameWasSent(1024));
307 AckOldestInFlightFrames(1);
308 EXPECT_EQ(media::cast::FrameId::first() + 1, latest_acked_frame_id());
309
310 // 10 differently-sized chunks pushed through the data pipe to make one frame
311 // that is larger than the data pipe's total capacity.
312 size_t offset = 0;
313 for (int i = 0; i < 10; ++i) {
314 const size_t chunk_size = 500 + i * 37;
315 ASSERT_TRUE(ProduceDataChunk(offset, chunk_size));
316 PostMojoCallTask_ConsumeDataChunk(offset, chunk_size, 6665);
317 RunPendingTasks();
318 offset += chunk_size;
319 }
320 PostMojoCallTask_SendFrame();
321 RunPendingTasks();
322 EXPECT_TRUE(ExpectOneFrameWasSent(6665));
323 AckOldestInFlightFrames(1);
324 EXPECT_EQ(media::cast::FrameId::first() + 2, latest_acked_frame_id());
325 }
326
327 TEST_F(CastRemotingSenderTest, SendsMultipleFramesWithDelayedAcks) {
328 // Send 4 frames.
329 for (int i = 0; i < 4; ++i) {
330 ASSERT_TRUE(ProduceDataChunk(0, 16));
331 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
332 PostMojoCallTask_SendFrame();
333 }
334 RunPendingTasks();
335 EXPECT_EQ(4, NumberOfFramesInFlight());
336 EXPECT_TRUE(ExpectNoFramesCanceled());
337
338 // Ack one frame.
339 AckOldestInFlightFrames(1);
340 EXPECT_EQ(3, NumberOfFramesInFlight());
341 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
342 media::cast::FrameId::first()));
343
344 // Ack all.
345 AckOldestInFlightFrames(3);
346 EXPECT_EQ(0, NumberOfFramesInFlight());
347 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
348 media::cast::FrameId::first() + 3));
349 }
350
351 TEST_F(CastRemotingSenderTest, KickstartsIfAckNotTimely) {
352 // Send first frame and don't Ack it. Expect the first frame to be
353 // kickstarted.
354 ASSERT_TRUE(ProduceDataChunk(0, 16));
355 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
356 PostMojoCallTask_SendFrame();
357 EXPECT_EQ(media::cast::FrameId::first(), WaitForKickstart());
166 EXPECT_EQ(1, NumberOfFramesInFlight()); 358 EXPECT_EQ(1, NumberOfFramesInFlight());
167 359
168 // Ack the frame. 360 // Send 3 more frames and don't Ack them either. Expect the 4th frame to be
169 media::cast::RtcpCastMessage cast_feedback(11); 361 // kickstarted.
170 cast_feedback.ack_frame_id = media::cast::FrameId::first(); 362 for (int i = 0; i < 3; ++i) {
171 OnReceivedCastMessage(cast_feedback); 363 ASSERT_TRUE(ProduceDataChunk(0, 16));
364 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
365 PostMojoCallTask_SendFrame();
366 }
367 EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
368 EXPECT_EQ(4, NumberOfFramesInFlight());
369
370 // Ack the first two frames and wait for another kickstart (for the 4th frame
371 // again).
372 AckOldestInFlightFrames(2);
373 EXPECT_EQ(2, NumberOfFramesInFlight());
374 EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
375 }
376
377 TEST_F(CastRemotingSenderTest, CancelsUnsentFrame) {
378 EXPECT_EQ(0u, GetSizeOfNextFrameData());
379 ASSERT_TRUE(ProduceDataChunk(0, 16));
380 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
381 RunPendingTasks();
382 EXPECT_EQ(16u, GetSizeOfNextFrameData());
383 PostMojoCallTask_CancelInFlightData();
384 RunPendingTasks();
385 EXPECT_EQ(0u, GetSizeOfNextFrameData());
386
387 // Since no frames were sent, none should have been passed to the
388 // CastTransport, and none should have been canceled.
389 std::vector<media::cast::EncodedFrame> frames;
390 TakeSentFrames(&frames);
391 EXPECT_TRUE(frames.empty());
392 EXPECT_TRUE(ExpectNoFramesCanceled());
393 }
394
395 TEST_F(CastRemotingSenderTest, CancelsFramesInFlight) {
396 EXPECT_TRUE(IsFlowControlInRestartingState());
397
398 // Send 10 frames.
399 for (int i = 0; i < 10; ++i) {
400 ASSERT_TRUE(ProduceDataChunk(0, 16));
401 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
402 PostMojoCallTask_SendFrame();
403 }
404 RunPendingTasks();
405 EXPECT_TRUE(IsFlowControlInConsumingState());
406 EXPECT_EQ(10, NumberOfFramesInFlight());
407
408 // Ack the first frame.
409 AckOldestInFlightFrames(1);
410 EXPECT_TRUE(IsFlowControlInConsumingState());
411 EXPECT_EQ(9, NumberOfFramesInFlight());
412 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
413 media::cast::FrameId::first()));
414
415 // Cancel all in-flight data. This should cause the remaining 9 frames to be
416 // canceled.
417 PostMojoCallTask_CancelInFlightData();
418 RunPendingTasks();
419 EXPECT_TRUE(IsFlowControlInRestartingState());
172 EXPECT_EQ(0, NumberOfFramesInFlight()); 420 EXPECT_EQ(0, NumberOfFramesInFlight());
173 421 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
174 // Send 4 frames. 422 media::cast::FrameId::first() + 9));
175 for (int i = 0; i < 4; ++i) 423
176 InsertFrame(); 424 // Send one more frame and ack it.
177 EXPECT_EQ(4, NumberOfFramesInFlight()); 425 ASSERT_TRUE(ProduceDataChunk(0, 16));
178 // Ack one frame. 426 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
179 cast_feedback.ack_frame_id = media::cast::FrameId::first() + 1; 427 PostMojoCallTask_SendFrame();
180 OnReceivedCastMessage(cast_feedback); 428 RunPendingTasks();
181 EXPECT_EQ(3, NumberOfFramesInFlight()); 429 EXPECT_TRUE(IsFlowControlInConsumingState());
182 // Ack all. 430 EXPECT_EQ(1, NumberOfFramesInFlight());
183 cast_feedback.received_later_frames.clear(); 431 AckOldestInFlightFrames(1);
184 cast_feedback.ack_frame_id = media::cast::FrameId::first() + 4;
185 OnReceivedCastMessage(cast_feedback);
186 EXPECT_EQ(0, NumberOfFramesInFlight()); 432 EXPECT_EQ(0, NumberOfFramesInFlight());
187 } 433
188 434 // Check that the dependency metadata was set correctly to indicate a frame
189 TEST_F(CastRemotingSenderTest, CancelFramesInFlight) { 435 // that immediately follows a CancelInFlightData() operation.
190 for (int i = 0; i < 10; ++i) 436 std::vector<media::cast::EncodedFrame> frames;
191 InsertFrame(); 437 TakeSentFrames(&frames);
192 EXPECT_EQ(10, NumberOfFramesInFlight()); 438 ASSERT_EQ(11u, frames.size());
193 439 for (size_t i = 0; i < 11; ++i) {
194 media::cast::RtcpCastMessage cast_feedback(11); 440 const media::cast::EncodedFrame& frame = frames[i];
195 cast_feedback.ack_frame_id = media::cast::FrameId::first(); 441 EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
196 OnReceivedCastMessage(cast_feedback); 442 if (i == 0 || i == 10)
197 EXPECT_EQ(9, NumberOfFramesInFlight()); 443 EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
198 444 else
199 CancelFramesInFlight(); 445 EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
446 }
447 }
448
449 TEST_F(CastRemotingSenderTest, ManagesFlowControl) {
450 EXPECT_TRUE(IsFlowControlInRestartingState());
451
452 // Send out a the maximum possible number of unacked frames, but don't ack any
453 // yet.
454 for (int i = 0; i < media::cast::kMaxUnackedFrames; ++i) {
455 ASSERT_TRUE(ProduceDataChunk(0, 4));
456 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
457 PostMojoCallTask_SendFrame();
458 }
459 RunPendingTasks();
460 EXPECT_TRUE(IsFlowControlInConsumingState());
461 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
462 // Note: All frames should have been sent to the Transport, and so
463 // CastRemotingSender's single-frame data buffer should be empty.
464 EXPECT_EQ(0u, GetSizeOfNextFrameData());
465
466 // Attempting to send the next frame will place the CastRemotingSenderTest in
467 // a "paused flow" state.
468 ASSERT_TRUE(ProduceDataChunk(0, 4));
469 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
470 PostMojoCallTask_SendFrame();
471 RunPendingTasks();
472 EXPECT_TRUE(IsFlowControlInPausedState());
473 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
474 // Note: The unsent frame resides in CastRemotingSender's single-frame data
475 // buffer.
476 EXPECT_EQ(4u, GetSizeOfNextFrameData());
477
478 // Ack the the first frame and expect sending to resume, starting with the
479 // frame that triggered the pause.
480 AckOldestInFlightFrames(1);
481 EXPECT_TRUE(IsFlowControlInConsumingState());
482 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
483 // Note: The frame causing the earlier pause should have been sent, and so
484 // CastRemotingSender's single-frame data buffer should now be empty.
485 EXPECT_EQ(0u, GetSizeOfNextFrameData());
486
487 // Attempting to send another frame will once again place the
488 // CastRemotingSender in a "paused flow" state.
489 ASSERT_TRUE(ProduceDataChunk(0, 4));
490 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
491 PostMojoCallTask_SendFrame();
492 RunPendingTasks();
493 EXPECT_TRUE(IsFlowControlInPausedState());
494 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
495 // Note: Once again, CastRemotingSender's single-frame data buffer contains an
496 // unsent frame.
497 EXPECT_EQ(4u, GetSizeOfNextFrameData());
498
499 // Send more frames: Some number of frames will queue-up inside the Mojo data
500 // pipe (the exact number depends on the data pipe's capacity, and how Mojo
501 // manages memory internally). At some point, attempting to produce and push
502 // another frame will fail because the data pipe is full.
503 int num_frames_in_data_pipe = 0;
504 while (ProduceDataChunk(0, 768)) {
505 ++num_frames_in_data_pipe;
506 PostMojoCallTask_ConsumeDataChunk(0, 768, 768);
507 PostMojoCallTask_SendFrame();
508 RunPendingTasks();
509 EXPECT_TRUE(IsFlowControlInPausedState());
510 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
511 // Note: CastRemotingSender's single-frame data buffer should still contain
512 // the unsent 4-byte frame.
513 EXPECT_EQ(4u, GetSizeOfNextFrameData());
514 }
515 EXPECT_LT(0, num_frames_in_data_pipe);
516
517 // Ack one frame at a time until the backlog in the Mojo data pipe has
518 // cleared. In each iteration, the flow will resume, but then it will become
519 // paused again when Mojo method calls are resumed and cause
520 // CastRemotingSender to pull another frame out of the data pipe.
521 int remaining_frames_in_data_pipe = num_frames_in_data_pipe;
522 while (remaining_frames_in_data_pipe > 0) {
523 AckOldestInFlightFrames(1);
524 EXPECT_TRUE(IsFlowControlInConsumingState());
525 EXPECT_EQ(0u, GetSizeOfNextFrameData());
526 // The following will execute one ConsumeDataChunk() and one SendFrame()
527 // Mojo method call.
528 RunPendingTasks();
529 --remaining_frames_in_data_pipe;
530 EXPECT_TRUE(IsFlowControlInPausedState());
531 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
532 EXPECT_EQ(768u, GetSizeOfNextFrameData());
533 }
534
535 // Ack one more frame. This should cause the flow to resume since there are no
536 // longer any frames backlogged on the input side of things.
537 AckOldestInFlightFrames(1);
538 EXPECT_TRUE(IsFlowControlInConsumingState());
539 RunPendingTasks(); // No additional Mojo method calls should be made here.
540 EXPECT_TRUE(IsFlowControlInConsumingState());
541 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
542 EXPECT_EQ(0u, GetSizeOfNextFrameData());
543
544 // Ack all but one frame.
545 AckOldestInFlightFrames(NumberOfFramesInFlight() - 1);
546 EXPECT_TRUE(IsFlowControlInConsumingState());
547 EXPECT_EQ(1, NumberOfFramesInFlight());
548 // ..and one more frame can be sent without pausing.
549 ASSERT_TRUE(ProduceDataChunk(0, 4));
550 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
551 PostMojoCallTask_SendFrame();
552 RunPendingTasks();
553 EXPECT_TRUE(IsFlowControlInConsumingState());
554 EXPECT_EQ(2, NumberOfFramesInFlight());
555 // ...and ack these last two frames.
556 AckOldestInFlightFrames(2);
557 EXPECT_TRUE(IsFlowControlInConsumingState());
200 EXPECT_EQ(0, NumberOfFramesInFlight()); 558 EXPECT_EQ(0, NumberOfFramesInFlight());
559
560 // Finally, examine all frames that were sent to the CastTransport, and
561 // confirm their metadata and data is valid.
562 std::vector<media::cast::EncodedFrame> frames;
563 TakeSentFrames(&frames);
564 const size_t total_frames_sent =
565 media::cast::kMaxUnackedFrames + 2 + num_frames_in_data_pipe + 1;
566 ASSERT_EQ(total_frames_sent, frames.size());
567 media::cast::RtpTimeTicks last_rtp_timestamp =
568 media::cast::RtpTimeTicks() - media::cast::RtpTimeDelta::FromTicks(1);
569 for (size_t i = 0; i < total_frames_sent; ++i) {
570 const media::cast::EncodedFrame& frame = frames[i];
571 EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
572 if (i == 0) {
573 EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
574 EXPECT_EQ(media::cast::FrameId::first() + i, frame.referenced_frame_id);
575 } else {
576 EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
577 EXPECT_EQ(media::cast::FrameId::first() + i - 1,
578 frame.referenced_frame_id);
579 }
580
581 // RTP timestamp must be monotonically increasing.
582 EXPECT_GT(frame.rtp_timestamp, last_rtp_timestamp);
583 last_rtp_timestamp = frame.rtp_timestamp;
584
585 size_t expected_frame_size = 4;
586 if ((i >= static_cast<size_t>(media::cast::kMaxUnackedFrames + 2)) &&
587 (i < static_cast<size_t>(media::cast::kMaxUnackedFrames + 2 +
588 num_frames_in_data_pipe))) {
589 expected_frame_size = 768;
590 }
591 EXPECT_TRUE(ExpectCorrectFrameData(expected_frame_size, frame));
592 }
201 } 593 }
202 594
203 } // namespace cast 595 } // namespace cast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698