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

Side by Side Diff: media/mojo/clients/mojo_renderer_unittest.cc

Issue 2239243002: Interpolate media time for mojo rendering pipeline. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdint.h> 5 #include <stdint.h>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
11 #include "base/threading/platform_thread.h" 11 #include "base/threading/platform_thread.h"
12 #include "base/timer/elapsed_timer.h"
12 #include "media/base/audio_renderer_sink.h" 13 #include "media/base/audio_renderer_sink.h"
13 #include "media/base/cdm_config.h" 14 #include "media/base/cdm_config.h"
14 #include "media/base/cdm_context.h" 15 #include "media/base/cdm_context.h"
15 #include "media/base/gmock_callback_support.h" 16 #include "media/base/gmock_callback_support.h"
16 #include "media/base/mock_filters.h" 17 #include "media/base/mock_filters.h"
17 #include "media/base/test_helpers.h" 18 #include "media/base/test_helpers.h"
18 #include "media/base/video_renderer_sink.h" 19 #include "media/base/video_renderer_sink.h"
19 #include "media/cdm/default_cdm_factory.h" 20 #include "media/cdm/default_cdm_factory.h"
20 #include "media/mojo/clients/mojo_renderer.h" 21 #include "media/mojo/clients/mojo_renderer.h"
21 #include "media/mojo/common/media_type_converters.h" 22 #include "media/mojo/common/media_type_converters.h"
22 #include "media/mojo/interfaces/content_decryption_module.mojom.h" 23 #include "media/mojo/interfaces/content_decryption_module.mojom.h"
23 #include "media/mojo/interfaces/renderer.mojom.h" 24 #include "media/mojo/interfaces/renderer.mojom.h"
24 #include "media/mojo/services/mojo_cdm_service.h" 25 #include "media/mojo/services/mojo_cdm_service.h"
25 #include "media/mojo/services/mojo_cdm_service_context.h" 26 #include "media/mojo/services/mojo_cdm_service_context.h"
26 #include "media/mojo/services/mojo_renderer_service.h" 27 #include "media/mojo/services/mojo_renderer_service.h"
27 #include "media/renderers/video_overlay_factory.h" 28 #include "media/renderers/video_overlay_factory.h"
28 #include "mojo/public/cpp/bindings/interface_request.h" 29 #include "mojo/public/cpp/bindings/interface_request.h"
29 #include "testing/gtest/include/gtest/gtest.h" 30 #include "testing/gtest/include/gtest/gtest.h"
30 31
31 using ::testing::_; 32 using ::testing::_;
32 using ::testing::DoAll; 33 using ::testing::DoAll;
33 using ::testing::Return; 34 using ::testing::Return;
34 using ::testing::SaveArg; 35 using ::testing::SaveArg;
35 using ::testing::StrictMock; 36 using ::testing::StrictMock;
36 37
37 namespace media { 38 namespace media {
38 39
40 namespace {
39 const int64_t kStartPlayingTimeInMs = 100; 41 const int64_t kStartPlayingTimeInMs = 100;
40 const char kClearKeyKeySystem[] = "org.w3.clearkey"; 42 const char kClearKeyKeySystem[] = "org.w3.clearkey";
41 43
42 ACTION_P2(SetError, renderer_client, error) { 44 ACTION_P2(SetError, renderer_client, error) {
43 renderer_client->OnError(error); 45 renderer_client->OnError(error);
44 } 46 }
45 47
48 void WaitFor(base::TimeDelta duration) {
DaleCurtis 2016/09/06 19:21:25 Does RunLoop().RunUntilIdle() not suffice?
alokp 2016/09/07 16:46:21 I want a few of the time-update tasks to be posted
49 base::RunLoop run_loop;
50 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
51 FROM_HERE, run_loop.QuitClosure(), duration);
52 run_loop.Run();
53 }
54 } // namespace
55
46 class MojoRendererTest : public ::testing::Test { 56 class MojoRendererTest : public ::testing::Test {
47 public: 57 public:
48 MojoRendererTest() { 58 MojoRendererTest() {
49 std::unique_ptr<StrictMock<MockRenderer>> mock_renderer( 59 std::unique_ptr<StrictMock<MockRenderer>> mock_renderer(
50 new StrictMock<MockRenderer>()); 60 new StrictMock<MockRenderer>());
51 mock_renderer_ = mock_renderer.get(); 61 mock_renderer_ = mock_renderer.get();
52 62
53 mojom::RendererPtr remote_renderer; 63 mojom::RendererPtr remote_renderer;
54 64
55 mojo_renderer_service_ = new MojoRendererService( 65 mojo_renderer_service_ = new MojoRendererService(
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } 238 }
229 239
230 TEST_F(MojoRendererTest, Initialize_AfterConnectionError) { 240 TEST_F(MojoRendererTest, Initialize_AfterConnectionError) {
231 ConnectionError(); 241 ConnectionError();
232 CreateAudioStream(); 242 CreateAudioStream();
233 InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED); 243 InitializeAndExpect(PIPELINE_ERROR_INITIALIZATION_FAILED);
234 } 244 }
235 245
236 TEST_F(MojoRendererTest, Flush_Success) { 246 TEST_F(MojoRendererTest, Flush_Success) {
237 Initialize(); 247 Initialize();
248 Play();
alokp 2016/09/02 22:51:18 It is illegal to call Flush when Renderer is not p
DaleCurtis 2016/09/06 19:21:25 Add DCHECK in Mojo renderer?
alokp 2016/09/07 16:46:21 I was wrong about Flush being illegal. RendererImp
238 249
239 EXPECT_CALL(*mock_renderer_, Flush(_)).WillOnce(RunClosure<0>()); 250 EXPECT_CALL(*mock_renderer_, Flush(_)).WillOnce(RunClosure<0>());
240 Flush(); 251 Flush();
241 } 252 }
242 253
243 TEST_F(MojoRendererTest, Flush_ConnectionError) { 254 TEST_F(MojoRendererTest, Flush_ConnectionError) {
244 Initialize(); 255 Initialize();
256 Play();
alokp 2016/09/02 22:51:17 ditto.
245 257
246 // Upon connection error, OnError() should be called once and only once. 258 // Upon connection error, OnError() should be called once and only once.
247 EXPECT_CALL(renderer_client_, OnError(PIPELINE_ERROR_DECODE)).Times(1); 259 EXPECT_CALL(renderer_client_, OnError(PIPELINE_ERROR_DECODE)).Times(1);
248 EXPECT_CALL(*mock_renderer_, Flush(_)) 260 EXPECT_CALL(*mock_renderer_, Flush(_))
249 .WillOnce(InvokeWithoutArgs(this, &MojoRendererTest::ConnectionError)); 261 .WillOnce(InvokeWithoutArgs(this, &MojoRendererTest::ConnectionError));
250 Flush(); 262 Flush();
251 } 263 }
252 264
253 TEST_F(MojoRendererTest, Flush_AfterConnectionError) { 265 TEST_F(MojoRendererTest, Flush_AfterConnectionError) {
254 Initialize(); 266 Initialize();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 331
320 TEST_F(MojoRendererTest, StartPlayingFrom) { 332 TEST_F(MojoRendererTest, StartPlayingFrom) {
321 Initialize(); 333 Initialize();
322 Play(); 334 Play();
323 } 335 }
324 336
325 TEST_F(MojoRendererTest, GetMediaTime) { 337 TEST_F(MojoRendererTest, GetMediaTime) {
326 Initialize(); 338 Initialize();
327 EXPECT_EQ(base::TimeDelta(), mojo_renderer_->GetMediaTime()); 339 EXPECT_EQ(base::TimeDelta(), mojo_renderer_->GetMediaTime());
328 340
329 Play(); 341 const base::TimeDelta kSleepTime = base::TimeDelta::FromMilliseconds(500);
342 const base::TimeDelta kStartTime =
343 base::TimeDelta::FromMilliseconds(kStartPlayingTimeInMs);
330 344
331 // Time is updated periodically with a short delay. 345 // Media time should not advance since playback rate is 0.
332 const base::TimeDelta kUpdatedTime = base::TimeDelta::FromMilliseconds(500); 346 EXPECT_CALL(*mock_renderer_, SetPlaybackRate(0));
347 EXPECT_CALL(*mock_renderer_, StartPlayingFrom(kStartTime));
333 EXPECT_CALL(*mock_renderer_, GetMediaTime()) 348 EXPECT_CALL(*mock_renderer_, GetMediaTime())
334 .WillRepeatedly(Return(kUpdatedTime)); 349 .WillRepeatedly(Return(kStartTime));
335 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 350 mojo_renderer_->SetPlaybackRate(0);
336 base::RunLoop().RunUntilIdle(); 351 mojo_renderer_->StartPlayingFrom(kStartTime);
337 EXPECT_EQ(kUpdatedTime, mojo_renderer_->GetMediaTime()); 352 WaitFor(kSleepTime);
353 EXPECT_EQ(kStartTime, mojo_renderer_->GetMediaTime());
354
355 // Media time should now advance since playback rate is > 0.
356 std::unique_ptr<base::ElapsedTimer> elapsed_timer(new base::ElapsedTimer);
357 EXPECT_CALL(*mock_renderer_, SetPlaybackRate(1.0));
358 EXPECT_CALL(*mock_renderer_, GetMediaTime())
359 .WillRepeatedly(Return(elapsed_timer->Elapsed()));
360 mojo_renderer_->SetPlaybackRate(1.0);
361 WaitFor(kSleepTime);
362 EXPECT_GT(mojo_renderer_->GetMediaTime(), kStartTime);
363
364 // Flushing should pause media-time updates.
365 EXPECT_CALL(*mock_renderer_, Flush(_)).WillOnce(RunClosure<0>());
366 Flush();
367 base::TimeDelta pause_time = mojo_renderer_->GetMediaTime();
368 EXPECT_GT(pause_time, kStartTime);
369 WaitFor(kSleepTime);
370 EXPECT_EQ(pause_time, mojo_renderer_->GetMediaTime());
371 Destroy();
338 } 372 }
339 373
340 TEST_F(MojoRendererTest, OnEnded) { 374 TEST_F(MojoRendererTest, OnEnded) {
341 Initialize(); 375 Initialize();
342 Play(); 376 Play();
343 377
344 EXPECT_CALL(renderer_client_, OnEnded()).Times(1); 378 EXPECT_CALL(renderer_client_, OnEnded()).Times(1);
345 remote_renderer_client_->OnEnded(); 379 remote_renderer_client_->OnEnded();
346 base::RunLoop().RunUntilIdle(); 380 base::RunLoop().RunUntilIdle();
347 } 381 }
(...skipping 16 matching lines...) Expand all
364 .WillRepeatedly(RunCallback<1>(true)); 398 .WillRepeatedly(RunCallback<1>(true));
365 EXPECT_CALL(*this, OnCdmAttached(false)); 399 EXPECT_CALL(*this, OnCdmAttached(false));
366 mojo_renderer_->SetCdm( 400 mojo_renderer_->SetCdm(
367 &cdm_context_, 401 &cdm_context_,
368 base::Bind(&MojoRendererTest::OnCdmAttached, base::Unretained(this))); 402 base::Bind(&MojoRendererTest::OnCdmAttached, base::Unretained(this)));
369 Destroy(); 403 Destroy();
370 } 404 }
371 405
372 TEST_F(MojoRendererTest, Destroy_PendingSetCdm) { 406 TEST_F(MojoRendererTest, Destroy_PendingSetCdm) {
373 Initialize(); 407 Initialize();
408 Play();
alokp 2016/09/02 22:51:17 ditto
409
374 EXPECT_CALL(*mock_renderer_, Flush(_)).WillRepeatedly(RunClosure<0>()); 410 EXPECT_CALL(*mock_renderer_, Flush(_)).WillRepeatedly(RunClosure<0>());
375 EXPECT_CALL(*this, OnFlushed()); 411 EXPECT_CALL(*this, OnFlushed());
376 mojo_renderer_->Flush( 412 mojo_renderer_->Flush(
377 base::Bind(&MojoRendererTest::OnFlushed, base::Unretained(this))); 413 base::Bind(&MojoRendererTest::OnFlushed, base::Unretained(this)));
378 Destroy(); 414 Destroy();
379 } 415 }
380 416
381 // TODO(xhwang): Add more tests on OnError. For example, ErrorDuringFlush, 417 // TODO(xhwang): Add more tests on OnError. For example, ErrorDuringFlush,
382 // ErrorAfterFlush etc. 418 // ErrorAfterFlush etc.
383 419
384 TEST_F(MojoRendererTest, ErrorDuringPlayback) { 420 TEST_F(MojoRendererTest, ErrorDuringPlayback) {
385 Initialize(); 421 Initialize();
386 422
387 EXPECT_CALL(renderer_client_, OnError(PIPELINE_ERROR_DECODE)).Times(1); 423 EXPECT_CALL(renderer_client_, OnError(PIPELINE_ERROR_DECODE)).Times(1);
388 424
389 Play(); 425 Play();
390 remote_renderer_client_->OnError(PIPELINE_ERROR_DECODE); 426 remote_renderer_client_->OnError(PIPELINE_ERROR_DECODE);
391 base::RunLoop().RunUntilIdle(); 427 base::RunLoop().RunUntilIdle();
392 428
393 EXPECT_CALL(*mock_renderer_, SetPlaybackRate(0.0)).Times(1); 429 EXPECT_CALL(*mock_renderer_, SetPlaybackRate(0.0)).Times(1);
394 mojo_renderer_->SetPlaybackRate(0.0); 430 mojo_renderer_->SetPlaybackRate(0.0);
395 Flush(); 431 Flush();
396 } 432 }
397 433
398 } // namespace media 434 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698