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

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