OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <string> | 5 #include <string> |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/stl_util-inl.h" | 8 #include "base/stl_util-inl.h" |
| 9 #include "base/threading/simple_thread.h" |
9 #include "media/base/pipeline_impl.h" | 10 #include "media/base/pipeline_impl.h" |
10 #include "media/base/media_format.h" | 11 #include "media/base/media_format.h" |
11 #include "media/base/filters.h" | 12 #include "media/base/filters.h" |
12 #include "media/base/filter_host.h" | 13 #include "media/base/filter_host.h" |
13 #include "media/base/mock_callback.h" | 14 #include "media/base/mock_callback.h" |
14 #include "media/base/mock_filters.h" | 15 #include "media/base/mock_filters.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 | 17 |
17 using ::testing::_; | 18 using ::testing::_; |
18 using ::testing::DeleteArg; | 19 using ::testing::DeleteArg; |
(...skipping 13 matching lines...) Expand all Loading... |
32 // Buffered bytes of the data source. | 33 // Buffered bytes of the data source. |
33 static const int kBufferedBytes = 1024; | 34 static const int kBufferedBytes = 1024; |
34 | 35 |
35 // Used for setting expectations on pipeline callbacks. Using a StrictMock | 36 // Used for setting expectations on pipeline callbacks. Using a StrictMock |
36 // also lets us test for missing callbacks. | 37 // also lets us test for missing callbacks. |
37 class CallbackHelper { | 38 class CallbackHelper { |
38 public: | 39 public: |
39 CallbackHelper() {} | 40 CallbackHelper() {} |
40 virtual ~CallbackHelper() {} | 41 virtual ~CallbackHelper() {} |
41 | 42 |
42 MOCK_METHOD0(OnStart, void()); | 43 MOCK_METHOD1(OnStart, void(PipelineStatus)); |
43 MOCK_METHOD0(OnSeek, void()); | 44 MOCK_METHOD1(OnSeek, void(PipelineStatus)); |
44 MOCK_METHOD0(OnStop, void()); | 45 MOCK_METHOD1(OnStop, void(PipelineStatus)); |
45 MOCK_METHOD0(OnEnded, void()); | 46 MOCK_METHOD1(OnEnded, void(PipelineStatus)); |
46 MOCK_METHOD0(OnError, void()); | 47 MOCK_METHOD1(OnError, void(PipelineStatus)); |
47 | 48 |
48 private: | 49 private: |
49 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); | 50 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); |
50 }; | 51 }; |
51 | 52 |
52 // TODO(scherkus): even though some filters are initialized on separate | 53 // TODO(scherkus): even though some filters are initialized on separate |
53 // threads these test aren't flaky... why? It's because filters' Initialize() | 54 // threads these test aren't flaky... why? It's because filters' Initialize() |
54 // is executed on |message_loop_| and the mock filters instantly call | 55 // is executed on |message_loop_| and the mock filters instantly call |
55 // InitializationComplete(), which keeps the pipeline humming along. If | 56 // InitializationComplete(), which keeps the pipeline humming along. If |
56 // either filters don't call InitializationComplete() immediately or filter | 57 // either filters don't call InitializationComplete() immediately or filter |
57 // initialization is moved to a separate thread this test will become flaky. | 58 // initialization is moved to a separate thread this test will become flaky. |
58 class PipelineImplTest : public ::testing::Test { | 59 class PipelineImplTest : public ::testing::Test { |
59 public: | 60 public: |
60 PipelineImplTest() | 61 PipelineImplTest() |
61 : pipeline_(new PipelineImpl(&message_loop_)) { | 62 : pipeline_(new PipelineImpl(&message_loop_)) { |
62 pipeline_->Init( | 63 pipeline_->Init( |
63 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), | 64 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), |
64 &CallbackHelper::OnEnded), | 65 &CallbackHelper::OnEnded), |
65 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), | 66 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), |
66 &CallbackHelper::OnError), | 67 &CallbackHelper::OnError), |
67 NULL); | 68 static_cast<PipelineStatusCallback*>(NULL)); |
68 mocks_.reset(new MockFilterCollection()); | 69 mocks_.reset(new MockFilterCollection()); |
69 } | 70 } |
70 | 71 |
71 virtual ~PipelineImplTest() { | 72 virtual ~PipelineImplTest() { |
72 if (!pipeline_->IsRunning()) { | 73 if (!pipeline_->IsRunning()) { |
73 return; | 74 return; |
74 } | 75 } |
75 | 76 |
76 // Expect a stop callback if we were started. | 77 // Expect a stop callback if we were started. |
77 EXPECT_CALL(callbacks_, OnStop()); | 78 EXPECT_CALL(callbacks_, OnStop(PIPELINE_OK)); |
78 pipeline_->Stop(NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), | 79 pipeline_->Stop(NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), |
79 &CallbackHelper::OnStop)); | 80 &CallbackHelper::OnStop)); |
80 message_loop_.RunAllPending(); | 81 message_loop_.RunAllPending(); |
81 | 82 |
82 mocks_.reset(); | 83 mocks_.reset(); |
83 } | 84 } |
84 | 85 |
85 protected: | 86 protected: |
86 // Sets up expectations to allow the demuxer to initialize. | 87 // Sets up expectations to allow the demuxer to initialize. |
87 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; | 88 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 .WillOnce(Invoke(&RunFilterCallback)); | 168 .WillOnce(Invoke(&RunFilterCallback)); |
168 EXPECT_CALL(*mocks_->audio_renderer(), Stop(NotNull())) | 169 EXPECT_CALL(*mocks_->audio_renderer(), Stop(NotNull())) |
169 .WillOnce(Invoke(&RunStopFilterCallback)); | 170 .WillOnce(Invoke(&RunStopFilterCallback)); |
170 } | 171 } |
171 | 172 |
172 // Sets up expectations on the callback and initializes the pipeline. Called | 173 // Sets up expectations on the callback and initializes the pipeline. Called |
173 // after tests have set expectations any filters they wish to use. | 174 // after tests have set expectations any filters they wish to use. |
174 void InitializePipeline() { | 175 void InitializePipeline() { |
175 InitializePipeline(PIPELINE_OK); | 176 InitializePipeline(PIPELINE_OK); |
176 } | 177 } |
177 | 178 // Most tests can expect the |filter_collection|'s |build_status| to get |
178 void InitializePipeline(PipelineError factory_error) { | 179 // reflected in |Start()|'s argument. |
| 180 void InitializePipeline(PipelineStatus start_status) { |
| 181 InitializePipeline(start_status, start_status); |
| 182 } |
| 183 // But some tests require different statuses in build & Start. |
| 184 void InitializePipeline(PipelineStatus build_status, |
| 185 PipelineStatus start_status) { |
179 // Expect an initialization callback. | 186 // Expect an initialization callback. |
180 EXPECT_CALL(callbacks_, OnStart()); | 187 EXPECT_CALL(callbacks_, OnStart(start_status)); |
181 pipeline_->Start(mocks_->filter_collection(true, true, factory_error), | 188 pipeline_->Start(mocks_->filter_collection(true, true, build_status), "", |
182 "", | |
183 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), | 189 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), |
184 &CallbackHelper::OnStart)); | 190 &CallbackHelper::OnStart)); |
185 message_loop_.RunAllPending(); | 191 message_loop_.RunAllPending(); |
186 } | 192 } |
187 | 193 |
188 void CreateAudioStream() { | 194 void CreateAudioStream() { |
189 audio_stream_ = CreateStream(DemuxerStream::AUDIO); | 195 audio_stream_ = CreateStream(DemuxerStream::AUDIO); |
190 } | 196 } |
191 | 197 |
192 void CreateVideoStream() { | 198 void CreateVideoStream() { |
(...skipping 21 matching lines...) Expand all Loading... |
214 } | 220 } |
215 | 221 |
216 if (video_stream_) { | 222 if (video_stream_) { |
217 EXPECT_CALL(*mocks_->video_decoder(), Seek(seek_time, NotNull())) | 223 EXPECT_CALL(*mocks_->video_decoder(), Seek(seek_time, NotNull())) |
218 .WillOnce(Invoke(&RunFilterCallback)); | 224 .WillOnce(Invoke(&RunFilterCallback)); |
219 EXPECT_CALL(*mocks_->video_renderer(), Seek(seek_time, NotNull())) | 225 EXPECT_CALL(*mocks_->video_renderer(), Seek(seek_time, NotNull())) |
220 .WillOnce(Invoke(&RunFilterCallback)); | 226 .WillOnce(Invoke(&RunFilterCallback)); |
221 } | 227 } |
222 | 228 |
223 // We expect a successful seek callback. | 229 // We expect a successful seek callback. |
224 EXPECT_CALL(callbacks_, OnSeek()); | 230 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
225 | 231 |
226 } | 232 } |
227 | 233 |
228 void DoSeek(const base::TimeDelta& seek_time) { | 234 void DoSeek(const base::TimeDelta& seek_time) { |
229 pipeline_->Seek(seek_time, | 235 pipeline_->Seek(seek_time, |
230 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), | 236 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), |
231 &CallbackHelper::OnSeek)); | 237 &CallbackHelper::OnSeek)); |
232 | 238 |
233 // We expect the time to be updated only after the seek has completed. | 239 // We expect the time to be updated only after the seek has completed. |
234 EXPECT_NE(seek_time, pipeline_->GetCurrentTime()); | 240 EXPECT_NE(seek_time, pipeline_->GetCurrentTime()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 292 |
287 EXPECT_EQ(0, pipeline_->GetBufferedBytes()); | 293 EXPECT_EQ(0, pipeline_->GetBufferedBytes()); |
288 EXPECT_EQ(0, pipeline_->GetTotalBytes()); | 294 EXPECT_EQ(0, pipeline_->GetTotalBytes()); |
289 | 295 |
290 // Should always get set to zero. | 296 // Should always get set to zero. |
291 size_t width = 1u; | 297 size_t width = 1u; |
292 size_t height = 1u; | 298 size_t height = 1u; |
293 pipeline_->GetVideoSize(&width, &height); | 299 pipeline_->GetVideoSize(&width, &height); |
294 EXPECT_EQ(0u, width); | 300 EXPECT_EQ(0u, width); |
295 EXPECT_EQ(0u, height); | 301 EXPECT_EQ(0u, height); |
296 | |
297 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
298 } | 302 } |
299 | 303 |
300 TEST_F(PipelineImplTest, NeverInitializes) { | 304 TEST_F(PipelineImplTest, NeverInitializes) { |
301 // This test hangs during initialization by never calling | 305 // This test hangs during initialization by never calling |
302 // InitializationComplete(). StrictMock<> will ensure that the callback is | 306 // InitializationComplete(). StrictMock<> will ensure that the callback is |
303 // never executed. | 307 // never executed. |
304 pipeline_->Start(mocks_->filter_collection(false, false, PIPELINE_OK), "", | 308 pipeline_->Start(mocks_->filter_collection(false, false, PIPELINE_OK), "", |
305 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), | 309 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), |
306 &CallbackHelper::OnStart)); | 310 &CallbackHelper::OnStart)); |
307 message_loop_.RunAllPending(); | 311 message_loop_.RunAllPending(); |
308 | 312 |
309 EXPECT_FALSE(pipeline_->IsInitialized()); | 313 EXPECT_FALSE(pipeline_->IsInitialized()); |
310 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
311 | 314 |
312 // Because our callback will get executed when the test tears down, we'll | 315 // Because our callback will get executed when the test tears down, we'll |
313 // verify that nothing has been called, then set our expectation for the call | 316 // verify that nothing has been called, then set our expectation for the call |
314 // made during tear down. | 317 // made during tear down. |
315 Mock::VerifyAndClear(&callbacks_); | 318 Mock::VerifyAndClear(&callbacks_); |
316 EXPECT_CALL(callbacks_, OnStart()); | 319 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); |
317 } | 320 } |
318 | 321 |
319 TEST_F(PipelineImplTest, RequiredFilterMissing) { | 322 TEST_F(PipelineImplTest, RequiredFilterMissing) { |
320 EXPECT_CALL(callbacks_, OnError()); | 323 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING)); |
321 | 324 |
322 // Sets up expectations on the callback and initializes the pipeline. Called | 325 // Sets up expectations on the callback and initializes the pipeline. Called |
323 // after tests have set expectations any filters they wish to use. | 326 // after tests have set expectations any filters they wish to use. |
324 // Expect an initialization callback. | 327 // Expect an initialization callback. |
325 EXPECT_CALL(callbacks_, OnStart()); | 328 EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_REQUIRED_FILTER_MISSING)); |
326 | 329 |
327 // Create a filter collection with missing filter. | 330 // Create a filter collection with missing filter. |
328 FilterCollection* collection = | 331 FilterCollection* collection = |
329 mocks_->filter_collection(false, true, | 332 mocks_->filter_collection(false, true, |
330 PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 333 PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
331 pipeline_->Start(collection, "", | 334 pipeline_->Start(collection, "", |
332 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), | 335 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), |
333 &CallbackHelper::OnStart)); | 336 &CallbackHelper::OnStart)); |
334 message_loop_.RunAllPending(); | 337 message_loop_.RunAllPending(); |
335 | 338 |
336 EXPECT_FALSE(pipeline_->IsInitialized()); | 339 EXPECT_FALSE(pipeline_->IsInitialized()); |
337 EXPECT_EQ(PIPELINE_ERROR_REQUIRED_FILTER_MISSING, | |
338 pipeline_->GetError()); | |
339 } | 340 } |
340 | 341 |
341 TEST_F(PipelineImplTest, URLNotFound) { | 342 TEST_F(PipelineImplTest, URLNotFound) { |
342 | 343 // TODO(acolwell,fischman): Since OnStart() is getting called with an error |
343 EXPECT_CALL(callbacks_, OnError()); | 344 // code already, OnError() doesn't also need to get called. Fix the pipeline |
344 | 345 // (and it's consumers!) so that OnError doesn't need to be called after |
| 346 // another callback has already reported the error. Same applies to NoStreams |
| 347 // below. |
| 348 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_URL_NOT_FOUND)); |
345 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND); | 349 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND); |
346 EXPECT_FALSE(pipeline_->IsInitialized()); | 350 EXPECT_FALSE(pipeline_->IsInitialized()); |
347 EXPECT_EQ(PIPELINE_ERROR_URL_NOT_FOUND, pipeline_->GetError()); | |
348 } | 351 } |
349 | 352 |
350 TEST_F(PipelineImplTest, NoStreams) { | 353 TEST_F(PipelineImplTest, NoStreams) { |
351 // Manually set these expectations because SetPlaybackRate() is not called if | 354 // Manually set these expectations because SetPlaybackRate() is not called if |
352 // we cannot fully initialize the pipeline. | 355 // we cannot fully initialize the pipeline. |
353 EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams()) | 356 EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams()) |
354 .WillRepeatedly(Return(0)); | 357 .WillRepeatedly(Return(0)); |
355 EXPECT_CALL(*mocks_->demuxer(), Stop(NotNull())) | 358 EXPECT_CALL(*mocks_->demuxer(), Stop(NotNull())) |
356 .WillOnce(Invoke(&RunStopFilterCallback)); | 359 .WillOnce(Invoke(&RunStopFilterCallback)); |
357 EXPECT_CALL(callbacks_, OnError()); | 360 // TODO(acolwell,fischman): see TODO in URLNotFound above. |
| 361 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_COULD_NOT_RENDER)); |
358 | 362 |
359 InitializePipeline(); | 363 InitializePipeline(PIPELINE_OK, PIPELINE_ERROR_COULD_NOT_RENDER); |
360 EXPECT_FALSE(pipeline_->IsInitialized()); | 364 EXPECT_FALSE(pipeline_->IsInitialized()); |
361 EXPECT_EQ(PIPELINE_ERROR_COULD_NOT_RENDER, pipeline_->GetError()); | |
362 } | 365 } |
363 | 366 |
364 TEST_F(PipelineImplTest, AudioStream) { | 367 TEST_F(PipelineImplTest, AudioStream) { |
365 CreateAudioStream(); | 368 CreateAudioStream(); |
366 MockDemuxerStreamVector streams; | 369 MockDemuxerStreamVector streams; |
367 streams.push_back(audio_stream()); | 370 streams.push_back(audio_stream()); |
368 | 371 |
369 InitializeDemuxer(&streams, base::TimeDelta()); | 372 InitializeDemuxer(&streams, base::TimeDelta()); |
370 InitializeAudioDecoder(audio_stream()); | 373 InitializeAudioDecoder(audio_stream()); |
371 InitializeAudioRenderer(); | 374 InitializeAudioRenderer(); |
372 | 375 |
373 InitializePipeline(); | 376 InitializePipeline(PIPELINE_OK); |
374 EXPECT_TRUE(pipeline_->IsInitialized()); | 377 EXPECT_TRUE(pipeline_->IsInitialized()); |
375 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
376 EXPECT_TRUE(pipeline_->HasAudio()); | 378 EXPECT_TRUE(pipeline_->HasAudio()); |
377 EXPECT_FALSE(pipeline_->HasVideo()); | 379 EXPECT_FALSE(pipeline_->HasVideo()); |
378 } | 380 } |
379 | 381 |
380 TEST_F(PipelineImplTest, VideoStream) { | 382 TEST_F(PipelineImplTest, VideoStream) { |
381 CreateVideoStream(); | 383 CreateVideoStream(); |
382 MockDemuxerStreamVector streams; | 384 MockDemuxerStreamVector streams; |
383 streams.push_back(video_stream()); | 385 streams.push_back(video_stream()); |
384 | 386 |
385 InitializeDemuxer(&streams, base::TimeDelta()); | 387 InitializeDemuxer(&streams, base::TimeDelta()); |
386 InitializeVideoDecoder(video_stream()); | 388 InitializeVideoDecoder(video_stream()); |
387 InitializeVideoRenderer(); | 389 InitializeVideoRenderer(); |
388 | 390 |
389 InitializePipeline(); | 391 InitializePipeline(PIPELINE_OK); |
390 EXPECT_TRUE(pipeline_->IsInitialized()); | 392 EXPECT_TRUE(pipeline_->IsInitialized()); |
391 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
392 EXPECT_FALSE(pipeline_->HasAudio()); | 393 EXPECT_FALSE(pipeline_->HasAudio()); |
393 EXPECT_TRUE(pipeline_->HasVideo()); | 394 EXPECT_TRUE(pipeline_->HasVideo()); |
394 } | 395 } |
395 | 396 |
396 TEST_F(PipelineImplTest, AudioVideoStream) { | 397 TEST_F(PipelineImplTest, AudioVideoStream) { |
397 CreateAudioStream(); | 398 CreateAudioStream(); |
398 CreateVideoStream(); | 399 CreateVideoStream(); |
399 MockDemuxerStreamVector streams; | 400 MockDemuxerStreamVector streams; |
400 streams.push_back(audio_stream()); | 401 streams.push_back(audio_stream()); |
401 streams.push_back(video_stream()); | 402 streams.push_back(video_stream()); |
402 | 403 |
403 InitializeDemuxer(&streams, base::TimeDelta()); | 404 InitializeDemuxer(&streams, base::TimeDelta()); |
404 InitializeAudioDecoder(audio_stream()); | 405 InitializeAudioDecoder(audio_stream()); |
405 InitializeAudioRenderer(); | 406 InitializeAudioRenderer(); |
406 InitializeVideoDecoder(video_stream()); | 407 InitializeVideoDecoder(video_stream()); |
407 InitializeVideoRenderer(); | 408 InitializeVideoRenderer(); |
408 | 409 |
409 InitializePipeline(); | 410 InitializePipeline(PIPELINE_OK); |
410 EXPECT_TRUE(pipeline_->IsInitialized()); | 411 EXPECT_TRUE(pipeline_->IsInitialized()); |
411 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
412 EXPECT_TRUE(pipeline_->HasAudio()); | 412 EXPECT_TRUE(pipeline_->HasAudio()); |
413 EXPECT_TRUE(pipeline_->HasVideo()); | 413 EXPECT_TRUE(pipeline_->HasVideo()); |
414 } | 414 } |
415 | 415 |
416 TEST_F(PipelineImplTest, Seek) { | 416 TEST_F(PipelineImplTest, Seek) { |
417 CreateAudioStream(); | 417 CreateAudioStream(); |
418 CreateVideoStream(); | 418 CreateVideoStream(); |
419 MockDemuxerStreamVector streams; | 419 MockDemuxerStreamVector streams; |
420 streams.push_back(audio_stream()); | 420 streams.push_back(audio_stream()); |
421 streams.push_back(video_stream()); | 421 streams.push_back(video_stream()); |
422 | 422 |
423 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000)); | 423 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000)); |
424 InitializeAudioDecoder(audio_stream()); | 424 InitializeAudioDecoder(audio_stream()); |
425 InitializeAudioRenderer(); | 425 InitializeAudioRenderer(); |
426 InitializeVideoDecoder(video_stream()); | 426 InitializeVideoDecoder(video_stream()); |
427 InitializeVideoRenderer(); | 427 InitializeVideoRenderer(); |
428 | 428 |
429 // Every filter should receive a call to Seek(). | 429 // Every filter should receive a call to Seek(). |
430 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); | 430 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); |
431 ExpectSeek(expected); | 431 ExpectSeek(expected); |
432 | 432 |
433 // Initialize then seek! | 433 // Initialize then seek! |
434 InitializePipeline(); | 434 InitializePipeline(PIPELINE_OK); |
435 DoSeek(expected); | 435 DoSeek(expected); |
436 } | 436 } |
437 | 437 |
438 TEST_F(PipelineImplTest, SetVolume) { | 438 TEST_F(PipelineImplTest, SetVolume) { |
439 CreateAudioStream(); | 439 CreateAudioStream(); |
440 MockDemuxerStreamVector streams; | 440 MockDemuxerStreamVector streams; |
441 streams.push_back(audio_stream()); | 441 streams.push_back(audio_stream()); |
442 | 442 |
443 InitializeDemuxer(&streams, base::TimeDelta()); | 443 InitializeDemuxer(&streams, base::TimeDelta()); |
444 InitializeAudioDecoder(audio_stream()); | 444 InitializeAudioDecoder(audio_stream()); |
445 InitializeAudioRenderer(); | 445 InitializeAudioRenderer(); |
446 | 446 |
447 // The audio renderer should receive a call to SetVolume(). | 447 // The audio renderer should receive a call to SetVolume(). |
448 float expected = 0.5f; | 448 float expected = 0.5f; |
449 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected)); | 449 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected)); |
450 | 450 |
451 // Initialize then set volume! | 451 // Initialize then set volume! |
452 InitializePipeline(); | 452 InitializePipeline(PIPELINE_OK); |
453 pipeline_->SetVolume(expected); | 453 pipeline_->SetVolume(expected); |
454 } | 454 } |
455 | 455 |
456 TEST_F(PipelineImplTest, Properties) { | 456 TEST_F(PipelineImplTest, Properties) { |
457 CreateVideoStream(); | 457 CreateVideoStream(); |
458 MockDemuxerStreamVector streams; | 458 MockDemuxerStreamVector streams; |
459 streams.push_back(video_stream()); | 459 streams.push_back(video_stream()); |
460 | 460 |
461 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); | 461 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
462 InitializeDemuxer(&streams, kDuration); | 462 InitializeDemuxer(&streams, kDuration); |
463 InitializeVideoDecoder(video_stream()); | 463 InitializeVideoDecoder(video_stream()); |
464 InitializeVideoRenderer(); | 464 InitializeVideoRenderer(); |
465 | 465 |
466 InitializePipeline(); | 466 InitializePipeline(PIPELINE_OK); |
467 EXPECT_TRUE(pipeline_->IsInitialized()); | 467 EXPECT_TRUE(pipeline_->IsInitialized()); |
468 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
469 EXPECT_EQ(kDuration.ToInternalValue(), | 468 EXPECT_EQ(kDuration.ToInternalValue(), |
470 pipeline_->GetMediaDuration().ToInternalValue()); | 469 pipeline_->GetMediaDuration().ToInternalValue()); |
471 EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes()); | 470 EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes()); |
472 EXPECT_EQ(kBufferedBytes, pipeline_->GetBufferedBytes()); | 471 EXPECT_EQ(kBufferedBytes, pipeline_->GetBufferedBytes()); |
473 | 472 |
474 // Because kTotalBytes and kBufferedBytes are equal to each other, | 473 // Because kTotalBytes and kBufferedBytes are equal to each other, |
475 // the entire video should be buffered. | 474 // the entire video should be buffered. |
476 EXPECT_EQ(kDuration.ToInternalValue(), | 475 EXPECT_EQ(kDuration.ToInternalValue(), |
477 pipeline_->GetBufferedTime().ToInternalValue()); | 476 pipeline_->GetBufferedTime().ToInternalValue()); |
478 } | 477 } |
479 | 478 |
480 TEST_F(PipelineImplTest, GetBufferedTime) { | 479 TEST_F(PipelineImplTest, GetBufferedTime) { |
481 CreateVideoStream(); | 480 CreateVideoStream(); |
482 MockDemuxerStreamVector streams; | 481 MockDemuxerStreamVector streams; |
483 streams.push_back(video_stream()); | 482 streams.push_back(video_stream()); |
484 | 483 |
485 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); | 484 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
486 InitializeDemuxer(&streams, kDuration); | 485 InitializeDemuxer(&streams, kDuration); |
487 InitializeVideoDecoder(video_stream()); | 486 InitializeVideoDecoder(video_stream()); |
488 InitializeVideoRenderer(); | 487 InitializeVideoRenderer(); |
489 | 488 |
490 InitializePipeline(); | 489 InitializePipeline(PIPELINE_OK); |
491 EXPECT_TRUE(pipeline_->IsInitialized()); | 490 EXPECT_TRUE(pipeline_->IsInitialized()); |
492 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
493 | 491 |
494 // TODO(vrk): The following mini-test cases are order-dependent, and should | 492 // TODO(vrk): The following mini-test cases are order-dependent, and should |
495 // probably be separated into independent test cases. | 493 // probably be separated into independent test cases. |
496 | 494 |
497 // Buffered time is 0 if no bytes are buffered. | 495 // Buffered time is 0 if no bytes are buffered. |
498 pipeline_->SetBufferedBytes(0); | 496 pipeline_->SetBufferedBytes(0); |
499 EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue()); | 497 EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue()); |
500 | 498 |
501 // We should return buffered_time_ if it is set, valid and less than | 499 // We should return buffered_time_ if it is set, valid and less than |
502 // the current time. | 500 // the current time. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 MockDemuxerStreamVector streams; | 548 MockDemuxerStreamVector streams; |
551 streams.push_back(audio_stream()); | 549 streams.push_back(audio_stream()); |
552 streams.push_back(video_stream()); | 550 streams.push_back(video_stream()); |
553 | 551 |
554 InitializeDemuxer(&streams, base::TimeDelta()); | 552 InitializeDemuxer(&streams, base::TimeDelta()); |
555 InitializeAudioDecoder(audio_stream()); | 553 InitializeAudioDecoder(audio_stream()); |
556 InitializeAudioRenderer(); | 554 InitializeAudioRenderer(); |
557 InitializeVideoDecoder(video_stream()); | 555 InitializeVideoDecoder(video_stream()); |
558 InitializeVideoRenderer(); | 556 InitializeVideoRenderer(); |
559 | 557 |
560 InitializePipeline(); | 558 InitializePipeline(PIPELINE_OK); |
561 EXPECT_TRUE(pipeline_->IsInitialized()); | 559 EXPECT_TRUE(pipeline_->IsInitialized()); |
562 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
563 EXPECT_TRUE(pipeline_->HasAudio()); | 560 EXPECT_TRUE(pipeline_->HasAudio()); |
564 EXPECT_TRUE(pipeline_->HasVideo()); | 561 EXPECT_TRUE(pipeline_->HasVideo()); |
565 | 562 |
566 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(1.0f)) | 563 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(1.0f)) |
567 .WillOnce(DisableAudioRenderer(mocks_->audio_renderer())); | 564 .WillOnce(DisableAudioRenderer(mocks_->audio_renderer())); |
568 EXPECT_CALL(*mocks_->demuxer(), | 565 EXPECT_CALL(*mocks_->demuxer(), |
569 OnAudioRendererDisabled()); | 566 OnAudioRendererDisabled()); |
570 EXPECT_CALL(*mocks_->audio_decoder(), | 567 EXPECT_CALL(*mocks_->audio_decoder(), |
571 OnAudioRendererDisabled()); | 568 OnAudioRendererDisabled()); |
572 EXPECT_CALL(*mocks_->audio_renderer(), | 569 EXPECT_CALL(*mocks_->audio_renderer(), |
573 OnAudioRendererDisabled()); | 570 OnAudioRendererDisabled()); |
574 EXPECT_CALL(*mocks_->video_decoder(), | 571 EXPECT_CALL(*mocks_->video_decoder(), |
575 OnAudioRendererDisabled()); | 572 OnAudioRendererDisabled()); |
576 EXPECT_CALL(*mocks_->video_renderer(), | 573 EXPECT_CALL(*mocks_->video_renderer(), |
577 OnAudioRendererDisabled()); | 574 OnAudioRendererDisabled()); |
578 | 575 |
579 mocks_->audio_renderer()->SetPlaybackRate(1.0f); | 576 mocks_->audio_renderer()->SetPlaybackRate(1.0f); |
580 | 577 |
581 // Verify that ended event is fired when video ends. | 578 // Verify that ended event is fired when video ends. |
582 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 579 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
583 .WillOnce(Return(true)); | 580 .WillOnce(Return(true)); |
584 EXPECT_CALL(callbacks_, OnEnded()); | 581 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
585 FilterHost* host = pipeline_; | 582 FilterHost* host = pipeline_; |
586 host->NotifyEnded(); | 583 host->NotifyEnded(); |
587 } | 584 } |
588 | 585 |
589 TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) { | 586 TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) { |
590 CreateAudioStream(); | 587 CreateAudioStream(); |
591 CreateVideoStream(); | 588 CreateVideoStream(); |
592 MockDemuxerStreamVector streams; | 589 MockDemuxerStreamVector streams; |
593 streams.push_back(audio_stream()); | 590 streams.push_back(audio_stream()); |
594 streams.push_back(video_stream()); | 591 streams.push_back(video_stream()); |
595 | 592 |
596 InitializeDemuxer(&streams, base::TimeDelta()); | 593 InitializeDemuxer(&streams, base::TimeDelta()); |
597 InitializeAudioDecoder(audio_stream()); | 594 InitializeAudioDecoder(audio_stream()); |
598 InitializeAudioRenderer(true); | 595 InitializeAudioRenderer(true); |
599 InitializeVideoDecoder(video_stream()); | 596 InitializeVideoDecoder(video_stream()); |
600 InitializeVideoRenderer(); | 597 InitializeVideoRenderer(); |
601 | 598 |
602 EXPECT_CALL(*mocks_->demuxer(), | 599 EXPECT_CALL(*mocks_->demuxer(), |
603 OnAudioRendererDisabled()); | 600 OnAudioRendererDisabled()); |
604 EXPECT_CALL(*mocks_->audio_decoder(), | 601 EXPECT_CALL(*mocks_->audio_decoder(), |
605 OnAudioRendererDisabled()); | 602 OnAudioRendererDisabled()); |
606 EXPECT_CALL(*mocks_->audio_renderer(), | 603 EXPECT_CALL(*mocks_->audio_renderer(), |
607 OnAudioRendererDisabled()); | 604 OnAudioRendererDisabled()); |
608 EXPECT_CALL(*mocks_->video_decoder(), | 605 EXPECT_CALL(*mocks_->video_decoder(), |
609 OnAudioRendererDisabled()); | 606 OnAudioRendererDisabled()); |
610 EXPECT_CALL(*mocks_->video_renderer(), | 607 EXPECT_CALL(*mocks_->video_renderer(), |
611 OnAudioRendererDisabled()); | 608 OnAudioRendererDisabled()); |
612 | 609 |
613 InitializePipeline(); | 610 InitializePipeline(PIPELINE_OK); |
614 EXPECT_TRUE(pipeline_->IsInitialized()); | 611 EXPECT_TRUE(pipeline_->IsInitialized()); |
615 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
616 EXPECT_FALSE(pipeline_->HasAudio()); | 612 EXPECT_FALSE(pipeline_->HasAudio()); |
617 EXPECT_TRUE(pipeline_->HasVideo()); | 613 EXPECT_TRUE(pipeline_->HasVideo()); |
618 | 614 |
619 // Verify that ended event is fired when video ends. | 615 // Verify that ended event is fired when video ends. |
620 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 616 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
621 .WillOnce(Return(true)); | 617 .WillOnce(Return(true)); |
622 EXPECT_CALL(callbacks_, OnEnded()); | 618 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
623 FilterHost* host = pipeline_; | 619 FilterHost* host = pipeline_; |
624 host->NotifyEnded(); | 620 host->NotifyEnded(); |
625 } | 621 } |
626 | 622 |
627 TEST_F(PipelineImplTest, EndedCallback) { | 623 TEST_F(PipelineImplTest, EndedCallback) { |
628 CreateAudioStream(); | 624 CreateAudioStream(); |
629 CreateVideoStream(); | 625 CreateVideoStream(); |
630 MockDemuxerStreamVector streams; | 626 MockDemuxerStreamVector streams; |
631 streams.push_back(audio_stream()); | 627 streams.push_back(audio_stream()); |
632 streams.push_back(video_stream()); | 628 streams.push_back(video_stream()); |
633 | 629 |
634 InitializeDemuxer(&streams, base::TimeDelta()); | 630 InitializeDemuxer(&streams, base::TimeDelta()); |
635 InitializeAudioDecoder(audio_stream()); | 631 InitializeAudioDecoder(audio_stream()); |
636 InitializeAudioRenderer(); | 632 InitializeAudioRenderer(); |
637 InitializeVideoDecoder(video_stream()); | 633 InitializeVideoDecoder(video_stream()); |
638 InitializeVideoRenderer(); | 634 InitializeVideoRenderer(); |
639 InitializePipeline(); | 635 InitializePipeline(PIPELINE_OK); |
640 | 636 |
641 // For convenience to simulate filters calling the methods. | 637 // For convenience to simulate filters calling the methods. |
642 FilterHost* host = pipeline_; | 638 FilterHost* host = pipeline_; |
643 | 639 |
644 // Due to short circuit evaluation we only need to test a subset of cases. | 640 // Due to short circuit evaluation we only need to test a subset of cases. |
645 InSequence s; | 641 InSequence s; |
646 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 642 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
647 .WillOnce(Return(false)); | 643 .WillOnce(Return(false)); |
648 host->NotifyEnded(); | 644 host->NotifyEnded(); |
649 | 645 |
650 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 646 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
651 .WillOnce(Return(true)); | 647 .WillOnce(Return(true)); |
652 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 648 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
653 .WillOnce(Return(false)); | 649 .WillOnce(Return(false)); |
654 host->NotifyEnded(); | 650 host->NotifyEnded(); |
655 | 651 |
656 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 652 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
657 .WillOnce(Return(true)); | 653 .WillOnce(Return(true)); |
658 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 654 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
659 .WillOnce(Return(true)); | 655 .WillOnce(Return(true)); |
660 EXPECT_CALL(callbacks_, OnEnded()); | 656 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
661 host->NotifyEnded(); | 657 host->NotifyEnded(); |
662 } | 658 } |
663 | 659 |
664 // Static function & time variable used to simulate changes in wallclock time. | 660 // Static function & time variable used to simulate changes in wallclock time. |
665 static int64 g_static_clock_time; | 661 static int64 g_static_clock_time; |
666 static base::Time StaticClockFunction() { | 662 static base::Time StaticClockFunction() { |
667 return base::Time::FromInternalValue(g_static_clock_time); | 663 return base::Time::FromInternalValue(g_static_clock_time); |
668 } | 664 } |
669 | 665 |
670 TEST_F(PipelineImplTest, AudioStreamShorterThanVideo) { | 666 TEST_F(PipelineImplTest, AudioStreamShorterThanVideo) { |
671 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); | 667 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); |
672 | 668 |
673 CreateAudioStream(); | 669 CreateAudioStream(); |
674 CreateVideoStream(); | 670 CreateVideoStream(); |
675 MockDemuxerStreamVector streams; | 671 MockDemuxerStreamVector streams; |
676 streams.push_back(audio_stream()); | 672 streams.push_back(audio_stream()); |
677 streams.push_back(video_stream()); | 673 streams.push_back(video_stream()); |
678 | 674 |
679 InitializeDemuxer(&streams, duration); | 675 InitializeDemuxer(&streams, duration); |
680 InitializeAudioDecoder(audio_stream()); | 676 InitializeAudioDecoder(audio_stream()); |
681 InitializeAudioRenderer(); | 677 InitializeAudioRenderer(); |
682 InitializeVideoDecoder(video_stream()); | 678 InitializeVideoDecoder(video_stream()); |
683 InitializeVideoRenderer(); | 679 InitializeVideoRenderer(); |
684 InitializePipeline(); | 680 InitializePipeline(PIPELINE_OK); |
685 | 681 |
686 // For convenience to simulate filters calling the methods. | 682 // For convenience to simulate filters calling the methods. |
687 FilterHost* host = pipeline_; | 683 FilterHost* host = pipeline_; |
688 | 684 |
689 // Replace the clock so we can simulate wallclock time advancing w/o using | 685 // Replace the clock so we can simulate wallclock time advancing w/o using |
690 // Sleep(). | 686 // Sleep(). |
691 pipeline_->SetClockForTesting(new Clock(&StaticClockFunction)); | 687 pipeline_->SetClockForTesting(new Clock(&StaticClockFunction)); |
692 | 688 |
693 EXPECT_EQ(0, host->GetTime().ToInternalValue()); | 689 EXPECT_EQ(0, host->GetTime().ToInternalValue()); |
694 | 690 |
(...skipping 27 matching lines...) Expand all Loading... |
722 start_time = host->GetTime().ToInternalValue(); | 718 start_time = host->GetTime().ToInternalValue(); |
723 g_static_clock_time += | 719 g_static_clock_time += |
724 base::TimeDelta::FromMilliseconds(100).ToInternalValue(); | 720 base::TimeDelta::FromMilliseconds(100).ToInternalValue(); |
725 EXPECT_GT(host->GetTime().ToInternalValue(), start_time); | 721 EXPECT_GT(host->GetTime().ToInternalValue(), start_time); |
726 | 722 |
727 // Signal end of video stream and make sure OnEnded() callback occurs. | 723 // Signal end of video stream and make sure OnEnded() callback occurs. |
728 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 724 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
729 .WillOnce(Return(true)); | 725 .WillOnce(Return(true)); |
730 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 726 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
731 .WillOnce(Return(true)); | 727 .WillOnce(Return(true)); |
732 EXPECT_CALL(callbacks_, OnEnded()); | 728 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
733 host->NotifyEnded(); | 729 host->NotifyEnded(); |
734 } | 730 } |
735 | 731 |
736 TEST_F(PipelineImplTest, ErrorDuringSeek) { | 732 TEST_F(PipelineImplTest, ErrorDuringSeek) { |
737 CreateAudioStream(); | 733 CreateAudioStream(); |
738 MockDemuxerStreamVector streams; | 734 MockDemuxerStreamVector streams; |
739 streams.push_back(audio_stream()); | 735 streams.push_back(audio_stream()); |
740 | 736 |
741 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(10)); | 737 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(10)); |
742 InitializeAudioDecoder(audio_stream()); | 738 InitializeAudioDecoder(audio_stream()); |
743 InitializeAudioRenderer(); | 739 InitializeAudioRenderer(); |
744 InitializePipeline(); | 740 InitializePipeline(PIPELINE_OK); |
745 | 741 |
746 float playback_rate = 1.0f; | 742 float playback_rate = 1.0f; |
747 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate)); | 743 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate)); |
748 EXPECT_CALL(*mocks_->audio_decoder(), SetPlaybackRate(playback_rate)); | 744 EXPECT_CALL(*mocks_->audio_decoder(), SetPlaybackRate(playback_rate)); |
749 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate)); | 745 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate)); |
750 pipeline_->SetPlaybackRate(playback_rate); | 746 pipeline_->SetPlaybackRate(playback_rate); |
751 message_loop_.RunAllPending(); | 747 message_loop_.RunAllPending(); |
752 | 748 |
753 InSequence s; | 749 InSequence s; |
754 | 750 |
755 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 751 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
756 | 752 |
757 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, NotNull())) | 753 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, NotNull())) |
758 .WillOnce(DoAll(SetError(mocks_->demuxer(), | 754 .WillOnce(DoAll(SetError(mocks_->demuxer(), |
759 PIPELINE_ERROR_READ), | 755 PIPELINE_ERROR_READ), |
760 Invoke(&RunFilterCallback))); | 756 Invoke(&RunFilterCallback))); |
761 | 757 |
762 pipeline_->Seek(seek_time, NewExpectedCallback()); | 758 pipeline_->Seek(seek_time, NewCallback( |
763 EXPECT_CALL(callbacks_, OnError()); | 759 reinterpret_cast<CallbackHelper*>(&callbacks_), &CallbackHelper::OnSeek)); |
| 760 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 761 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); |
764 message_loop_.RunAllPending(); | 762 message_loop_.RunAllPending(); |
765 } | 763 } |
766 | 764 |
| 765 class FlexibleCallbackRunner : public base::DelegateSimpleThread::Delegate { |
| 766 public: |
| 767 FlexibleCallbackRunner(int delayInMs, PipelineStatus status, |
| 768 PipelineStatusCallback* callback) |
| 769 : delayInMs_(delayInMs), status_(status), callback_(callback) { |
| 770 if (delayInMs_ < 0) { |
| 771 callback_->Run(status_); |
| 772 return; |
| 773 } |
| 774 } |
| 775 virtual void Run() { |
| 776 if (delayInMs_ < 0) return; |
| 777 base::PlatformThread::Sleep(delayInMs_); |
| 778 callback_->Run(status_); |
| 779 } |
| 780 |
| 781 private: |
| 782 int delayInMs_; |
| 783 PipelineStatus status_; |
| 784 PipelineStatusCallback* callback_; |
| 785 }; |
| 786 |
| 787 void TestPipelineStatusNotification(int delayInMs) { |
| 788 PipelineStatusNotification note; |
| 789 // Arbitrary error value we expect to fish out of the notification after the |
| 790 // callback is fired. |
| 791 const PipelineStatus expected_error = PIPELINE_ERROR_URL_NOT_FOUND; |
| 792 FlexibleCallbackRunner runner(delayInMs, expected_error, note.Callback()); |
| 793 base::DelegateSimpleThread thread(&runner, "FlexibleCallbackRunner"); |
| 794 thread.Start(); |
| 795 note.Wait(); |
| 796 EXPECT_EQ(note.status(), expected_error); |
| 797 thread.Join(); |
| 798 } |
| 799 |
| 800 // Test that in-line callback (same thread, no yield) works correctly. |
| 801 TEST(PipelineStatusNotificationTest, InlineCallback) { |
| 802 TestPipelineStatusNotification(-1); |
| 803 } |
| 804 |
| 805 // Test that different-thread, no-delay callback works correctly. |
| 806 TEST(PipelineStatusNotificationTest, ImmediateCallback) { |
| 807 TestPipelineStatusNotification(0); |
| 808 } |
| 809 |
| 810 // Test that different-thread, some-delay callback (the expected common case) |
| 811 // works correctly. |
| 812 TEST(PipelineStatusNotificationTest, DelayedCallback) { |
| 813 TestPipelineStatusNotification(20); |
| 814 } |
| 815 |
767 } // namespace media | 816 } // namespace media |
OLD | NEW |