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

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

Powered by Google App Engine
This is Rietveld 408576698