Chromium Code Reviews| 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 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_URL_NOT_FOUND)); |
|
acolwell GONE FROM CHROMIUM
2011/03/15 23:43:55
This doesn't smell right. I wouldn't expect an OnE
Ami GONE FROM CHROMIUM
2011/03/16 00:01:02
Done.
| |
| 343 EXPECT_CALL(callbacks_, OnError()); | |
| 344 | |
| 345 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND); | 344 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND); |
| 346 EXPECT_FALSE(pipeline_->IsInitialized()); | 345 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 347 EXPECT_EQ(PIPELINE_ERROR_URL_NOT_FOUND, pipeline_->GetError()); | |
| 348 } | 346 } |
| 349 | 347 |
| 350 TEST_F(PipelineImplTest, NoStreams) { | 348 TEST_F(PipelineImplTest, NoStreams) { |
| 351 // Manually set these expectations because SetPlaybackRate() is not called if | 349 // Manually set these expectations because SetPlaybackRate() is not called if |
| 352 // we cannot fully initialize the pipeline. | 350 // we cannot fully initialize the pipeline. |
| 353 EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams()) | 351 EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams()) |
| 354 .WillRepeatedly(Return(0)); | 352 .WillRepeatedly(Return(0)); |
| 355 EXPECT_CALL(*mocks_->demuxer(), Stop(NotNull())) | 353 EXPECT_CALL(*mocks_->demuxer(), Stop(NotNull())) |
| 356 .WillOnce(Invoke(&RunStopFilterCallback)); | 354 .WillOnce(Invoke(&RunStopFilterCallback)); |
| 357 EXPECT_CALL(callbacks_, OnError()); | 355 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_COULD_NOT_RENDER)); |
|
acolwell GONE FROM CHROMIUM
2011/03/15 23:43:55
This doesn't smell right. I wouldn't expect an OnE
Ami GONE FROM CHROMIUM
2011/03/16 00:01:02
Done.
| |
| 358 | 356 |
| 359 InitializePipeline(); | 357 InitializePipeline(PIPELINE_OK, PIPELINE_ERROR_COULD_NOT_RENDER); |
| 360 EXPECT_FALSE(pipeline_->IsInitialized()); | 358 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 361 EXPECT_EQ(PIPELINE_ERROR_COULD_NOT_RENDER, pipeline_->GetError()); | |
| 362 } | 359 } |
| 363 | 360 |
| 364 TEST_F(PipelineImplTest, AudioStream) { | 361 TEST_F(PipelineImplTest, AudioStream) { |
| 365 CreateAudioStream(); | 362 CreateAudioStream(); |
| 366 MockDemuxerStreamVector streams; | 363 MockDemuxerStreamVector streams; |
| 367 streams.push_back(audio_stream()); | 364 streams.push_back(audio_stream()); |
| 368 | 365 |
| 369 InitializeDemuxer(&streams, base::TimeDelta()); | 366 InitializeDemuxer(&streams, base::TimeDelta()); |
| 370 InitializeAudioDecoder(audio_stream()); | 367 InitializeAudioDecoder(audio_stream()); |
| 371 InitializeAudioRenderer(); | 368 InitializeAudioRenderer(); |
| 372 | 369 |
| 373 InitializePipeline(); | 370 InitializePipeline(PIPELINE_OK); |
| 374 EXPECT_TRUE(pipeline_->IsInitialized()); | 371 EXPECT_TRUE(pipeline_->IsInitialized()); |
| 375 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
| 376 EXPECT_TRUE(pipeline_->HasAudio()); | 372 EXPECT_TRUE(pipeline_->HasAudio()); |
| 377 EXPECT_FALSE(pipeline_->HasVideo()); | 373 EXPECT_FALSE(pipeline_->HasVideo()); |
| 378 } | 374 } |
| 379 | 375 |
| 380 TEST_F(PipelineImplTest, VideoStream) { | 376 TEST_F(PipelineImplTest, VideoStream) { |
| 381 CreateVideoStream(); | 377 CreateVideoStream(); |
| 382 MockDemuxerStreamVector streams; | 378 MockDemuxerStreamVector streams; |
| 383 streams.push_back(video_stream()); | 379 streams.push_back(video_stream()); |
| 384 | 380 |
| 385 InitializeDemuxer(&streams, base::TimeDelta()); | 381 InitializeDemuxer(&streams, base::TimeDelta()); |
| 386 InitializeVideoDecoder(video_stream()); | 382 InitializeVideoDecoder(video_stream()); |
| 387 InitializeVideoRenderer(); | 383 InitializeVideoRenderer(); |
| 388 | 384 |
| 389 InitializePipeline(); | 385 InitializePipeline(PIPELINE_OK); |
| 390 EXPECT_TRUE(pipeline_->IsInitialized()); | 386 EXPECT_TRUE(pipeline_->IsInitialized()); |
| 391 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
| 392 EXPECT_FALSE(pipeline_->HasAudio()); | 387 EXPECT_FALSE(pipeline_->HasAudio()); |
| 393 EXPECT_TRUE(pipeline_->HasVideo()); | 388 EXPECT_TRUE(pipeline_->HasVideo()); |
| 394 } | 389 } |
| 395 | 390 |
| 396 TEST_F(PipelineImplTest, AudioVideoStream) { | 391 TEST_F(PipelineImplTest, AudioVideoStream) { |
| 397 CreateAudioStream(); | 392 CreateAudioStream(); |
| 398 CreateVideoStream(); | 393 CreateVideoStream(); |
| 399 MockDemuxerStreamVector streams; | 394 MockDemuxerStreamVector streams; |
| 400 streams.push_back(audio_stream()); | 395 streams.push_back(audio_stream()); |
| 401 streams.push_back(video_stream()); | 396 streams.push_back(video_stream()); |
| 402 | 397 |
| 403 InitializeDemuxer(&streams, base::TimeDelta()); | 398 InitializeDemuxer(&streams, base::TimeDelta()); |
| 404 InitializeAudioDecoder(audio_stream()); | 399 InitializeAudioDecoder(audio_stream()); |
| 405 InitializeAudioRenderer(); | 400 InitializeAudioRenderer(); |
| 406 InitializeVideoDecoder(video_stream()); | 401 InitializeVideoDecoder(video_stream()); |
| 407 InitializeVideoRenderer(); | 402 InitializeVideoRenderer(); |
| 408 | 403 |
| 409 InitializePipeline(); | 404 InitializePipeline(PIPELINE_OK); |
| 410 EXPECT_TRUE(pipeline_->IsInitialized()); | 405 EXPECT_TRUE(pipeline_->IsInitialized()); |
| 411 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
| 412 EXPECT_TRUE(pipeline_->HasAudio()); | 406 EXPECT_TRUE(pipeline_->HasAudio()); |
| 413 EXPECT_TRUE(pipeline_->HasVideo()); | 407 EXPECT_TRUE(pipeline_->HasVideo()); |
| 414 } | 408 } |
| 415 | 409 |
| 416 TEST_F(PipelineImplTest, Seek) { | 410 TEST_F(PipelineImplTest, Seek) { |
| 417 CreateAudioStream(); | 411 CreateAudioStream(); |
| 418 CreateVideoStream(); | 412 CreateVideoStream(); |
| 419 MockDemuxerStreamVector streams; | 413 MockDemuxerStreamVector streams; |
| 420 streams.push_back(audio_stream()); | 414 streams.push_back(audio_stream()); |
| 421 streams.push_back(video_stream()); | 415 streams.push_back(video_stream()); |
| 422 | 416 |
| 423 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000)); | 417 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000)); |
| 424 InitializeAudioDecoder(audio_stream()); | 418 InitializeAudioDecoder(audio_stream()); |
| 425 InitializeAudioRenderer(); | 419 InitializeAudioRenderer(); |
| 426 InitializeVideoDecoder(video_stream()); | 420 InitializeVideoDecoder(video_stream()); |
| 427 InitializeVideoRenderer(); | 421 InitializeVideoRenderer(); |
| 428 | 422 |
| 429 // Every filter should receive a call to Seek(). | 423 // Every filter should receive a call to Seek(). |
| 430 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); | 424 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); |
| 431 ExpectSeek(expected); | 425 ExpectSeek(expected); |
| 432 | 426 |
| 433 // Initialize then seek! | 427 // Initialize then seek! |
| 434 InitializePipeline(); | 428 InitializePipeline(PIPELINE_OK); |
| 435 DoSeek(expected); | 429 DoSeek(expected); |
| 436 } | 430 } |
| 437 | 431 |
| 438 TEST_F(PipelineImplTest, SetVolume) { | 432 TEST_F(PipelineImplTest, SetVolume) { |
| 439 CreateAudioStream(); | 433 CreateAudioStream(); |
| 440 MockDemuxerStreamVector streams; | 434 MockDemuxerStreamVector streams; |
| 441 streams.push_back(audio_stream()); | 435 streams.push_back(audio_stream()); |
| 442 | 436 |
| 443 InitializeDemuxer(&streams, base::TimeDelta()); | 437 InitializeDemuxer(&streams, base::TimeDelta()); |
| 444 InitializeAudioDecoder(audio_stream()); | 438 InitializeAudioDecoder(audio_stream()); |
| 445 InitializeAudioRenderer(); | 439 InitializeAudioRenderer(); |
| 446 | 440 |
| 447 // The audio renderer should receive a call to SetVolume(). | 441 // The audio renderer should receive a call to SetVolume(). |
| 448 float expected = 0.5f; | 442 float expected = 0.5f; |
| 449 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected)); | 443 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected)); |
| 450 | 444 |
| 451 // Initialize then set volume! | 445 // Initialize then set volume! |
| 452 InitializePipeline(); | 446 InitializePipeline(PIPELINE_OK); |
| 453 pipeline_->SetVolume(expected); | 447 pipeline_->SetVolume(expected); |
| 454 } | 448 } |
| 455 | 449 |
| 456 TEST_F(PipelineImplTest, Properties) { | 450 TEST_F(PipelineImplTest, Properties) { |
| 457 CreateVideoStream(); | 451 CreateVideoStream(); |
| 458 MockDemuxerStreamVector streams; | 452 MockDemuxerStreamVector streams; |
| 459 streams.push_back(video_stream()); | 453 streams.push_back(video_stream()); |
| 460 | 454 |
| 461 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); | 455 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
| 462 InitializeDemuxer(&streams, kDuration); | 456 InitializeDemuxer(&streams, kDuration); |
| 463 InitializeVideoDecoder(video_stream()); | 457 InitializeVideoDecoder(video_stream()); |
| 464 InitializeVideoRenderer(); | 458 InitializeVideoRenderer(); |
| 465 | 459 |
| 466 InitializePipeline(); | 460 InitializePipeline(PIPELINE_OK); |
| 467 EXPECT_TRUE(pipeline_->IsInitialized()); | 461 EXPECT_TRUE(pipeline_->IsInitialized()); |
| 468 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
| 469 EXPECT_EQ(kDuration.ToInternalValue(), | 462 EXPECT_EQ(kDuration.ToInternalValue(), |
| 470 pipeline_->GetMediaDuration().ToInternalValue()); | 463 pipeline_->GetMediaDuration().ToInternalValue()); |
| 471 EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes()); | 464 EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes()); |
| 472 EXPECT_EQ(kBufferedBytes, pipeline_->GetBufferedBytes()); | 465 EXPECT_EQ(kBufferedBytes, pipeline_->GetBufferedBytes()); |
| 473 | 466 |
| 474 // Because kTotalBytes and kBufferedBytes are equal to each other, | 467 // Because kTotalBytes and kBufferedBytes are equal to each other, |
| 475 // the entire video should be buffered. | 468 // the entire video should be buffered. |
| 476 EXPECT_EQ(kDuration.ToInternalValue(), | 469 EXPECT_EQ(kDuration.ToInternalValue(), |
| 477 pipeline_->GetBufferedTime().ToInternalValue()); | 470 pipeline_->GetBufferedTime().ToInternalValue()); |
| 478 } | 471 } |
| 479 | 472 |
| 480 TEST_F(PipelineImplTest, GetBufferedTime) { | 473 TEST_F(PipelineImplTest, GetBufferedTime) { |
| 481 CreateVideoStream(); | 474 CreateVideoStream(); |
| 482 MockDemuxerStreamVector streams; | 475 MockDemuxerStreamVector streams; |
| 483 streams.push_back(video_stream()); | 476 streams.push_back(video_stream()); |
| 484 | 477 |
| 485 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); | 478 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
| 486 InitializeDemuxer(&streams, kDuration); | 479 InitializeDemuxer(&streams, kDuration); |
| 487 InitializeVideoDecoder(video_stream()); | 480 InitializeVideoDecoder(video_stream()); |
| 488 InitializeVideoRenderer(); | 481 InitializeVideoRenderer(); |
| 489 | 482 |
| 490 InitializePipeline(); | 483 InitializePipeline(PIPELINE_OK); |
| 491 EXPECT_TRUE(pipeline_->IsInitialized()); | 484 EXPECT_TRUE(pipeline_->IsInitialized()); |
| 492 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
| 493 | 485 |
| 494 // TODO(vrk): The following mini-test cases are order-dependent, and should | 486 // TODO(vrk): The following mini-test cases are order-dependent, and should |
| 495 // probably be separated into independent test cases. | 487 // probably be separated into independent test cases. |
| 496 | 488 |
| 497 // Buffered time is 0 if no bytes are buffered. | 489 // Buffered time is 0 if no bytes are buffered. |
| 498 pipeline_->SetBufferedBytes(0); | 490 pipeline_->SetBufferedBytes(0); |
| 499 EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue()); | 491 EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue()); |
| 500 | 492 |
| 501 // We should return buffered_time_ if it is set, valid and less than | 493 // We should return buffered_time_ if it is set, valid and less than |
| 502 // the current time. | 494 // the current time. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 MockDemuxerStreamVector streams; | 542 MockDemuxerStreamVector streams; |
| 551 streams.push_back(audio_stream()); | 543 streams.push_back(audio_stream()); |
| 552 streams.push_back(video_stream()); | 544 streams.push_back(video_stream()); |
| 553 | 545 |
| 554 InitializeDemuxer(&streams, base::TimeDelta()); | 546 InitializeDemuxer(&streams, base::TimeDelta()); |
| 555 InitializeAudioDecoder(audio_stream()); | 547 InitializeAudioDecoder(audio_stream()); |
| 556 InitializeAudioRenderer(); | 548 InitializeAudioRenderer(); |
| 557 InitializeVideoDecoder(video_stream()); | 549 InitializeVideoDecoder(video_stream()); |
| 558 InitializeVideoRenderer(); | 550 InitializeVideoRenderer(); |
| 559 | 551 |
| 560 InitializePipeline(); | 552 InitializePipeline(PIPELINE_OK); |
| 561 EXPECT_TRUE(pipeline_->IsInitialized()); | 553 EXPECT_TRUE(pipeline_->IsInitialized()); |
| 562 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
| 563 EXPECT_TRUE(pipeline_->HasAudio()); | 554 EXPECT_TRUE(pipeline_->HasAudio()); |
| 564 EXPECT_TRUE(pipeline_->HasVideo()); | 555 EXPECT_TRUE(pipeline_->HasVideo()); |
| 565 | 556 |
| 566 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(1.0f)) | 557 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(1.0f)) |
| 567 .WillOnce(DisableAudioRenderer(mocks_->audio_renderer())); | 558 .WillOnce(DisableAudioRenderer(mocks_->audio_renderer())); |
| 568 EXPECT_CALL(*mocks_->demuxer(), | 559 EXPECT_CALL(*mocks_->demuxer(), |
| 569 OnAudioRendererDisabled()); | 560 OnAudioRendererDisabled()); |
| 570 EXPECT_CALL(*mocks_->audio_decoder(), | 561 EXPECT_CALL(*mocks_->audio_decoder(), |
| 571 OnAudioRendererDisabled()); | 562 OnAudioRendererDisabled()); |
| 572 EXPECT_CALL(*mocks_->audio_renderer(), | 563 EXPECT_CALL(*mocks_->audio_renderer(), |
| 573 OnAudioRendererDisabled()); | 564 OnAudioRendererDisabled()); |
| 574 EXPECT_CALL(*mocks_->video_decoder(), | 565 EXPECT_CALL(*mocks_->video_decoder(), |
| 575 OnAudioRendererDisabled()); | 566 OnAudioRendererDisabled()); |
| 576 EXPECT_CALL(*mocks_->video_renderer(), | 567 EXPECT_CALL(*mocks_->video_renderer(), |
| 577 OnAudioRendererDisabled()); | 568 OnAudioRendererDisabled()); |
| 578 | 569 |
| 579 mocks_->audio_renderer()->SetPlaybackRate(1.0f); | 570 mocks_->audio_renderer()->SetPlaybackRate(1.0f); |
| 580 | 571 |
| 581 // Verify that ended event is fired when video ends. | 572 // Verify that ended event is fired when video ends. |
| 582 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 573 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
| 583 .WillOnce(Return(true)); | 574 .WillOnce(Return(true)); |
| 584 EXPECT_CALL(callbacks_, OnEnded()); | 575 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
| 585 FilterHost* host = pipeline_; | 576 FilterHost* host = pipeline_; |
| 586 host->NotifyEnded(); | 577 host->NotifyEnded(); |
| 587 } | 578 } |
| 588 | 579 |
| 589 TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) { | 580 TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) { |
| 590 CreateAudioStream(); | 581 CreateAudioStream(); |
| 591 CreateVideoStream(); | 582 CreateVideoStream(); |
| 592 MockDemuxerStreamVector streams; | 583 MockDemuxerStreamVector streams; |
| 593 streams.push_back(audio_stream()); | 584 streams.push_back(audio_stream()); |
| 594 streams.push_back(video_stream()); | 585 streams.push_back(video_stream()); |
| 595 | 586 |
| 596 InitializeDemuxer(&streams, base::TimeDelta()); | 587 InitializeDemuxer(&streams, base::TimeDelta()); |
| 597 InitializeAudioDecoder(audio_stream()); | 588 InitializeAudioDecoder(audio_stream()); |
| 598 InitializeAudioRenderer(true); | 589 InitializeAudioRenderer(true); |
| 599 InitializeVideoDecoder(video_stream()); | 590 InitializeVideoDecoder(video_stream()); |
| 600 InitializeVideoRenderer(); | 591 InitializeVideoRenderer(); |
| 601 | 592 |
| 602 EXPECT_CALL(*mocks_->demuxer(), | 593 EXPECT_CALL(*mocks_->demuxer(), |
| 603 OnAudioRendererDisabled()); | 594 OnAudioRendererDisabled()); |
| 604 EXPECT_CALL(*mocks_->audio_decoder(), | 595 EXPECT_CALL(*mocks_->audio_decoder(), |
| 605 OnAudioRendererDisabled()); | 596 OnAudioRendererDisabled()); |
| 606 EXPECT_CALL(*mocks_->audio_renderer(), | 597 EXPECT_CALL(*mocks_->audio_renderer(), |
| 607 OnAudioRendererDisabled()); | 598 OnAudioRendererDisabled()); |
| 608 EXPECT_CALL(*mocks_->video_decoder(), | 599 EXPECT_CALL(*mocks_->video_decoder(), |
| 609 OnAudioRendererDisabled()); | 600 OnAudioRendererDisabled()); |
| 610 EXPECT_CALL(*mocks_->video_renderer(), | 601 EXPECT_CALL(*mocks_->video_renderer(), |
| 611 OnAudioRendererDisabled()); | 602 OnAudioRendererDisabled()); |
| 612 | 603 |
| 613 InitializePipeline(); | 604 InitializePipeline(PIPELINE_OK); |
| 614 EXPECT_TRUE(pipeline_->IsInitialized()); | 605 EXPECT_TRUE(pipeline_->IsInitialized()); |
| 615 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError()); | |
| 616 EXPECT_FALSE(pipeline_->HasAudio()); | 606 EXPECT_FALSE(pipeline_->HasAudio()); |
| 617 EXPECT_TRUE(pipeline_->HasVideo()); | 607 EXPECT_TRUE(pipeline_->HasVideo()); |
| 618 | 608 |
| 619 // Verify that ended event is fired when video ends. | 609 // Verify that ended event is fired when video ends. |
| 620 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 610 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
| 621 .WillOnce(Return(true)); | 611 .WillOnce(Return(true)); |
| 622 EXPECT_CALL(callbacks_, OnEnded()); | 612 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
| 623 FilterHost* host = pipeline_; | 613 FilterHost* host = pipeline_; |
| 624 host->NotifyEnded(); | 614 host->NotifyEnded(); |
| 625 } | 615 } |
| 626 | 616 |
| 627 TEST_F(PipelineImplTest, EndedCallback) { | 617 TEST_F(PipelineImplTest, EndedCallback) { |
| 628 CreateAudioStream(); | 618 CreateAudioStream(); |
| 629 CreateVideoStream(); | 619 CreateVideoStream(); |
| 630 MockDemuxerStreamVector streams; | 620 MockDemuxerStreamVector streams; |
| 631 streams.push_back(audio_stream()); | 621 streams.push_back(audio_stream()); |
| 632 streams.push_back(video_stream()); | 622 streams.push_back(video_stream()); |
| 633 | 623 |
| 634 InitializeDemuxer(&streams, base::TimeDelta()); | 624 InitializeDemuxer(&streams, base::TimeDelta()); |
| 635 InitializeAudioDecoder(audio_stream()); | 625 InitializeAudioDecoder(audio_stream()); |
| 636 InitializeAudioRenderer(); | 626 InitializeAudioRenderer(); |
| 637 InitializeVideoDecoder(video_stream()); | 627 InitializeVideoDecoder(video_stream()); |
| 638 InitializeVideoRenderer(); | 628 InitializeVideoRenderer(); |
| 639 InitializePipeline(); | 629 InitializePipeline(PIPELINE_OK); |
| 640 | 630 |
| 641 // For convenience to simulate filters calling the methods. | 631 // For convenience to simulate filters calling the methods. |
| 642 FilterHost* host = pipeline_; | 632 FilterHost* host = pipeline_; |
| 643 | 633 |
| 644 // Due to short circuit evaluation we only need to test a subset of cases. | 634 // Due to short circuit evaluation we only need to test a subset of cases. |
| 645 InSequence s; | 635 InSequence s; |
| 646 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 636 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
| 647 .WillOnce(Return(false)); | 637 .WillOnce(Return(false)); |
| 648 host->NotifyEnded(); | 638 host->NotifyEnded(); |
| 649 | 639 |
| 650 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 640 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
| 651 .WillOnce(Return(true)); | 641 .WillOnce(Return(true)); |
| 652 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 642 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
| 653 .WillOnce(Return(false)); | 643 .WillOnce(Return(false)); |
| 654 host->NotifyEnded(); | 644 host->NotifyEnded(); |
| 655 | 645 |
| 656 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 646 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
| 657 .WillOnce(Return(true)); | 647 .WillOnce(Return(true)); |
| 658 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 648 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
| 659 .WillOnce(Return(true)); | 649 .WillOnce(Return(true)); |
| 660 EXPECT_CALL(callbacks_, OnEnded()); | 650 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
| 661 host->NotifyEnded(); | 651 host->NotifyEnded(); |
| 662 } | 652 } |
| 663 | 653 |
| 664 // Static function & time variable used to simulate changes in wallclock time. | 654 // Static function & time variable used to simulate changes in wallclock time. |
| 665 static int64 g_static_clock_time; | 655 static int64 g_static_clock_time; |
| 666 static base::Time StaticClockFunction() { | 656 static base::Time StaticClockFunction() { |
| 667 return base::Time::FromInternalValue(g_static_clock_time); | 657 return base::Time::FromInternalValue(g_static_clock_time); |
| 668 } | 658 } |
| 669 | 659 |
| 670 TEST_F(PipelineImplTest, AudioStreamShorterThanVideo) { | 660 TEST_F(PipelineImplTest, AudioStreamShorterThanVideo) { |
| 671 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); | 661 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); |
| 672 | 662 |
| 673 CreateAudioStream(); | 663 CreateAudioStream(); |
| 674 CreateVideoStream(); | 664 CreateVideoStream(); |
| 675 MockDemuxerStreamVector streams; | 665 MockDemuxerStreamVector streams; |
| 676 streams.push_back(audio_stream()); | 666 streams.push_back(audio_stream()); |
| 677 streams.push_back(video_stream()); | 667 streams.push_back(video_stream()); |
| 678 | 668 |
| 679 InitializeDemuxer(&streams, duration); | 669 InitializeDemuxer(&streams, duration); |
| 680 InitializeAudioDecoder(audio_stream()); | 670 InitializeAudioDecoder(audio_stream()); |
| 681 InitializeAudioRenderer(); | 671 InitializeAudioRenderer(); |
| 682 InitializeVideoDecoder(video_stream()); | 672 InitializeVideoDecoder(video_stream()); |
| 683 InitializeVideoRenderer(); | 673 InitializeVideoRenderer(); |
| 684 InitializePipeline(); | 674 InitializePipeline(PIPELINE_OK); |
| 685 | 675 |
| 686 // For convenience to simulate filters calling the methods. | 676 // For convenience to simulate filters calling the methods. |
| 687 FilterHost* host = pipeline_; | 677 FilterHost* host = pipeline_; |
| 688 | 678 |
| 689 // Replace the clock so we can simulate wallclock time advancing w/o using | 679 // Replace the clock so we can simulate wallclock time advancing w/o using |
| 690 // Sleep(). | 680 // Sleep(). |
| 691 pipeline_->SetClockForTesting(new Clock(&StaticClockFunction)); | 681 pipeline_->SetClockForTesting(new Clock(&StaticClockFunction)); |
| 692 | 682 |
| 693 EXPECT_EQ(0, host->GetTime().ToInternalValue()); | 683 EXPECT_EQ(0, host->GetTime().ToInternalValue()); |
| 694 | 684 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 722 start_time = host->GetTime().ToInternalValue(); | 712 start_time = host->GetTime().ToInternalValue(); |
| 723 g_static_clock_time += | 713 g_static_clock_time += |
| 724 base::TimeDelta::FromMilliseconds(100).ToInternalValue(); | 714 base::TimeDelta::FromMilliseconds(100).ToInternalValue(); |
| 725 EXPECT_GT(host->GetTime().ToInternalValue(), start_time); | 715 EXPECT_GT(host->GetTime().ToInternalValue(), start_time); |
| 726 | 716 |
| 727 // Signal end of video stream and make sure OnEnded() callback occurs. | 717 // Signal end of video stream and make sure OnEnded() callback occurs. |
| 728 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) | 718 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) |
| 729 .WillOnce(Return(true)); | 719 .WillOnce(Return(true)); |
| 730 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) | 720 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) |
| 731 .WillOnce(Return(true)); | 721 .WillOnce(Return(true)); |
| 732 EXPECT_CALL(callbacks_, OnEnded()); | 722 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK)); |
| 733 host->NotifyEnded(); | 723 host->NotifyEnded(); |
| 734 } | 724 } |
| 735 | 725 |
| 736 TEST_F(PipelineImplTest, ErrorDuringSeek) { | 726 TEST_F(PipelineImplTest, ErrorDuringSeek) { |
| 737 CreateAudioStream(); | 727 CreateAudioStream(); |
| 738 MockDemuxerStreamVector streams; | 728 MockDemuxerStreamVector streams; |
| 739 streams.push_back(audio_stream()); | 729 streams.push_back(audio_stream()); |
| 740 | 730 |
| 741 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(10)); | 731 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(10)); |
| 742 InitializeAudioDecoder(audio_stream()); | 732 InitializeAudioDecoder(audio_stream()); |
| 743 InitializeAudioRenderer(); | 733 InitializeAudioRenderer(); |
| 744 InitializePipeline(); | 734 InitializePipeline(PIPELINE_OK); |
| 745 | 735 |
| 746 float playback_rate = 1.0f; | 736 float playback_rate = 1.0f; |
| 747 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate)); | 737 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate)); |
| 748 EXPECT_CALL(*mocks_->audio_decoder(), SetPlaybackRate(playback_rate)); | 738 EXPECT_CALL(*mocks_->audio_decoder(), SetPlaybackRate(playback_rate)); |
| 749 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate)); | 739 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate)); |
| 750 pipeline_->SetPlaybackRate(playback_rate); | 740 pipeline_->SetPlaybackRate(playback_rate); |
| 751 message_loop_.RunAllPending(); | 741 message_loop_.RunAllPending(); |
| 752 | 742 |
| 753 InSequence s; | 743 InSequence s; |
| 754 | 744 |
| 755 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 745 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 756 | 746 |
| 757 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, NotNull())) | 747 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, NotNull())) |
| 758 .WillOnce(DoAll(SetError(mocks_->demuxer(), | 748 .WillOnce(DoAll(SetError(mocks_->demuxer(), |
| 759 PIPELINE_ERROR_READ), | 749 PIPELINE_ERROR_READ), |
| 760 Invoke(&RunFilterCallback))); | 750 Invoke(&RunFilterCallback))); |
| 761 | 751 |
| 762 pipeline_->Seek(seek_time, NewExpectedCallback()); | 752 pipeline_->Seek(seek_time, NewCallback( |
| 763 EXPECT_CALL(callbacks_, OnError()); | 753 reinterpret_cast<CallbackHelper*>(&callbacks_), &CallbackHelper::OnSeek)); |
| 754 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | |
| 755 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); | |
| 764 message_loop_.RunAllPending(); | 756 message_loop_.RunAllPending(); |
| 765 } | 757 } |
| 766 | 758 |
| 759 class FlexibleCallbackRunner : public base::DelegateSimpleThread::Delegate { | |
| 760 public: | |
| 761 FlexibleCallbackRunner(int delayInMs, PipelineStatus status, | |
| 762 PipelineStatusCallback* callback) | |
| 763 : delayInMs_(delayInMs), status_(status), callback_(callback) { | |
|
acolwell GONE FROM CHROMIUM
2011/03/15 23:43:55
I think these need to be on separate lines.
Ami GONE FROM CHROMIUM
2011/03/16 00:01:02
I don't think so.
| |
| 764 if (delayInMs_ < 0) { | |
| 765 callback_->Run(status_); | |
| 766 return; | |
| 767 } | |
| 768 } | |
| 769 virtual void Run() { | |
| 770 if (delayInMs_ < 0) return; | |
| 771 base::PlatformThread::Sleep(delayInMs_); | |
| 772 callback_->Run(status_); | |
| 773 } | |
| 774 | |
| 775 private: | |
| 776 int delayInMs_; | |
| 777 PipelineStatus status_; | |
| 778 PipelineStatusCallback* callback_; | |
| 779 }; | |
| 780 | |
| 781 void TestPipelineStatusNotification(int delayInMs) { | |
| 782 PipelineStatusNotification note; | |
| 783 // Arbitrary error value we expect to fish out of the notification after the | |
| 784 // callback is fired. | |
| 785 const PipelineStatus expected_error = PIPELINE_ERROR_URL_NOT_FOUND; | |
| 786 FlexibleCallbackRunner runner(delayInMs, expected_error, note.Callback()); | |
| 787 base::DelegateSimpleThread thread(&runner, "FlexibleCallbackRunner"); | |
| 788 thread.Start(); | |
| 789 note.Wait(); | |
| 790 EXPECT_EQ(note.status(), expected_error); | |
| 791 thread.Join(); | |
| 792 } | |
| 793 | |
| 794 // Test that in-line callback (same thread, no yield) works correctly. | |
| 795 TEST(PipelineStatusNotificationTest, InlineCallback) { | |
| 796 TestPipelineStatusNotification(-1); | |
| 797 } | |
| 798 | |
| 799 // Test that different-thread, no-delay callback works correctly. | |
| 800 TEST(PipelineStatusNotificationTest, ImmediateCallback) { | |
| 801 TestPipelineStatusNotification(0); | |
| 802 } | |
| 803 | |
| 804 // Test that different-thread, some-delay callback (the expected common case) | |
| 805 // works correctly. | |
| 806 TEST(PipelineStatusNotificationTest, DelayedCallback) { | |
| 807 TestPipelineStatusNotification(20); | |
| 808 } | |
| 809 | |
| 767 } // namespace media | 810 } // namespace media |
| OLD | NEW |