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

Side by Side Diff: content/renderer/media/webmediaplayer_ms_unittest.cc

Issue 1417533006: Unit test for WebMediaPlayerMS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and merge some classes together Created 5 years, 1 month 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
(Empty)
1 // Copyright 2015 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 "base/strings/string_number_conversions.h"
6 #include "base/strings/string_split.h"
7 #include "cc/layers/video_frame_provider.h"
8 #include "content/public/renderer/media_stream_renderer_factory.h"
9 #include "content/renderer/media/webmediaplayer_ms.h"
10 #include "content/renderer/media/webmediaplayer_ms_compositor.h"
11 #include "content/renderer/render_frame_impl.h"
12 #include "media/base/test_helpers.h"
13 #include "media/base/video_frame.h"
14 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
15 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
16
17 namespace content {
18
19 class WebMediaPlayerMSTest;
mcasas 2015/11/04 22:20:31 Why this forward declaration?
qiangchen 2015/11/06 19:14:58 Done.
20
21 class MockCB {
22 public:
23 MOCK_METHOD0(StartRendering, void());
24 MOCK_METHOD0(StopRendering, void());
25
26 MOCK_METHOD1(SetWebLayer, void(bool));
27 MOCK_METHOD1(NetworkStateChanged, void(blink::WebMediaPlayer::NetworkState));
28 MOCK_METHOD1(ReadyStateChanged, void(blink::WebMediaPlayer::ReadyState));
29 void VerifyAndClearExpectations() {
30 // Note: the raw value of "this" could be different from &mock_cb_.
31 // So this is not equivalent with calling
32 // VerifyAndClearExpectations(&mock_cb_) outside.
33 testing::Mock::VerifyAndClearExpectations(this);
34 }
35 };
36
37 struct TestFrame {
38 enum TestFrameType {
39 NORMAL_FRAME,
40 BROKEN_FRAME,
41 TEST_BRAKE // Signal to pause message loop.
42 };
43 TestFrame(TestFrameType input_category,
44 const scoped_refptr<media::VideoFrame>& input_frame)
45 : category(input_category), frame(input_frame) {}
46
47 TestFrameType category;
48 scoped_refptr<media::VideoFrame> frame;
49 };
50
51 class ReusableMessageLoopEvent {
mcasas 2015/11/04 22:20:31 How's this class different from media::WaitableMes
qiangchen 2015/11/06 19:14:58 The main reason I made this class is to deal with
52 public:
53 ReusableMessageLoopEvent() : event_(new media::WaitableMessageLoopEvent()) {}
54
55 base::Closure GetClosure() { return event_->GetClosure(); }
56
57 media::PipelineStatusCB GetPipelineStatusCB() {
58 return event_->GetPipelineStatusCB();
59 }
60
61 void RunAndWait() {
62 event_->RunAndWait();
63 event_.reset(new media::WaitableMessageLoopEvent());
64 }
65
66 void RunAndWaitForStatus(media::PipelineStatus expected) {
67 event_->RunAndWaitForStatus(expected);
68 event_.reset(new media::WaitableMessageLoopEvent());
69 }
70
71 private:
72 scoped_ptr<media::WaitableMessageLoopEvent> event_;
73 };
74
75 // The class mainly used to inject VideoFrames into WebMediaPlayerMS.
76 class MockVideoFrameProvider : public VideoFrameProvider {
77 public:
78 MockVideoFrameProvider(base::MessageLoop* message_loop,
79 ReusableMessageLoopEvent* message_loop_controller,
80 const base::Closure& error_cb,
81 const VideoFrameProvider::RepaintCB& repaint_cb)
82 : started_(false),
83 message_loop_(message_loop),
84 message_loop_controller_(message_loop_controller),
85 error_cb_(error_cb),
86 repaint_cb_(repaint_cb),
87 delay_(base::TimeDelta::FromSecondsD(1.0 / 30.0)) {}
88
89 // Implementation of VideoFrameProvider
90 void Start() override {
91 started_ = true;
mcasas 2015/11/04 22:20:31 Do not inline method bodies if the body is >= 2 li
qiangchen 2015/11/06 19:14:58 Done.
92 paused_ = false;
93 message_loop_->PostTask(FROM_HERE,
94 base::Bind(&MockVideoFrameProvider::InjectFrame,
95 base::Unretained(this)));
96 }
97
98 void Stop() override {
99 started_ = false;
100 frames_.clear();
101 }
102
103 void Play() override {
104 CHECK(started_);
105 paused_ = false;
106 }
107
108 void Pause() override {
109 CHECK(started_);
110 paused_ = true;
111 }
112
113 // Methods for test use
114 void PrepareFrame(TestFrame::TestFrameType category,
115 const scoped_refptr<media::VideoFrame>& frame) {
116 frames_.push_back(TestFrame(category, frame));
117 }
118
119 void QueueFrames(const std::vector<int>& input) {
120 for (const int token : input) {
121 if (token == -1) {
mcasas 2015/11/04 22:20:31 please add anonymous enums for -1 and -2, enum {
qiangchen 2015/11/06 19:14:57 Done. Just pull the TestFrameType out to be an ano
122 PrepareFrame(TestFrame::TestFrameType::BROKEN_FRAME, nullptr);
123 continue;
124 }
125
126 if (token == -2) {
127 PrepareFrame(TestFrame::TestFrameType::TEST_BRAKE, nullptr);
128 continue;
129 }
130
131 if (token >= 0) {
132 gfx::Size natural_size = media::TestVideoConfig::NormalCodedSize();
133 auto frame = media::VideoFrame::CreateFrame(
134 media::PIXEL_FORMAT_YV12, natural_size, gfx::Rect(natural_size),
135 natural_size, base::TimeDelta::FromMilliseconds(token));
136
137 frame->metadata()->SetTimeTicks(
138 media::VideoFrameMetadata::Key::REFERENCE_TIME,
139 base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(token));
140
141 PrepareFrame(TestFrame::TestFrameType::NORMAL_FRAME, frame);
142 continue;
143 }
144
145 CHECK(false) << "Unrecognized token: " << token;
146 }
147 }
148
149 bool Started() { return started_; }
150
151 bool Paused() { return paused_; }
152
153 private:
154 ~MockVideoFrameProvider() override {}
155
156 // Main function that pushes frame into WebMediaPlayerMS
157 void InjectFrame() {
mcasas 2015/11/04 22:20:31 If this is just meant to be run on |message_loop_|
qiangchen 2015/11/06 19:14:58 Done.
158 if (!started_)
159 return;
160
161 if (frames_.empty()) {
162 message_loop_controller_->GetClosure().Run();
163 return;
164 }
165
166 auto frame = frames_.front();
167 frames_.pop_front();
168
169 if (frame.category == TestFrame::TestFrameType::BROKEN_FRAME) {
170 error_cb_.Run();
171 return;
172 }
173
174 // For pause case, the provider will still let the stream continue, but
175 // not send the frames to the player. As is the same case in reality.
176 if (frame.category == TestFrame::TestFrameType::NORMAL_FRAME) {
177 if (!paused_)
178 repaint_cb_.Run(frame.frame);
179
180 size_t i = 0;
181 while (i < frames_.size() &&
182 frames_[i].category != TestFrame::TestFrameType::NORMAL_FRAME) {
183 ++i;
184 }
185
186 if (i < frames_.size()) {
187 delay_ = (frames_[i].frame->timestamp() - frame.frame->timestamp()) /
188 (i + 1);
189 }
190 }
191
192 message_loop_->PostDelayedTask(
193 FROM_HERE, base::Bind(&MockVideoFrameProvider::InjectFrame,
194 base::Unretained(this)),
195 delay_);
196
197 if (frame.category == TestFrame::TestFrameType::TEST_BRAKE)
198 message_loop_controller_->GetClosure().Run();
199 }
200
201 bool started_;
202 bool paused_;
203
204 base::MessageLoop* message_loop_;
205 ReusableMessageLoopEvent* message_loop_controller_;
206 base::Closure error_cb_;
207 VideoFrameProvider::RepaintCB repaint_cb_;
mcasas 2015/11/04 22:20:31 I believe all these 4 members can be const.
qiangchen 2015/11/06 19:14:57 Done.
208
209 std::deque<TestFrame> frames_;
210 base::TimeDelta delay_;
211 };
212
213 // The class is used to generate MockVideoProvider
mcasas 2015/11/04 22:20:31 "... used to generate _a_ MockVideoProvider".
qiangchen 2015/11/06 19:14:58 Done.
214 class MockRenderFactory : public MediaStreamRendererFactory {
215 public:
216 MockRenderFactory(base::MessageLoop* message_loop,
217 ReusableMessageLoopEvent* message_loop_controller)
218 : message_loop_(message_loop),
219 message_loop_controller_(message_loop_controller) {}
220
221 scoped_refptr<VideoFrameProvider> GetVideoFrameProvider(
222 const GURL& url,
223 const base::Closure& error_cb,
224 const VideoFrameProvider::RepaintCB& repaint_cb,
225 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
226 const scoped_refptr<base::TaskRunner>& worker_task_runner,
227 media::GpuVideoAcceleratorFactories* gpu_factories) override {
228 provider_ = new MockVideoFrameProvider(
229 message_loop_, message_loop_controller_, error_cb, repaint_cb);
230
231 return provider_;
232 }
233
234 MockVideoFrameProvider* GetVideoFrameProvider() {
235 return static_cast<MockVideoFrameProvider*>(provider_.get());
236 }
237
238 scoped_refptr<MediaStreamAudioRenderer> GetAudioRenderer(
239 const GURL& url,
240 int render_frame_id,
241 const std::string& device_id,
242 const url::Origin& security_origin) override {
243 return nullptr;
244 }
245
246 private:
247 base::MessageLoop* message_loop_;
mcasas 2015/11/04 22:20:31 const?
qiangchen 2015/11/06 19:14:58 Done.
248 scoped_refptr<VideoFrameProvider> provider_;
249 ReusableMessageLoopEvent* message_loop_controller_;
mcasas 2015/11/04 22:20:31 const?
qiangchen 2015/11/06 19:14:58 Done.
250 };
251
252 class WebMediaPlayerMSTest : public testing::Test,
253 public blink::WebMediaPlayerClient,
254 public cc::VideoFrameProvider::Client {
255 public:
256 WebMediaPlayerMSTest()
257 : render_factory_(
258 new MockRenderFactory(&message_loop_, &message_loop_controller_)),
259 player_(nullptr,
260 this,
261 base::WeakPtr<RenderFrameImpl>(),
262 new media::MediaLog(),
263 scoped_ptr<MediaStreamRendererFactory>(render_factory_),
264 message_loop_.task_runner(),
265 message_loop_.task_runner(),
266 message_loop_.task_runner(),
267 nullptr,
268 blink::WebString(),
269 blink::WebSecurityOrigin()),
270 rendering_(false) {}
271 ~WebMediaPlayerMSTest() override {}
272
273 MockVideoFrameProvider* LoadAndGetFrameProvider(bool algorithm_enabled) {
274 MockVideoFrameProvider* provider = render_factory_->GetVideoFrameProvider();
275 EXPECT_EQ(nullptr, provider);
276
277 EXPECT_CALL(mock_cb_, NetworkStateChanged(
278 blink::WebMediaPlayer::NetworkStateLoading));
279 EXPECT_CALL(mock_cb_, ReadyStateChanged(
280 blink::WebMediaPlayer::ReadyStateHaveNothing));
281 player_.load(blink::WebMediaPlayer::LoadTypeURL, blink::WebURL(),
282 blink::WebMediaPlayer::CORSModeUnspecified);
283 compositor_ = player_.GetCompositorForTesting();
mcasas 2015/11/04 22:20:31 You don't need GetCompositorForTesting() since We
qiangchen 2015/11/06 19:14:58 Done.
284 EXPECT_NE(nullptr, compositor_);
285 compositor_->SetAlgorithmEnabledForTesting(algorithm_enabled);
286
287 provider = render_factory_->GetVideoFrameProvider();
288 EXPECT_NE(nullptr, provider);
289 EXPECT_TRUE(provider->Started());
290
291 mock_cb_.VerifyAndClearExpectations();
292 return provider;
293 }
294
295 // Implementation of WebMediaPlayerClient
296 void networkStateChanged() override {
297 blink::WebMediaPlayer::NetworkState state = player_.networkState();
298 mock_cb_.NetworkStateChanged(state);
299 if (state == blink::WebMediaPlayer::NetworkState::NetworkStateFormatError ||
300 state == blink::WebMediaPlayer::NetworkState::NetworkStateDecodeError ||
301 state ==
302 blink::WebMediaPlayer::NetworkState::NetworkStateNetworkError) {
303 message_loop_controller_.GetPipelineStatusCB().Run(
304 media::PipelineStatus::PIPELINE_ERROR_NETWORK);
305 }
306 }
307
308 void readyStateChanged() override {
309 blink::WebMediaPlayer::ReadyState state = player_.readyState();
310 mock_cb_.ReadyStateChanged(state);
311 if (state == blink::WebMediaPlayer::ReadyState::ReadyStateHaveEnoughData)
312 player_.play();
313 }
314
315 void timeChanged() override {}
316 void repaint() override {}
317 void durationChanged() override {}
318 void sizeChanged() override {}
319 void playbackStateChanged() override {}
320 void setWebLayer(blink::WebLayer* layer) override {
321 if (layer) {
322 compositor_->SetVideoFrameProviderClient(this);
323 }
mcasas 2015/11/04 22:20:30 No need for {} [1] " In general, curly braces are
qiangchen 2015/11/06 19:14:58 Done.
324 mock_cb_.SetWebLayer(!!layer);
325 }
326
327 blink::WebMediaPlayer::TrackId addAudioTrack(const blink::WebString& id,
328 AudioTrackKind,
329 const blink::WebString& label,
330 const blink::WebString& language,
331 bool enabled) override {
332 return 0;
333 }
334 void removeAudioTrack(blink::WebMediaPlayer::TrackId) override {}
335
336 blink::WebMediaPlayer::TrackId addVideoTrack(const blink::WebString& id,
337 VideoTrackKind,
338 const blink::WebString& label,
339 const blink::WebString& language,
340 bool selected) override {
341 return 0;
342 }
343 void removeVideoTrack(blink::WebMediaPlayer::TrackId) override {}
344 void addTextTrack(blink::WebInbandTextTrack*) override {}
345 void removeTextTrack(blink::WebInbandTextTrack*) override {}
346 void mediaSourceOpened(blink::WebMediaSource*) override {}
347 void requestSeek(double) override {}
348 void remoteRouteAvailabilityChanged(bool) override {}
349 void connectedToRemoteDevice() override {}
350 void disconnectedFromRemoteDevice() override {}
351
352 // Implementation of cc::VideoFrameProvider::Client
353 void StopUsingProvider() {
354 if (rendering_)
355 StopRendering();
356 }
357
358 void StartRendering() {
359 if (!rendering_) {
360 rendering_ = true;
361 message_loop_.PostTask(FROM_HERE,
362 base::Bind(&WebMediaPlayerMSTest::RenderFrame,
363 base::Unretained(this)));
364 }
365 mock_cb_.StartRendering();
366 }
367
368 void StopRendering() {
369 rendering_ = false;
370 mock_cb_.StopRendering();
371 }
372 void DidReceiveFrame() override {}
373 void DidUpdateMatrix(const float* matrix) override {}
374
375 // For test use
376 void SetBackgroundRendering(bool background_rendering) {
377 background_rendering_ = background_rendering;
378 }
379
380 protected:
381 // Use StrictMock<T> to catch missing/extra callbacks.
382 testing::StrictMock<MockCB> mock_cb_;
383
384 base::MessageLoop message_loop_;
385 MockRenderFactory* render_factory_;
386 WebMediaPlayerMS player_;
387 WebMediaPlayerMSCompositor* compositor_;
388
389 ReusableMessageLoopEvent message_loop_controller_;
390
391 private:
392 // Main function trying to ask WebMediaPlayerMS to submit a frame for
393 // rendering.
394 void RenderFrame() {
395 if (!rendering_ || !compositor_)
396 return;
397
398 base::TimeTicks now = base::TimeTicks::Now();
399 base::TimeTicks deadline_min =
400 now + base::TimeDelta::FromSecondsD(1.0 / 60.0);
401 base::TimeTicks deadline_max =
402 deadline_min + base::TimeDelta::FromSecondsD(1.0 / 60.0);
403
404 // Background rendering is different from stop rendering. The rendering loop
405 // is still running but we do not ask frames from compositor_. And
406 // background rendering is not initiated from compositor_.
407 if (!background_rendering_) {
408 compositor_->UpdateCurrentFrame(deadline_min, deadline_max);
409 auto frame = compositor_->GetCurrentFrame();
410 compositor_->PutCurrentFrame();
411 }
412 message_loop_.PostDelayedTask(
413 FROM_HERE,
414 base::Bind(&WebMediaPlayerMSTest::RenderFrame, base::Unretained(this)),
415 base::TimeDelta::FromSecondsD(1.0 / 60.0));
416 }
417
418 bool rendering_;
419 bool background_rendering_;
420 };
421
422 TEST_F(WebMediaPlayerMSTest, Playing_Normal) {
423 // Workflow:
424 // 1. WMPMS::Load will generate and start content::VideoFrameProvider.
425 // 2. content::VideoFrameProvider will start pushing frames into WMPMS
426 // repeatedly.
427 // 3. On WMPMS receiving the first frame, a WebLayer will be created.
428 // 4. The WebLayer will call WMPMSCompositor::SetVideoFrameProviderClient,
429 // which in turn will trigger cc::VideoFrameProviderClient::StartRendering.
430 // 5. Then cc::VideoFrameProviderClient will start calling
431 // WMPMSCompositor::UpdateCurrentFrame, GetCurrentFrame for rendering
432 // repeatedly.
433 // 6. When WMPSMS::pause gets called, it should trigger
434 // content::VideoFrameProvider::Pause, and then the provider will stop
435 // pushing frames into WMPMS, but instead digesting them; simultanously, it
436 // should call cc::VideoFrameProviderClient::StopRendering, so the client
437 // will stop asking frames from WMPMSCompositor.
438 // 7. When WMPMS::play gets called, evething paused in step 6 should be
439 // resumed.
440 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(true);
441
442 int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
443 333, 366, 400, 433, 466, 500, 533, 566, 600};
444 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
445 provider->QueueFrames(timestamps);
446
447 EXPECT_CALL(mock_cb_, SetWebLayer(true));
448 EXPECT_CALL(mock_cb_, StartRendering());
449 EXPECT_CALL(mock_cb_,
450 ReadyStateChanged(blink::WebMediaPlayer::ReadyStateHaveMetadata));
451 EXPECT_CALL(mock_cb_, ReadyStateChanged(
452 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
453 message_loop_controller_.RunAndWaitForStatus(
454 media::PipelineStatus::PIPELINE_OK);
455 mock_cb_.VerifyAndClearExpectations();
456
457 EXPECT_CALL(mock_cb_, SetWebLayer(false));
458 }
459
460 TEST_F(WebMediaPlayerMSTest, Playing_ErrorFrame) {
461 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
462
463 int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
464 333, 366, 400, 433, 466, 500, 533, 566, 600, -1};
465 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
466 provider->QueueFrames(timestamps);
467
468 EXPECT_CALL(mock_cb_, SetWebLayer(true));
469 EXPECT_CALL(mock_cb_, StartRendering());
470 EXPECT_CALL(mock_cb_,
471 ReadyStateChanged(blink::WebMediaPlayer::ReadyStateHaveMetadata));
472 EXPECT_CALL(mock_cb_, ReadyStateChanged(
473 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
474 EXPECT_CALL(mock_cb_, NetworkStateChanged(
475 blink::WebMediaPlayer::NetworkStateFormatError));
476 message_loop_controller_.RunAndWaitForStatus(
477 media::PipelineStatus::PIPELINE_ERROR_NETWORK);
478 mock_cb_.VerifyAndClearExpectations();
479
480 EXPECT_CALL(mock_cb_, SetWebLayer(false));
481 }
482
483 TEST_F(WebMediaPlayerMSTest, PlayThenPause) {
484 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
485
486 int tokens[] = {0, 33, 66, 100, 133, -2, 166, 200, 233, 266,
487 300, 333, 366, 400, 433, 466, 500, 533, 566, 600};
488 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
489 provider->QueueFrames(timestamps);
490
491 EXPECT_CALL(mock_cb_, SetWebLayer(true));
492 EXPECT_CALL(mock_cb_, StartRendering());
493 EXPECT_CALL(mock_cb_,
494 ReadyStateChanged(blink::WebMediaPlayer::ReadyStateHaveMetadata));
495 EXPECT_CALL(mock_cb_, ReadyStateChanged(
496 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
497 // Rendering will be "paused" at the TestBrake.
498 message_loop_controller_.RunAndWaitForStatus(
499 media::PipelineStatus::PIPELINE_OK);
500 mock_cb_.VerifyAndClearExpectations();
501
502 // Here No more rendering. 1. Render should not be called, 2. Frame freeze.
503 EXPECT_CALL(mock_cb_, StopRendering());
504 player_.pause();
505 auto prev_frame = compositor_->GetCurrentFrame();
506 message_loop_controller_.RunAndWaitForStatus(
507 media::PipelineStatus::PIPELINE_OK);
508 auto after_frame = compositor_->GetCurrentFrame();
509 EXPECT_EQ(prev_frame->timestamp(), after_frame->timestamp());
510 mock_cb_.VerifyAndClearExpectations();
511
512 EXPECT_CALL(mock_cb_, SetWebLayer(false));
513 }
514
515 TEST_F(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
516 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
517
518 int tokens[] = {0, 33, 66, 100, 133, -2, 166, 200, 233, 266, 300,
519 333, 366, 400, 433, -2, 466, 500, 533, 566, 600};
520 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
521 provider->QueueFrames(timestamps);
522
523 EXPECT_CALL(mock_cb_, SetWebLayer(true));
524 EXPECT_CALL(mock_cb_, StartRendering());
525 EXPECT_CALL(mock_cb_,
526 ReadyStateChanged(blink::WebMediaPlayer::ReadyStateHaveMetadata));
527 EXPECT_CALL(mock_cb_, ReadyStateChanged(
528 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
529 // Rendering will be "paused" at the TestBrake.
530 message_loop_controller_.RunAndWaitForStatus(
531 media::PipelineStatus::PIPELINE_OK);
532 mock_cb_.VerifyAndClearExpectations();
533
534 // Here No more rendering. 1. Render should not be called, 2. Frame freeze.
535 EXPECT_CALL(mock_cb_, StopRendering());
536 player_.pause();
537 auto prev_frame = compositor_->GetCurrentFrame();
538 message_loop_controller_.RunAndWaitForStatus(
539 media::PipelineStatus::PIPELINE_OK);
540 auto after_frame = compositor_->GetCurrentFrame();
541 EXPECT_EQ(prev_frame->timestamp(), after_frame->timestamp());
542 mock_cb_.VerifyAndClearExpectations();
543
544 // We resume the player
545 EXPECT_CALL(mock_cb_, StartRendering());
546 player_.play();
547 prev_frame = compositor_->GetCurrentFrame();
548 message_loop_controller_.RunAndWaitForStatus(
549 media::PipelineStatus::PIPELINE_OK);
550 after_frame = compositor_->GetCurrentFrame();
551 EXPECT_NE(prev_frame->timestamp(), after_frame->timestamp());
552 mock_cb_.VerifyAndClearExpectations();
553
554 EXPECT_CALL(mock_cb_, SetWebLayer(false));
555 }
556
557 TEST_F(WebMediaPlayerMSTest, BackgroudRendering) {
558 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(true);
559
560 int tokens[] = {0, 33, 66, 100, 133, -2, 166, 200, 233, 266, 300,
561 333, 366, 400, 433, -2, 466, 500, 533, 566, 600};
562 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
563 provider->QueueFrames(timestamps);
564
565 EXPECT_CALL(mock_cb_, SetWebLayer(true));
566 EXPECT_CALL(mock_cb_, StartRendering());
567 EXPECT_CALL(mock_cb_,
568 ReadyStateChanged(blink::WebMediaPlayer::ReadyStateHaveMetadata));
569 EXPECT_CALL(mock_cb_, ReadyStateChanged(
570 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
571 // Rendering will be "paused" at the TestBrake.
572 message_loop_controller_.RunAndWaitForStatus(
573 media::PipelineStatus::PIPELINE_OK);
574 mock_cb_.VerifyAndClearExpectations();
575
576 // Switch to background rendering, expect rendering to continue
577 SetBackgroundRendering(true);
578 auto prev_frame = compositor_->GetCurrentFrame();
579 message_loop_controller_.RunAndWaitForStatus(
580 media::PipelineStatus::PIPELINE_OK);
581 auto after_frame = compositor_->GetCurrentFrame();
582 EXPECT_NE(prev_frame->timestamp(), after_frame->timestamp());
583
584 // Switch to foreground rendering
585 SetBackgroundRendering(false);
586 prev_frame = compositor_->GetCurrentFrame();
587 message_loop_controller_.RunAndWaitForStatus(
588 media::PipelineStatus::PIPELINE_OK);
589 after_frame = compositor_->GetCurrentFrame();
590 EXPECT_NE(prev_frame->timestamp(), after_frame->timestamp());
591 mock_cb_.VerifyAndClearExpectations();
592
593 EXPECT_CALL(mock_cb_, SetWebLayer(false));
594 }
595 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698