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

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: Just a REBASE on ToT before commit. 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.
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 IsFlowRestartPending() const {
172 return remoting_sender_->flow_restart_pending_;
173 }
174
175 bool ProduceDataChunk(size_t offset, size_t size) WARN_UNUSED_RESULT {
176 std::vector<uint8_t> fake_chunk(size);
177 for (size_t i = 0; i < size; ++i)
178 fake_chunk[i] = static_cast<uint8_t>(offset + i);
179 uint32_t num_bytes = fake_chunk.size();
180 return mojo::WriteDataRaw(
181 producer_end_.get(), fake_chunk.data(), &num_bytes,
182 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE) == MOJO_RESULT_OK;
183 }
184
185 void PostMojoCallTask_ConsumeDataChunk(size_t offset, size_t size,
186 size_t total_payload_size) {
187 sender_->ConsumeDataChunk(offset, size, total_payload_size);
188 }
189
190 void PostMojoCallTask_SendFrame() {
191 sender_->SendFrame();
192 }
193
194 void PostMojoCallTask_CancelInFlightData() { sender_->CancelInFlightData(); }
195
196 void TakeSentFrames(std::vector<media::cast::EncodedFrame>* frames) {
197 transport_.TakeSentFrames(frames);
198 }
199
200 bool ExpectOneFrameWasSent(size_t expected_payload_size) {
201 std::vector<media::cast::EncodedFrame> frames;
202 transport_.TakeSentFrames(&frames);
203 EXPECT_EQ(1u, frames.size());
204 if (frames.empty())
205 return false;
206 return ExpectCorrectFrameData(expected_payload_size, frames.front());
207 }
208
209 void AckUpToAndIncluding(media::cast::FrameId frame_id) {
210 media::cast::RtcpCastMessage cast_feedback(transport_config_.feedback_ssrc);
211 cast_feedback.ack_frame_id = frame_id;
212 remoting_sender_->OnReceivedCastMessage(cast_feedback);
213 }
214
215 void AckOldestInFlightFrames(int count) {
216 AckUpToAndIncluding(latest_acked_frame_id() + count);
217 }
218
219 // Blocks the caller indefinitely, until a kickstart frame is sent, and then
220 // returns the FrameId of the kickstarted-frame.
221 media::cast::FrameId WaitForKickstart() {
222 return transport_.WaitForKickstart();
223 }
224
225 bool ExpectNoFramesCanceled() {
226 std::vector<media::cast::FrameId> frame_ids;
227 transport_.TakeCanceledFrameIds(&frame_ids);
228 return frame_ids.empty();
229 }
230
231 bool ExpectFramesCanceled(media::cast::FrameId first_frame_id,
232 media::cast::FrameId last_frame_id) {
233 std::vector<media::cast::FrameId> frame_ids;
234 transport_.TakeCanceledFrameIds(&frame_ids);
235 auto begin = frame_ids.begin();
236 auto end = frame_ids.end();
237 for (auto fid = first_frame_id; fid <= last_frame_id; ++fid) {
238 auto new_end = std::remove(begin, end, fid);
239 if (new_end == end)
240 return false;
241 end = new_end;
242 }
243 return begin == end;
244 }
245
246 static bool ExpectCorrectFrameData(size_t expected_payload_size,
247 const media::cast::EncodedFrame& frame) {
248 if (expected_payload_size != frame.data.size()) {
249 ADD_FAILURE() << "Expected frame data size != frame.data.size(): "
250 << expected_payload_size << " vs " << frame.data.size();
251 return false;
252 }
253 for (size_t i = 0; i < expected_payload_size; ++i) {
254 if (static_cast<uint8_t>(frame.data[i]) != static_cast<uint8_t>(i)) {
255 ADD_FAILURE() << "Frame data byte mismatch at offset " << i;
256 return false;
257 }
258 }
259 return true;
260 }
261
262 private:
263 void OnError() {
264 CHECK(expecting_error_callback_run_);
265 }
266
267 content::TestBrowserThreadBundle thread_bundle_;
152 const scoped_refptr<media::cast::CastEnvironment> cast_environment_; 268 const scoped_refptr<media::cast::CastEnvironment> cast_environment_;
153 TestPacketSender* transport_; // Owned by CastTransport. 269 media::cast::CastTransportRtpConfig transport_config_;
154 std::unique_ptr<media::cast::CastTransportImpl> transport_sender_; 270 FakeTransport transport_;
155 std::unique_ptr<CastRemotingSender> remoting_sender_; 271 std::unique_ptr<CastRemotingSender> remoting_sender_;
272 media::mojom::RemotingDataStreamSenderPtr sender_;
273 mojo::ScopedDataPipeProducerHandle producer_end_;
274 bool expecting_error_callback_run_;
156 275
157 private: 276 private:
158 DISALLOW_COPY_AND_ASSIGN(CastRemotingSenderTest); 277 DISALLOW_COPY_AND_ASSIGN(CastRemotingSenderTest);
159 }; 278 };
160 279
161 TEST_F(CastRemotingSenderTest, SendAndAckEncodedFrame) { 280 TEST_F(CastRemotingSenderTest, SendsFramesViaMojoInterface) {
162 // Send a fake video frame that will be decomposed into 4 packets. 281 // One 256-byte chunk pushed through the data pipe to make one frame.
163 InsertFrame(); 282 ASSERT_TRUE(ProduceDataChunk(0, 256));
164 task_runner_->RunTasks(); 283 PostMojoCallTask_ConsumeDataChunk(0, 256, 256);
165 EXPECT_EQ(4, transport_->number_of_rtp_packets()); 284 PostMojoCallTask_SendFrame();
285 RunPendingTasks();
286 EXPECT_TRUE(ExpectOneFrameWasSent(256));
287 AckOldestInFlightFrames(1);
288 EXPECT_EQ(media::cast::FrameId::first(), latest_acked_frame_id());
289
290 // Four 256-byte chunks pushed through the data pipe to make one frame.
291 for (int i = 0; i < 4; ++i) {
292 ASSERT_TRUE(ProduceDataChunk(i * 256, 256));
293 PostMojoCallTask_ConsumeDataChunk(i * 256, 256, 1024);
294 }
295 PostMojoCallTask_SendFrame();
296 RunPendingTasks();
297 EXPECT_TRUE(ExpectOneFrameWasSent(1024));
298 AckOldestInFlightFrames(1);
299 EXPECT_EQ(media::cast::FrameId::first() + 1, latest_acked_frame_id());
300
301 // 10 differently-sized chunks pushed through the data pipe to make one frame
302 // that is larger than the data pipe's total capacity.
303 size_t offset = 0;
304 for (int i = 0; i < 10; ++i) {
305 const size_t chunk_size = 500 + i * 37;
306 ASSERT_TRUE(ProduceDataChunk(offset, chunk_size));
307 PostMojoCallTask_ConsumeDataChunk(offset, chunk_size, 6665);
308 RunPendingTasks();
309 offset += chunk_size;
310 }
311 PostMojoCallTask_SendFrame();
312 RunPendingTasks();
313 EXPECT_TRUE(ExpectOneFrameWasSent(6665));
314 AckOldestInFlightFrames(1);
315 EXPECT_EQ(media::cast::FrameId::first() + 2, latest_acked_frame_id());
316 }
317
318 TEST_F(CastRemotingSenderTest, SendsMultipleFramesWithDelayedAcks) {
319 // Send 4 frames.
320 for (int i = 0; i < 4; ++i) {
321 ASSERT_TRUE(ProduceDataChunk(0, 16));
322 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
323 PostMojoCallTask_SendFrame();
324 }
325 RunPendingTasks();
326 EXPECT_EQ(4, NumberOfFramesInFlight());
327 EXPECT_TRUE(ExpectNoFramesCanceled());
328
329 // Ack one frame.
330 AckOldestInFlightFrames(1);
331 EXPECT_EQ(3, NumberOfFramesInFlight());
332 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
333 media::cast::FrameId::first()));
334
335 // Ack all.
336 AckOldestInFlightFrames(3);
337 EXPECT_EQ(0, NumberOfFramesInFlight());
338 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
339 media::cast::FrameId::first() + 3));
340 }
341
342 TEST_F(CastRemotingSenderTest, KickstartsIfAckNotTimely) {
343 // Send first frame and don't Ack it. Expect the first frame to be
344 // kickstarted.
345 ASSERT_TRUE(ProduceDataChunk(0, 16));
346 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
347 PostMojoCallTask_SendFrame();
348 EXPECT_EQ(media::cast::FrameId::first(), WaitForKickstart());
166 EXPECT_EQ(1, NumberOfFramesInFlight()); 349 EXPECT_EQ(1, NumberOfFramesInFlight());
167 350
168 // Ack the frame. 351 // Send 3 more frames and don't Ack them either. Expect the 4th frame to be
169 media::cast::RtcpCastMessage cast_feedback(11); 352 // kickstarted.
170 cast_feedback.ack_frame_id = media::cast::FrameId::first(); 353 for (int i = 0; i < 3; ++i) {
171 OnReceivedCastMessage(cast_feedback); 354 ASSERT_TRUE(ProduceDataChunk(0, 16));
172 EXPECT_EQ(0, NumberOfFramesInFlight()); 355 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
173 356 PostMojoCallTask_SendFrame();
174 // Send 4 frames. 357 }
175 for (int i = 0; i < 4; ++i) 358 EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
176 InsertFrame();
177 EXPECT_EQ(4, NumberOfFramesInFlight()); 359 EXPECT_EQ(4, NumberOfFramesInFlight());
178 // Ack one frame. 360
179 cast_feedback.ack_frame_id = media::cast::FrameId::first() + 1; 361 // Ack the first two frames and wait for another kickstart (for the 4th frame
180 OnReceivedCastMessage(cast_feedback); 362 // again).
363 AckOldestInFlightFrames(2);
364 EXPECT_EQ(2, NumberOfFramesInFlight());
365 EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
366 }
367
368 TEST_F(CastRemotingSenderTest, CancelsUnsentFrame) {
369 EXPECT_EQ(0u, GetSizeOfNextFrameData());
370 ASSERT_TRUE(ProduceDataChunk(0, 16));
371 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
372 RunPendingTasks();
373 EXPECT_EQ(16u, GetSizeOfNextFrameData());
374 PostMojoCallTask_CancelInFlightData();
375 RunPendingTasks();
376 EXPECT_EQ(0u, GetSizeOfNextFrameData());
377
378 // Since no frames were sent, none should have been passed to the
379 // CastTransport, and none should have been canceled.
380 std::vector<media::cast::EncodedFrame> frames;
381 TakeSentFrames(&frames);
382 EXPECT_TRUE(frames.empty());
383 EXPECT_TRUE(ExpectNoFramesCanceled());
384 }
385
386 // http://crbug.com/647423
387 #define MAYBE_CancelsFramesInFlight DISABLED_CancelsFramesInFlight
388 TEST_F(CastRemotingSenderTest, MAYBE_CancelsFramesInFlight) {
389 EXPECT_TRUE(IsFlowRestartPending());
390
391 // Send 10 frames.
392 for (int i = 0; i < 10; ++i) {
393 ASSERT_TRUE(ProduceDataChunk(0, 16));
394 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
395 PostMojoCallTask_SendFrame();
396 }
397 RunPendingTasks();
398 EXPECT_FALSE(IsFlowRestartPending());
399 EXPECT_EQ(10, NumberOfFramesInFlight());
400
401 // Ack the first frame.
402 AckOldestInFlightFrames(1);
403 EXPECT_FALSE(IsFlowRestartPending());
404 EXPECT_EQ(9, NumberOfFramesInFlight());
405 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
406 media::cast::FrameId::first()));
407
408 // Cancel all in-flight data. This should cause the remaining 9 frames to be
409 // canceled.
410 PostMojoCallTask_CancelInFlightData();
411 RunPendingTasks();
412 EXPECT_TRUE(IsFlowRestartPending());
413 EXPECT_EQ(0, NumberOfFramesInFlight());
414 EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
415 media::cast::FrameId::first() + 9));
416
417 // Send one more frame and ack it.
418 ASSERT_TRUE(ProduceDataChunk(0, 16));
419 PostMojoCallTask_ConsumeDataChunk(0, 16, 16);
420 PostMojoCallTask_SendFrame();
421 RunPendingTasks();
422 EXPECT_FALSE(IsFlowRestartPending());
423 EXPECT_EQ(1, NumberOfFramesInFlight());
424 AckOldestInFlightFrames(1);
425 EXPECT_EQ(0, NumberOfFramesInFlight());
426
427 // Check that the dependency metadata was set correctly to indicate a frame
428 // that immediately follows a CancelInFlightData() operation.
429 std::vector<media::cast::EncodedFrame> frames;
430 TakeSentFrames(&frames);
431 ASSERT_EQ(11u, frames.size());
432 for (size_t i = 0; i < 11; ++i) {
433 const media::cast::EncodedFrame& frame = frames[i];
434 EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
435 if (i == 0 || i == 10)
436 EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
437 else
438 EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
439 }
440 }
441
442 TEST_F(CastRemotingSenderTest, WaitsForDataBeforeConsumingFromDataPipe) {
443 // Queue up and issue Mojo calls to consume data chunks and send three
444 // frames. Since no data has been pushed into the pipe yet no frames should be
445 // sent.
446 for (int i = 0; i < 3; ++i) {
447 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
448 PostMojoCallTask_SendFrame();
449 }
450 RunPendingTasks();
451 EXPECT_TRUE(IsFlowRestartPending());
452 EXPECT_EQ(0, NumberOfFramesInFlight());
453
454 // Push the data for one frame into the data pipe. This should trigger input
455 // processing and allow one frame to be sent.
456 ASSERT_TRUE(ProduceDataChunk(0, 4));
457 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
458 EXPECT_FALSE(IsFlowRestartPending());
459 EXPECT_EQ(1, NumberOfFramesInFlight());
460
461 // Now push the data for the other two frames into the data pipe and expect
462 // two more frames to be sent.
463 ASSERT_TRUE(ProduceDataChunk(0, 4));
464 ASSERT_TRUE(ProduceDataChunk(0, 4));
465 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
466 EXPECT_FALSE(IsFlowRestartPending());
181 EXPECT_EQ(3, NumberOfFramesInFlight()); 467 EXPECT_EQ(3, NumberOfFramesInFlight());
182 // Ack all. 468 }
183 cast_feedback.received_later_frames.clear(); 469
184 cast_feedback.ack_frame_id = media::cast::FrameId::first() + 4; 470 TEST_F(CastRemotingSenderTest, WaitsForDataThenDiscardsCanceledData) {
185 OnReceivedCastMessage(cast_feedback); 471 // Queue up and issue Mojo calls to consume data chunks and send three
186 EXPECT_EQ(0, NumberOfFramesInFlight()); 472 // frames. Since no data has been pushed into the pipe yet no frames should be
187 } 473 // sent.
188 474 for (int i = 0; i < 3; ++i) {
189 TEST_F(CastRemotingSenderTest, CancelFramesInFlight) { 475 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
190 for (int i = 0; i < 10; ++i) 476 PostMojoCallTask_SendFrame();
191 InsertFrame(); 477 }
192 EXPECT_EQ(10, NumberOfFramesInFlight()); 478 RunPendingTasks();
193 479 EXPECT_EQ(0, NumberOfFramesInFlight());
194 media::cast::RtcpCastMessage cast_feedback(11); 480
195 cast_feedback.ack_frame_id = media::cast::FrameId::first(); 481 // Cancel all in-flight data.
196 OnReceivedCastMessage(cast_feedback); 482 PostMojoCallTask_CancelInFlightData();
197 EXPECT_EQ(9, NumberOfFramesInFlight()); 483 RunPendingTasks();
198 484
199 CancelFramesInFlight(); 485 // Now, push the data for one frame into the data pipe. Because of the
200 EXPECT_EQ(0, NumberOfFramesInFlight()); 486 // cancellation, no frames should be sent.
487 ASSERT_TRUE(ProduceDataChunk(0, 4));
488 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
489 EXPECT_EQ(0, NumberOfFramesInFlight());
490
491 // Now push the data for the other two frames into the data pipe and still no
492 // frames should be sent.
493 ASSERT_TRUE(ProduceDataChunk(0, 4));
494 ASSERT_TRUE(ProduceDataChunk(0, 4));
495 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
496 EXPECT_EQ(0, NumberOfFramesInFlight());
497
498 // Now issue calls to send another frame and then push the data for it into
499 // the data pipe. Expect to see the frame gets sent since it was provided
500 // after the CancelInFlightData().
501 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
502 PostMojoCallTask_SendFrame();
503 RunPendingTasks();
504 EXPECT_EQ(0, NumberOfFramesInFlight());
505 ASSERT_TRUE(ProduceDataChunk(0, 4));
506 RunPendingTasks(); // Allow Mojo Watcher to signal CastRemotingSender.
507 EXPECT_EQ(1, NumberOfFramesInFlight());
508 }
509
510 TEST_F(CastRemotingSenderTest, StopsConsumingWhileTooManyFramesAreInFlight) {
511 EXPECT_TRUE(IsFlowRestartPending());
512
513 // Send out a the maximum possible number of unacked frames, but don't ack any
514 // yet.
515 for (int i = 0; i < media::cast::kMaxUnackedFrames; ++i) {
516 ASSERT_TRUE(ProduceDataChunk(0, 4));
517 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
518 PostMojoCallTask_SendFrame();
519 }
520 RunPendingTasks();
521 EXPECT_FALSE(IsFlowRestartPending());
522 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
523 // Note: All frames should have been sent to the Transport, and so
524 // CastRemotingSender's single-frame data buffer should be empty.
525 EXPECT_EQ(0u, GetSizeOfNextFrameData());
526
527 // When the client provides one more frame, CastRemotingSender will begin
528 // queuing input operations instead of sending the the frame to the
529 // CastTransport.
530 ASSERT_TRUE(ProduceDataChunk(0, 4));
531 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
532 PostMojoCallTask_SendFrame();
533 RunPendingTasks();
534 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
535 // Note: The unsent frame resides in CastRemotingSender's single-frame data
536 // buffer.
537 EXPECT_EQ(4u, GetSizeOfNextFrameData());
538
539 // Ack the the first frame and expect sending to resume, with one more frame
540 // being sent to the CastTransport.
541 AckOldestInFlightFrames(1);
542 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
543 // Note: Only one frame was backlogged, and so CastRemotingSender's
544 // single-frame data buffer should be empty.
545 EXPECT_EQ(0u, GetSizeOfNextFrameData());
546
547 // Attempting to send another frame will once again cause CastRemotingSender
548 // to queue input operations.
549 ASSERT_TRUE(ProduceDataChunk(0, 4));
550 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
551 PostMojoCallTask_SendFrame();
552 RunPendingTasks();
553 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
554 // Note: Once again, CastRemotingSender's single-frame data buffer contains an
555 // unsent frame.
556 EXPECT_EQ(4u, GetSizeOfNextFrameData());
557
558 // Send more frames: Some number of frames will queue-up inside the Mojo data
559 // pipe (the exact number depends on the data pipe's capacity, and how Mojo
560 // manages memory internally). At some point, attempting to produce and push
561 // another frame will fail because the data pipe is full.
562 int num_frames_in_data_pipe = 0;
563 while (ProduceDataChunk(0, 768)) {
564 ++num_frames_in_data_pipe;
565 PostMojoCallTask_ConsumeDataChunk(0, 768, 768);
566 PostMojoCallTask_SendFrame();
567 RunPendingTasks();
568 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
569 // Note: CastRemotingSender's single-frame data buffer should still contain
570 // the unsent 4-byte frame.
571 EXPECT_EQ(4u, GetSizeOfNextFrameData());
572 }
573 EXPECT_LT(0, num_frames_in_data_pipe);
574
575 // Ack one frame at a time until the backlog in the Mojo data pipe has
576 // cleared.
577 int remaining_frames_in_data_pipe = num_frames_in_data_pipe;
578 while (remaining_frames_in_data_pipe > 0) {
579 AckOldestInFlightFrames(1);
580 --remaining_frames_in_data_pipe;
581 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
582 EXPECT_EQ(768u, GetSizeOfNextFrameData());
583 }
584
585 // Ack one more frame. There should no longer be a backlog on the input side
586 // of things.
587 AckOldestInFlightFrames(1);
588 RunPendingTasks(); // No additional Mojo method calls should be made here.
589 EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
590 // The single-frame data buffer should be empty to indicate no input backlog.
591 EXPECT_EQ(0u, GetSizeOfNextFrameData());
592
593 // Ack all but one frame.
594 AckOldestInFlightFrames(NumberOfFramesInFlight() - 1);
595 EXPECT_EQ(1, NumberOfFramesInFlight());
596 // ..and one more frame can be sent immediately.
597 ASSERT_TRUE(ProduceDataChunk(0, 4));
598 PostMojoCallTask_ConsumeDataChunk(0, 4, 4);
599 PostMojoCallTask_SendFrame();
600 RunPendingTasks();
601 EXPECT_EQ(2, NumberOfFramesInFlight());
602 // ...and ack these last two frames.
603 AckOldestInFlightFrames(2);
604 EXPECT_EQ(0, NumberOfFramesInFlight());
605
606 // Finally, examine all frames that were sent to the CastTransport, and
607 // confirm their metadata and data is valid.
608 std::vector<media::cast::EncodedFrame> frames;
609 TakeSentFrames(&frames);
610 const size_t total_frames_sent =
611 media::cast::kMaxUnackedFrames + 2 + num_frames_in_data_pipe + 1;
612 ASSERT_EQ(total_frames_sent, frames.size());
613 media::cast::RtpTimeTicks last_rtp_timestamp =
614 media::cast::RtpTimeTicks() - media::cast::RtpTimeDelta::FromTicks(1);
615 for (size_t i = 0; i < total_frames_sent; ++i) {
616 const media::cast::EncodedFrame& frame = frames[i];
617 EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
618 if (i == 0) {
619 EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
620 EXPECT_EQ(media::cast::FrameId::first() + i, frame.referenced_frame_id);
621 } else {
622 EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
623 EXPECT_EQ(media::cast::FrameId::first() + i - 1,
624 frame.referenced_frame_id);
625 }
626
627 // RTP timestamp must be monotonically increasing.
628 EXPECT_GT(frame.rtp_timestamp, last_rtp_timestamp);
629 last_rtp_timestamp = frame.rtp_timestamp;
630
631 size_t expected_frame_size = 4;
632 if ((i >= media::cast::kMaxUnackedFrames + 2u) &&
633 (i < media::cast::kMaxUnackedFrames + 2u + num_frames_in_data_pipe)) {
634 expected_frame_size = 768;
635 }
636 EXPECT_TRUE(ExpectCorrectFrameData(expected_frame_size, frame));
637 }
201 } 638 }
202 639
203 } // namespace cast 640 } // namespace cast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698