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

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: Kill Memory Leak Created 5 years 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
« no previous file with comments | « content/renderer/media/webmediaplayer_ms_compositor.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "content/public/renderer/media_stream_renderer_factory.h"
5 #include "content/renderer/media/webmediaplayer_ms.h"
6 #include "content/renderer/media/webmediaplayer_ms_compositor.h"
7 #include "content/renderer/render_frame_impl.h"
8 #include "media/base/test_helpers.h"
9 #include "media/base/video_frame.h"
10 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
11 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
12
13 namespace content {
14
15 enum class FrameType {
16 NORMAL_FRAME = 0,
17 BROKEN_FRAME = -1,
18 TEST_BRAKE = -2, // Signal to pause message loop.
19 MIN_TYPE = TEST_BRAKE
20 };
21
22 using TestFrame = std::pair<FrameType, scoped_refptr<media::VideoFrame>>;
23
24 class ReusableMessageLoopEvent {
25 public:
26 ReusableMessageLoopEvent() : event_(new media::WaitableMessageLoopEvent()) {}
27
28 base::Closure GetClosure() const { return event_->GetClosure(); }
29
30 media::PipelineStatusCB GetPipelineStatusCB() const {
31 return event_->GetPipelineStatusCB();
32 }
33
34 void RunAndWait() {
35 event_->RunAndWait();
36 event_.reset(new media::WaitableMessageLoopEvent());
37 }
38
39 void RunAndWaitForStatus(media::PipelineStatus expected) {
40 event_->RunAndWaitForStatus(expected);
41 event_.reset(new media::WaitableMessageLoopEvent());
42 }
43
44 private:
45 scoped_ptr<media::WaitableMessageLoopEvent> event_;
46 };
47
48 // The class is used mainly to inject VideoFrames into WebMediaPlayerMS.
49 class MockVideoFrameProvider : public VideoFrameProvider {
50 public:
51 MockVideoFrameProvider(
52 const scoped_refptr<base::SingleThreadTaskRunner> task_runner,
53 ReusableMessageLoopEvent* message_loop_controller,
54 const base::Closure& error_cb,
55 const VideoFrameProvider::RepaintCB& repaint_cb)
56 : started_(false),
57 task_runner_(task_runner),
58 message_loop_controller_(message_loop_controller),
59 error_cb_(error_cb),
60 repaint_cb_(repaint_cb),
61 delay_till_next_generated_frame_(
62 base::TimeDelta::FromSecondsD(1.0 / 30.0)) {}
63
64 // Implementation of VideoFrameProvider
65 void Start() override;
66 void Stop() override;
67 void Play() override;
68 void Pause() override;
69
70 // Methods for test use
71 void QueueFrames(const std::vector<int>& timestamps_or_frame_type);
72 bool Started() { return started_; }
73 bool Paused() { return paused_; }
74
75 private:
76 ~MockVideoFrameProvider() override {}
77
78 // Main function that pushes a frame into WebMediaPlayerMS
79 void InjectFrame();
80
81 // Methods for test use
82 void AddFrame(FrameType category,
83 const scoped_refptr<media::VideoFrame>& frame);
84
85 bool started_;
86 bool paused_;
87
88 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
89 ReusableMessageLoopEvent* const message_loop_controller_;
90 const base::Closure error_cb_;
91 const VideoFrameProvider::RepaintCB repaint_cb_;
92
93 std::deque<TestFrame> frames_;
94 base::TimeDelta delay_till_next_generated_frame_;
95 };
96
97 void MockVideoFrameProvider::Start() {
98 started_ = true;
99 paused_ = false;
100 task_runner_->PostTask(
101 FROM_HERE,
102 base::Bind(&MockVideoFrameProvider::InjectFrame, base::Unretained(this)));
103 }
104
105 void MockVideoFrameProvider::Stop() {
106 started_ = false;
107 frames_.clear();
108 }
109
110 void MockVideoFrameProvider::Play() {
111 CHECK(started_);
112 paused_ = false;
113 }
114
115 void MockVideoFrameProvider::Pause() {
116 CHECK(started_);
117 paused_ = true;
118 }
119
120 void MockVideoFrameProvider::AddFrame(
121 FrameType category,
122 const scoped_refptr<media::VideoFrame>& frame) {
123 frames_.push_back(std::make_pair(category, frame));
124 }
125
126 void MockVideoFrameProvider::QueueFrames(
127 const std::vector<int>& timestamp_or_frame_type) {
128 for (const int token : timestamp_or_frame_type) {
129 if (token < static_cast<int>(FrameType::MIN_TYPE)) {
130 CHECK(false) << "Unrecognized frame type: " << token;
131 return;
132 }
133
134 if (token < 0) {
135 AddFrame(static_cast<FrameType>(token), nullptr);
136 continue;
137 }
138
139 if (token >= 0) {
140 gfx::Size natural_size = media::TestVideoConfig::NormalCodedSize();
141 auto frame = media::VideoFrame::CreateFrame(
142 media::PIXEL_FORMAT_YV12, natural_size, gfx::Rect(natural_size),
143 natural_size, base::TimeDelta::FromMilliseconds(token));
144
145 frame->metadata()->SetTimeTicks(
146 media::VideoFrameMetadata::Key::REFERENCE_TIME,
147 base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(token));
148
149 AddFrame(FrameType::NORMAL_FRAME, frame);
150 continue;
151 }
152 }
153 }
154
155 void MockVideoFrameProvider::InjectFrame() {
156 DCHECK(task_runner_->BelongsToCurrentThread());
157 if (!started_)
158 return;
159
160 if (frames_.empty()) {
161 message_loop_controller_->GetClosure().Run();
162 return;
163 }
164
165 auto frame = frames_.front();
166 frames_.pop_front();
167
168 if (frame.first == FrameType::BROKEN_FRAME) {
169 error_cb_.Run();
170 return;
171 }
172
173 // For pause case, the provider will still let the stream continue, but
174 // not send the frames to the player. As is the same case in reality.
175 if (frame.first == FrameType::NORMAL_FRAME) {
176 if (!paused_)
177 repaint_cb_.Run(frame.second);
178
179 for (size_t i = 0; i < frames_.size(); ++i) {
180 if (frames_[i].first == FrameType::NORMAL_FRAME) {
181 delay_till_next_generated_frame_ =
182 (frames_[i].second->timestamp() - frame.second->timestamp()) /
183 (i + 1);
184 break;
185 }
186 }
187 }
188
189 task_runner_->PostDelayedTask(
190 FROM_HERE,
191 base::Bind(&MockVideoFrameProvider::InjectFrame, base::Unretained(this)),
192 delay_till_next_generated_frame_);
193
194 // This will pause the |message_loop_|, and the purpose is to allow the main
195 // test function to do some operations (e.g. call pause(), switch to
196 // background rendering, etc) on WebMediaPlayerMS before resuming
197 // |message_loop_|.
198 if (frame.first == FrameType::TEST_BRAKE)
199 message_loop_controller_->GetClosure().Run();
200 }
201
202 // The class is used to generate a MockVideoProvider in
203 // WebMediaPlayerMS::load().
204 class MockRenderFactory : public MediaStreamRendererFactory {
205 public:
206 MockRenderFactory(
207 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
208 ReusableMessageLoopEvent* message_loop_controller)
209 : task_runner_(task_runner),
210 message_loop_controller_(message_loop_controller) {}
211
212 scoped_refptr<VideoFrameProvider> GetVideoFrameProvider(
213 const GURL& url,
214 const base::Closure& error_cb,
215 const VideoFrameProvider::RepaintCB& repaint_cb,
216 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
217 const scoped_refptr<base::TaskRunner>& worker_task_runner,
218 media::GpuVideoAcceleratorFactories* gpu_factories) override;
219
220 MockVideoFrameProvider* provider() {
221 return static_cast<MockVideoFrameProvider*>(provider_.get());
222 }
223
224 scoped_refptr<MediaStreamAudioRenderer> GetAudioRenderer(
225 const GURL& url,
226 int render_frame_id,
227 const std::string& device_id,
228 const url::Origin& security_origin) override {
229 return nullptr;
230 }
231
232 private:
233 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
234 scoped_refptr<VideoFrameProvider> provider_;
235 ReusableMessageLoopEvent* const message_loop_controller_;
236 };
237
238 scoped_refptr<VideoFrameProvider> MockRenderFactory::GetVideoFrameProvider(
239 const GURL& url,
240 const base::Closure& error_cb,
241 const VideoFrameProvider::RepaintCB& repaint_cb,
242 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
243 const scoped_refptr<base::TaskRunner>& worker_task_runner,
244 media::GpuVideoAcceleratorFactories* gpu_factories) {
245 provider_ = new MockVideoFrameProvider(task_runner_, message_loop_controller_,
246 error_cb, repaint_cb);
247
248 return provider_;
249 }
250
251 // This is the main class coordinating the tests.
252 // Basic workflow:
253 // 1. WebMediaPlayerMS::Load will generate and start
254 // content::VideoFrameProvider.
255 // 2. content::VideoFrameProvider will start pushing frames into
256 // WebMediaPlayerMS repeatedly.
257 // 3. On WebMediaPlayerMS receiving the first frame, a WebLayer will be created.
258 // 4. The WebLayer will call
259 // WebMediaPlayerMSCompositor::SetVideoFrameProviderClient, which in turn
260 // will trigger cc::VideoFrameProviderClient::StartRendering.
261 // 5. Then cc::VideoFrameProviderClient will start calling
262 // WebMediaPlayerMSCompositor::UpdateCurrentFrame, GetCurrentFrame for
263 // rendering repeatedly.
264 // 6. When WebMediaPlayerMS::pause gets called, it should trigger
265 // content::VideoFrameProvider::Pause, and then the provider will stop
266 // pushing frames into WebMediaPlayerMS, but instead digesting them;
267 // simultanously, it should call cc::VideoFrameProviderClient::StopRendering,
268 // so cc::VideoFrameProviderClient will stop asking frames from
269 // WebMediaPlayerMSCompositor.
270 // 7. When WebMediaPlayerMS::play gets called, evething paused in step 6 should
271 // be resumed.
272 class WebMediaPlayerMSTest : public testing::Test,
273 public blink::WebMediaPlayerClient,
274 public cc::VideoFrameProvider::Client {
275 public:
276 WebMediaPlayerMSTest()
277 : render_factory_(new MockRenderFactory(message_loop_.task_runner(),
278 &message_loop_controller_)),
279 player_(nullptr,
280 this,
281 base::WeakPtr<media::WebMediaPlayerDelegate>(),
282 new media::MediaLog(),
283 scoped_ptr<MediaStreamRendererFactory>(render_factory_),
284 message_loop_.task_runner(),
285 message_loop_.task_runner(),
286 message_loop_.task_runner(),
287 nullptr,
288 blink::WebString(),
289 blink::WebSecurityOrigin()),
290 rendering_(false) {}
291 ~WebMediaPlayerMSTest() override {}
292
293 MockVideoFrameProvider* LoadAndGetFrameProvider(bool algorithm_enabled);
294
295 // Implementation of WebMediaPlayerClient
296 void networkStateChanged() override;
297 void readyStateChanged() override;
298 void timeChanged() override {}
299 void repaint() override {}
300 void durationChanged() override {}
301 void sizeChanged() override {}
302 void playbackStateChanged() override {}
303 void setWebLayer(blink::WebLayer* layer) override;
304 blink::WebMediaPlayer::TrackId addAudioTrack(const blink::WebString& id,
305 AudioTrackKind,
306 const blink::WebString& label,
307 const blink::WebString& language,
308 bool enabled) override {
309 return 0;
310 }
311 void removeAudioTrack(blink::WebMediaPlayer::TrackId) override {}
312 blink::WebMediaPlayer::TrackId addVideoTrack(const blink::WebString& id,
313 VideoTrackKind,
314 const blink::WebString& label,
315 const blink::WebString& language,
316 bool selected) override {
317 return 0;
318 }
319 void removeVideoTrack(blink::WebMediaPlayer::TrackId) override {}
320 void addTextTrack(blink::WebInbandTextTrack*) override {}
321 void removeTextTrack(blink::WebInbandTextTrack*) override {}
322 void mediaSourceOpened(blink::WebMediaSource*) override {}
323 void requestSeek(double) override {}
324 void remoteRouteAvailabilityChanged(bool) override {}
325 void connectedToRemoteDevice() override {}
326 void disconnectedFromRemoteDevice() override {}
327
328 // Implementation of cc::VideoFrameProvider::Client
329 void StopUsingProvider() override;
330 void StartRendering() override;
331 void StopRendering() override;
332 void DidReceiveFrame() override {}
333 void DidUpdateMatrix(const float* matrix) override {}
334
335 // For test use
336 void SetBackgroundRendering(bool background_rendering) {
337 background_rendering_ = background_rendering;
338 }
339
340 protected:
341 MOCK_METHOD0(DoStartRendering, void());
342 MOCK_METHOD0(DoStopRendering, void());
343
344 MOCK_METHOD1(DoSetWebLayer, void(bool));
345 MOCK_METHOD1(DoNetworkStateChanged,
346 void(blink::WebMediaPlayer::NetworkState));
347 MOCK_METHOD1(DoReadyStateChanged, void(blink::WebMediaPlayer::ReadyState));
348
349 base::MessageLoop message_loop_;
350 MockRenderFactory* render_factory_;
351 WebMediaPlayerMS player_;
352 WebMediaPlayerMSCompositor* compositor_;
353 ReusableMessageLoopEvent message_loop_controller_;
354
355 private:
356 // Main function trying to ask WebMediaPlayerMS to submit a frame for
357 // rendering.
358 void RenderFrame();
359
360 bool rendering_;
361 bool background_rendering_;
362 };
363
364 MockVideoFrameProvider* WebMediaPlayerMSTest::LoadAndGetFrameProvider(
365 bool algorithm_enabled) {
366 EXPECT_FALSE(!!render_factory_->provider()) << "There should not be a "
367 "FrameProvider yet.";
368
369 EXPECT_CALL(
370 *this, DoNetworkStateChanged(blink::WebMediaPlayer::NetworkStateLoading));
371 EXPECT_CALL(
372 *this, DoReadyStateChanged(blink::WebMediaPlayer::ReadyStateHaveNothing));
373 player_.load(blink::WebMediaPlayer::LoadTypeURL, blink::WebURL(),
374 blink::WebMediaPlayer::CORSModeUnspecified);
375 compositor_ = player_.compositor_.get();
376 EXPECT_TRUE(!!compositor_);
377 compositor_->SetAlgorithmEnabledForTesting(algorithm_enabled);
378
379 MockVideoFrameProvider* const provider = render_factory_->provider();
380 EXPECT_TRUE(!!provider);
381 EXPECT_TRUE(provider->Started());
382
383 testing::Mock::VerifyAndClearExpectations(this);
384 return provider;
385 }
386
387 void WebMediaPlayerMSTest::networkStateChanged() {
388 blink::WebMediaPlayer::NetworkState state = player_.networkState();
389 DoNetworkStateChanged(state);
390 if (state == blink::WebMediaPlayer::NetworkState::NetworkStateFormatError ||
391 state == blink::WebMediaPlayer::NetworkState::NetworkStateDecodeError ||
392 state == blink::WebMediaPlayer::NetworkState::NetworkStateNetworkError) {
393 message_loop_controller_.GetPipelineStatusCB().Run(
394 media::PipelineStatus::PIPELINE_ERROR_NETWORK);
395 }
396 }
397
398 void WebMediaPlayerMSTest::readyStateChanged() {
399 blink::WebMediaPlayer::ReadyState state = player_.readyState();
400 DoReadyStateChanged(state);
401 if (state == blink::WebMediaPlayer::ReadyState::ReadyStateHaveEnoughData)
402 player_.play();
403 }
404
405 void WebMediaPlayerMSTest::setWebLayer(blink::WebLayer* layer) {
406 if (layer)
407 compositor_->SetVideoFrameProviderClient(this);
408 DoSetWebLayer(!!layer);
409 }
410
411 void WebMediaPlayerMSTest::StopUsingProvider() {
412 if (rendering_)
413 StopRendering();
414 }
415
416 void WebMediaPlayerMSTest::StartRendering() {
417 if (!rendering_) {
418 rendering_ = true;
419 message_loop_.PostTask(
420 FROM_HERE,
421 base::Bind(&WebMediaPlayerMSTest::RenderFrame, base::Unretained(this)));
422 }
423 DoStartRendering();
424 }
425
426 void WebMediaPlayerMSTest::StopRendering() {
427 rendering_ = false;
428 DoStopRendering();
429 }
430
431 void WebMediaPlayerMSTest::RenderFrame() {
432 if (!rendering_ || !compositor_)
433 return;
434
435 base::TimeTicks now = base::TimeTicks::Now();
436 base::TimeTicks deadline_min =
437 now + base::TimeDelta::FromSecondsD(1.0 / 60.0);
438 base::TimeTicks deadline_max =
439 deadline_min + base::TimeDelta::FromSecondsD(1.0 / 60.0);
440
441 // Background rendering is different from stop rendering. The rendering loop
442 // is still running but we do not ask frames from |compositor_|. And
443 // background rendering is not initiated from |compositor_|.
444 if (!background_rendering_) {
445 compositor_->UpdateCurrentFrame(deadline_min, deadline_max);
446 auto frame = compositor_->GetCurrentFrame();
447 compositor_->PutCurrentFrame();
448 }
449 message_loop_.PostDelayedTask(
450 FROM_HERE,
451 base::Bind(&WebMediaPlayerMSTest::RenderFrame, base::Unretained(this)),
452 base::TimeDelta::FromSecondsD(1.0 / 60.0));
453 }
454
455 TEST_F(WebMediaPlayerMSTest, Playing_Normal) {
456 // This test sends a bunch of normal frames with increasing timestamps
457 // and verifies that they are produced by WebMediaPlayerMS in appropriate
458 // order.
459
460 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(true);
461
462 int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
463 333, 366, 400, 433, 466, 500, 533, 566, 600};
464 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
465 provider->QueueFrames(timestamps);
466
467 EXPECT_CALL(*this, DoSetWebLayer(true));
468 EXPECT_CALL(*this, DoStartRendering());
469 EXPECT_CALL(*this, DoReadyStateChanged(
470 blink::WebMediaPlayer::ReadyStateHaveMetadata));
471 EXPECT_CALL(*this, DoReadyStateChanged(
472 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
473 message_loop_controller_.RunAndWaitForStatus(
474 media::PipelineStatus::PIPELINE_OK);
475 testing::Mock::VerifyAndClearExpectations(this);
476
477 EXPECT_CALL(*this, DoSetWebLayer(false));
478 EXPECT_CALL(*this, DoStopRendering());
479 }
480
481 TEST_F(WebMediaPlayerMSTest, Playing_ErrorFrame) {
482 // This tests sends a broken frame to WebMediaPlayerMS, and verifies
483 // OnSourceError function works as expected.
484
485 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
486
487 const int kBrokenFrame = static_cast<int>(FrameType::BROKEN_FRAME);
488 int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
489 333, 366, 400, 433, 466, 500, 533, 566, 600, kBrokenFrame};
490 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
491 provider->QueueFrames(timestamps);
492
493 EXPECT_CALL(*this, DoSetWebLayer(true));
494 EXPECT_CALL(*this, DoStartRendering());
495 EXPECT_CALL(*this, DoReadyStateChanged(
496 blink::WebMediaPlayer::ReadyStateHaveMetadata));
497 EXPECT_CALL(*this, DoReadyStateChanged(
498 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
499 EXPECT_CALL(*this, DoNetworkStateChanged(
500 blink::WebMediaPlayer::NetworkStateFormatError));
501 message_loop_controller_.RunAndWaitForStatus(
502 media::PipelineStatus::PIPELINE_ERROR_NETWORK);
503 testing::Mock::VerifyAndClearExpectations(this);
504
505 EXPECT_CALL(*this, DoSetWebLayer(false));
506 EXPECT_CALL(*this, DoStopRendering());
507 }
508
509 TEST_F(WebMediaPlayerMSTest, PlayThenPause) {
510 // In the middle of this test, WebMediaPlayerMS::pause will be called, and we
511 // are going to verify that during the pause stage, a frame gets freezed, and
512 // cc::VideoFrameProviderClient should also be paused.
513 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
514
515 const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
516 int tokens[] = {0, 33, 66, 100, 133, kTestBrake, 166, 200, 233, 266,
517 300, 333, 366, 400, 433, 466, 500, 533, 566, 600};
518 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
519 provider->QueueFrames(timestamps);
520
521 EXPECT_CALL(*this, DoSetWebLayer(true));
522 EXPECT_CALL(*this, DoStartRendering());
523 EXPECT_CALL(*this, DoReadyStateChanged(
524 blink::WebMediaPlayer::ReadyStateHaveMetadata));
525 EXPECT_CALL(*this, DoReadyStateChanged(
526 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
527 message_loop_controller_.RunAndWaitForStatus(
528 media::PipelineStatus::PIPELINE_OK);
529 testing::Mock::VerifyAndClearExpectations(this);
530
531 // Here we call pause, and expect a freezing frame.
532 EXPECT_CALL(*this, DoStopRendering());
533 player_.pause();
534 auto prev_frame = compositor_->GetCurrentFrame();
535 message_loop_controller_.RunAndWaitForStatus(
536 media::PipelineStatus::PIPELINE_OK);
537 auto after_frame = compositor_->GetCurrentFrame();
538 EXPECT_EQ(prev_frame->timestamp(), after_frame->timestamp());
539 testing::Mock::VerifyAndClearExpectations(this);
540
541 EXPECT_CALL(*this, DoSetWebLayer(false));
542 }
543
544 TEST_F(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
545 // Similary to PlayAndPause test above, this one focuses on testing that
546 // WebMediaPlayerMS can be resumed after a period of paused status.
547 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
548
549 const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
550 int tokens[] = {0, 33, 66, 100, 133, kTestBrake, 166,
551 200, 233, 266, 300, 333, 366, 400,
552 433, kTestBrake, 466, 500, 533, 566, 600};
553 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
554 provider->QueueFrames(timestamps);
555
556 EXPECT_CALL(*this, DoSetWebLayer(true));
557 EXPECT_CALL(*this, DoStartRendering());
558 EXPECT_CALL(*this, DoReadyStateChanged(
559 blink::WebMediaPlayer::ReadyStateHaveMetadata));
560 EXPECT_CALL(*this, DoReadyStateChanged(
561 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
562 message_loop_controller_.RunAndWaitForStatus(
563 media::PipelineStatus::PIPELINE_OK);
564 testing::Mock::VerifyAndClearExpectations(this);
565
566 // Here we call pause, and expect a freezing frame.
567 EXPECT_CALL(*this, DoStopRendering());
568 player_.pause();
569 auto prev_frame = compositor_->GetCurrentFrame();
570 message_loop_controller_.RunAndWaitForStatus(
571 media::PipelineStatus::PIPELINE_OK);
572 auto after_frame = compositor_->GetCurrentFrame();
573 EXPECT_EQ(prev_frame->timestamp(), after_frame->timestamp());
574 testing::Mock::VerifyAndClearExpectations(this);
575
576 // We resume the player, and expect rendering can continue.
577 EXPECT_CALL(*this, DoStartRendering());
578 player_.play();
579 prev_frame = compositor_->GetCurrentFrame();
580 message_loop_controller_.RunAndWaitForStatus(
581 media::PipelineStatus::PIPELINE_OK);
582 after_frame = compositor_->GetCurrentFrame();
583 EXPECT_NE(prev_frame->timestamp(), after_frame->timestamp());
584 testing::Mock::VerifyAndClearExpectations(this);
585
586 EXPECT_CALL(*this, DoSetWebLayer(false));
587 EXPECT_CALL(*this, DoStopRendering());
588 }
589
590 TEST_F(WebMediaPlayerMSTest, BackgroudRendering) {
591 // During this test, we will switch to background rendering mode, in which
592 // WebMediaPlayerMS::pause does not get called, but
593 // cc::VideoFrameProviderClient simply stops asking frames from
594 // WebMediaPlayerMS without an explicit notification. We should expect that
595 // WebMediaPlayerMS can digest old frames, rather than piling frames up and
596 // explode.
597 MockVideoFrameProvider* provider = LoadAndGetFrameProvider(true);
598
599 const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
600 int tokens[] = {0, 33, 66, 100, 133, kTestBrake, 166,
601 200, 233, 266, 300, 333, 366, 400,
602 433, kTestBrake, 466, 500, 533, 566, 600};
603 std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
604 provider->QueueFrames(timestamps);
605
606 EXPECT_CALL(*this, DoSetWebLayer(true));
607 EXPECT_CALL(*this, DoStartRendering());
608 EXPECT_CALL(*this, DoReadyStateChanged(
609 blink::WebMediaPlayer::ReadyStateHaveMetadata));
610 EXPECT_CALL(*this, DoReadyStateChanged(
611 blink::WebMediaPlayer::ReadyStateHaveEnoughData));
612
613 message_loop_controller_.RunAndWaitForStatus(
614 media::PipelineStatus::PIPELINE_OK);
615 testing::Mock::VerifyAndClearExpectations(this);
616
617 // Switch to background rendering, expect rendering to continue.
618 SetBackgroundRendering(true);
619 auto prev_frame = compositor_->GetCurrentFrame();
620 message_loop_controller_.RunAndWaitForStatus(
621 media::PipelineStatus::PIPELINE_OK);
622 auto after_frame = compositor_->GetCurrentFrame();
623 EXPECT_NE(prev_frame->timestamp(), after_frame->timestamp());
624
625 // Switch to foreground rendering.
626 SetBackgroundRendering(false);
627 prev_frame = compositor_->GetCurrentFrame();
628 message_loop_controller_.RunAndWaitForStatus(
629 media::PipelineStatus::PIPELINE_OK);
630 after_frame = compositor_->GetCurrentFrame();
631 EXPECT_NE(prev_frame->timestamp(), after_frame->timestamp());
632 testing::Mock::VerifyAndClearExpectations(this);
633
634 EXPECT_CALL(*this, DoSetWebLayer(false));
635 EXPECT_CALL(*this, DoStopRendering());
636 }
637
638 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webmediaplayer_ms_compositor.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698