| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/threading/simple_thread.h" | 10 #include "base/threading/simple_thread.h" |
| 11 #include "media/base/clock.h" | 11 #include "media/base/clock.h" |
| 12 #include "media/base/media_log.h" | 12 #include "media/base/media_log.h" |
| 13 #include "media/base/pipeline.h" | 13 #include "media/base/pipeline.h" |
| 14 #include "media/base/mock_callback.h" | 14 #include "media/base/mock_callback.h" |
| 15 #include "media/base/mock_filters.h" | 15 #include "media/base/mock_filters.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "ui/gfx/size.h" | 17 #include "ui/gfx/size.h" |
| 18 | 18 |
| 19 using ::testing::_; | 19 using ::testing::_; |
| 20 using ::testing::DeleteArg; | 20 using ::testing::DeleteArg; |
| 21 using ::testing::DoAll; | 21 using ::testing::DoAll; |
| 22 // TODO(scherkus): Remove InSequence after refactoring Pipeline. |
| 22 using ::testing::InSequence; | 23 using ::testing::InSequence; |
| 23 using ::testing::Invoke; | 24 using ::testing::Invoke; |
| 24 using ::testing::InvokeWithoutArgs; | 25 using ::testing::InvokeWithoutArgs; |
| 25 using ::testing::Mock; | 26 using ::testing::Mock; |
| 26 using ::testing::NotNull; | 27 using ::testing::NotNull; |
| 27 using ::testing::Return; | 28 using ::testing::Return; |
| 28 using ::testing::ReturnRef; | 29 using ::testing::ReturnRef; |
| 29 using ::testing::SaveArg; | 30 using ::testing::SaveArg; |
| 30 using ::testing::StrictMock; | 31 using ::testing::StrictMock; |
| 31 using ::testing::WithArg; | 32 using ::testing::WithArg; |
| 32 | 33 |
| 33 namespace media { | 34 namespace media { |
| 34 | 35 |
| 35 // Demuxer properties. | 36 // Demuxer properties. |
| 36 static const int kTotalBytes = 1024; | 37 static const int kTotalBytes = 1024; |
| 37 static const int kBitrate = 1234; | 38 static const int kBitrate = 1234; |
| 38 | 39 |
| 39 ACTION_P(SetDemuxerProperties, duration) { | 40 ACTION_P(SetDemuxerProperties, duration) { |
| 40 arg0->SetTotalBytes(kTotalBytes); | 41 arg0->SetTotalBytes(kTotalBytes); |
| 41 arg0->SetDuration(duration); | 42 arg0->SetDuration(duration); |
| 42 } | 43 } |
| 43 | 44 |
| 44 ACTION(RunPipelineStatusCB1) { | 45 ACTION_P2(Stop, pipeline, stop_cb) { |
| 46 pipeline->Stop(stop_cb); |
| 47 } |
| 48 |
| 49 ACTION_P2(SetError, pipeline, status) { |
| 50 pipeline->SetErrorForTesting(status); |
| 51 } |
| 52 |
| 53 ACTION(RunPipelineStatusCB) { |
| 45 arg1.Run(PIPELINE_OK); | 54 arg1.Run(PIPELINE_OK); |
| 46 } | 55 } |
| 47 | 56 |
| 48 ACTION_P(RunPipelineStatusCB1WithStatus, status) { | 57 ACTION_P(RunPipelineStatusCBWithStatus, status) { |
| 49 arg1.Run(status); | 58 arg1.Run(status); |
| 50 } | 59 } |
| 51 | 60 |
| 52 // Used for setting expectations on pipeline callbacks. Using a StrictMock | 61 // Used for setting expectations on pipeline callbacks. Using a StrictMock |
| 53 // also lets us test for missing callbacks. | 62 // also lets us test for missing callbacks. |
| 54 class CallbackHelper { | 63 class CallbackHelper { |
| 55 public: | 64 public: |
| 56 CallbackHelper() {} | 65 CallbackHelper() {} |
| 57 virtual ~CallbackHelper() {} | 66 virtual ~CallbackHelper() {} |
| 58 | 67 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 virtual ~PipelineTest() { | 100 virtual ~PipelineTest() { |
| 92 if (!pipeline_->IsRunning()) { | 101 if (!pipeline_->IsRunning()) { |
| 93 return; | 102 return; |
| 94 } | 103 } |
| 95 | 104 |
| 96 // Shutdown sequence. | 105 // Shutdown sequence. |
| 97 if (pipeline_->IsInitialized()) { | 106 if (pipeline_->IsInitialized()) { |
| 98 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 107 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 99 .WillOnce(RunClosure()); | 108 .WillOnce(RunClosure()); |
| 100 | 109 |
| 110 // TODO(scherkus): Don't pause+flush on shutdown, |
| 111 // see http://crbug.com/110228 |
| 101 if (audio_stream_) { | 112 if (audio_stream_) { |
| 102 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) | 113 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) |
| 103 .WillOnce(RunClosure()); | 114 .WillOnce(RunClosure()); |
| 104 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) | 115 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) |
| 105 .WillOnce(RunClosure()); | 116 .WillOnce(RunClosure()); |
| 106 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) | 117 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) |
| 107 .WillOnce(RunClosure()); | 118 .WillOnce(RunClosure()); |
| 108 } | 119 } |
| 109 | 120 |
| 110 if (video_stream_) { | 121 if (video_stream_) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 127 mocks_.reset(); | 138 mocks_.reset(); |
| 128 } | 139 } |
| 129 | 140 |
| 130 protected: | 141 protected: |
| 131 // Sets up expectations to allow the demuxer to initialize. | 142 // Sets up expectations to allow the demuxer to initialize. |
| 132 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; | 143 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; |
| 133 void InitializeDemuxer(MockDemuxerStreamVector* streams, | 144 void InitializeDemuxer(MockDemuxerStreamVector* streams, |
| 134 const base::TimeDelta& duration) { | 145 const base::TimeDelta& duration) { |
| 135 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) | 146 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) |
| 136 .WillOnce(DoAll(SetDemuxerProperties(duration), | 147 .WillOnce(DoAll(SetDemuxerProperties(duration), |
| 137 RunPipelineStatusCB1())); | 148 RunPipelineStatusCB())); |
| 138 | 149 |
| 139 // Configure the demuxer to return the streams. | 150 // Configure the demuxer to return the streams. |
| 140 for (size_t i = 0; i < streams->size(); ++i) { | 151 for (size_t i = 0; i < streams->size(); ++i) { |
| 141 scoped_refptr<DemuxerStream> stream((*streams)[i]); | 152 scoped_refptr<DemuxerStream> stream((*streams)[i]); |
| 142 EXPECT_CALL(*mocks_->demuxer(), GetStream(stream->type())) | 153 EXPECT_CALL(*mocks_->demuxer(), GetStream(stream->type())) |
| 143 .WillRepeatedly(Return(stream)); | 154 .WillRepeatedly(Return(stream)); |
| 144 } | 155 } |
| 145 } | 156 } |
| 146 | 157 |
| 147 void InitializeDemuxer(MockDemuxerStreamVector* streams) { | 158 void InitializeDemuxer(MockDemuxerStreamVector* streams) { |
| 148 // Initialize with a default non-zero duration. | 159 // Initialize with a default non-zero duration. |
| 149 InitializeDemuxer(streams, base::TimeDelta::FromSeconds(10)); | 160 InitializeDemuxer(streams, base::TimeDelta::FromSeconds(10)); |
| 150 } | 161 } |
| 151 | 162 |
| 152 StrictMock<MockDemuxerStream>* CreateStream(DemuxerStream::Type type) { | 163 StrictMock<MockDemuxerStream>* CreateStream(DemuxerStream::Type type) { |
| 153 StrictMock<MockDemuxerStream>* stream = | 164 StrictMock<MockDemuxerStream>* stream = |
| 154 new StrictMock<MockDemuxerStream>(); | 165 new StrictMock<MockDemuxerStream>(); |
| 155 EXPECT_CALL(*stream, type()) | 166 EXPECT_CALL(*stream, type()) |
| 156 .WillRepeatedly(Return(type)); | 167 .WillRepeatedly(Return(type)); |
| 157 return stream; | 168 return stream; |
| 158 } | 169 } |
| 159 | 170 |
| 160 // Sets up expectations to allow the video decoder to initialize. | 171 // Sets up expectations to allow the video decoder to initialize. |
| 161 void InitializeVideoDecoder(const scoped_refptr<DemuxerStream>& stream) { | 172 void InitializeVideoDecoder(const scoped_refptr<DemuxerStream>& stream) { |
| 162 EXPECT_CALL(*mocks_->video_decoder(), | 173 EXPECT_CALL(*mocks_->video_decoder(), |
| 163 Initialize(stream, _, _)) | 174 Initialize(stream, _, _)) |
| 164 .WillOnce(RunPipelineStatusCB1()); | 175 .WillOnce(RunPipelineStatusCB()); |
| 165 } | 176 } |
| 166 | 177 |
| 167 // Sets up expectations to allow the audio decoder to initialize. | 178 // Sets up expectations to allow the audio decoder to initialize. |
| 168 void InitializeAudioDecoder(const scoped_refptr<DemuxerStream>& stream) { | 179 void InitializeAudioDecoder(const scoped_refptr<DemuxerStream>& stream) { |
| 169 EXPECT_CALL(*mocks_->audio_decoder(), Initialize(stream, _, _)) | 180 EXPECT_CALL(*mocks_->audio_decoder(), Initialize(stream, _, _)) |
| 170 .WillOnce(RunPipelineStatusCB1()); | 181 .WillOnce(RunPipelineStatusCB()); |
| 171 } | 182 } |
| 172 | 183 |
| 173 // Sets up expectations to allow the video renderer to initialize. | 184 // Sets up expectations to allow the video renderer to initialize. |
| 174 void InitializeVideoRenderer() { | 185 void InitializeVideoRenderer() { |
| 175 EXPECT_CALL(*mocks_->video_renderer(), Initialize( | 186 EXPECT_CALL(*mocks_->video_renderer(), Initialize( |
| 176 scoped_refptr<VideoDecoder>(mocks_->video_decoder()), | 187 scoped_refptr<VideoDecoder>(mocks_->video_decoder()), |
| 177 _, _, _, _, _, _, _, _)) | 188 _, _, _, _, _, _, _, _)) |
| 178 .WillOnce(RunPipelineStatusCB1()); | 189 .WillOnce(RunPipelineStatusCB()); |
| 179 EXPECT_CALL(*mocks_->video_renderer(), SetPlaybackRate(0.0f)); | 190 EXPECT_CALL(*mocks_->video_renderer(), SetPlaybackRate(0.0f)); |
| 180 | 191 |
| 181 // Startup sequence. | 192 // Startup sequence. |
| 182 EXPECT_CALL(*mocks_->video_renderer(), | 193 EXPECT_CALL(*mocks_->video_renderer(), |
| 183 Preroll(mocks_->demuxer()->GetStartTime(), _)) | 194 Preroll(mocks_->demuxer()->GetStartTime(), _)) |
| 184 .WillOnce(RunPipelineStatusCB1()); | 195 .WillOnce(RunPipelineStatusCB()); |
| 185 EXPECT_CALL(*mocks_->video_renderer(), Play(_)) | 196 EXPECT_CALL(*mocks_->video_renderer(), Play(_)) |
| 186 .WillOnce(RunClosure()); | 197 .WillOnce(RunClosure()); |
| 187 } | 198 } |
| 188 | 199 |
| 189 // Sets up expectations to allow the audio renderer to initialize. | 200 // Sets up expectations to allow the audio renderer to initialize. |
| 190 void InitializeAudioRenderer(bool disable_after_init_cb = false) { | 201 void InitializeAudioRenderer(bool disable_after_init_cb = false) { |
| 191 if (disable_after_init_cb) { | 202 if (disable_after_init_cb) { |
| 192 EXPECT_CALL(*mocks_->audio_renderer(), Initialize( | 203 EXPECT_CALL(*mocks_->audio_renderer(), Initialize( |
| 193 scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), | 204 scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), |
| 194 _, _, _, _, _, _)) | 205 _, _, _, _, _, _)) |
| 195 .WillOnce(DoAll(RunPipelineStatusCB1(), | 206 .WillOnce(DoAll(RunPipelineStatusCB(), |
| 196 WithArg<5>(RunClosure()))); // |disabled_cb|. | 207 WithArg<5>(RunClosure()))); // |disabled_cb|. |
| 197 } else { | 208 } else { |
| 198 EXPECT_CALL(*mocks_->audio_renderer(), Initialize( | 209 EXPECT_CALL(*mocks_->audio_renderer(), Initialize( |
| 199 scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), | 210 scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), |
| 200 _, _, _, _, _, _)) | 211 _, _, _, _, _, _)) |
| 201 .WillOnce(DoAll(SaveArg<3>(&audio_time_cb_), | 212 .WillOnce(DoAll(SaveArg<3>(&audio_time_cb_), |
| 202 RunPipelineStatusCB1())); | 213 RunPipelineStatusCB())); |
| 203 } | 214 } |
| 204 } | 215 } |
| 205 | 216 |
| 206 // Sets up expectations on the callback and initializes the pipeline. Called | 217 // Sets up expectations on the callback and initializes the pipeline. Called |
| 207 // after tests have set expectations any filters they wish to use. | 218 // after tests have set expectations any filters they wish to use. |
| 208 void InitializePipeline(PipelineStatus start_status) { | 219 void InitializePipeline(PipelineStatus start_status) { |
| 209 EXPECT_CALL(callbacks_, OnStart(start_status)); | 220 EXPECT_CALL(callbacks_, OnStart(start_status)); |
| 210 | 221 |
| 211 if (start_status == PIPELINE_OK) { | 222 if (start_status == PIPELINE_OK) { |
| 212 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(0.0f)); | 223 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(0.0f)); |
| 213 | 224 |
| 214 if (audio_stream_) { | 225 if (audio_stream_) { |
| 215 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(0.0f)); | 226 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(0.0f)); |
| 216 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(1.0f)); | 227 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(1.0f)); |
| 217 | 228 |
| 218 // Startup sequence. | 229 // Startup sequence. |
| 219 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(base::TimeDelta(), _)) | 230 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(base::TimeDelta(), _)) |
| 220 .WillOnce(RunPipelineStatusCB1()); | 231 .WillOnce(RunPipelineStatusCB()); |
| 221 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) | 232 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) |
| 222 .WillOnce(RunClosure()); | 233 .WillOnce(RunClosure()); |
| 223 } | 234 } |
| 224 } | 235 } |
| 225 | 236 |
| 226 pipeline_->Start( | 237 pipeline_->Start( |
| 227 mocks_->Create().Pass(), | 238 mocks_->Create().Pass(), |
| 228 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), | 239 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), |
| 229 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), | 240 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), |
| 230 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_))); | 241 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_))); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 243 return audio_stream_; | 254 return audio_stream_; |
| 244 } | 255 } |
| 245 | 256 |
| 246 MockDemuxerStream* video_stream() { | 257 MockDemuxerStream* video_stream() { |
| 247 return video_stream_; | 258 return video_stream_; |
| 248 } | 259 } |
| 249 | 260 |
| 250 void ExpectSeek(const base::TimeDelta& seek_time) { | 261 void ExpectSeek(const base::TimeDelta& seek_time) { |
| 251 // Every filter should receive a call to Seek(). | 262 // Every filter should receive a call to Seek(). |
| 252 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) | 263 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) |
| 253 .WillOnce(RunPipelineStatusCB1()); | 264 .WillOnce(RunPipelineStatusCB()); |
| 254 | 265 |
| 255 if (audio_stream_) { | 266 if (audio_stream_) { |
| 256 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) | 267 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) |
| 257 .WillOnce(RunClosure()); | 268 .WillOnce(RunClosure()); |
| 258 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) | 269 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) |
| 259 .WillOnce(RunClosure()); | 270 .WillOnce(RunClosure()); |
| 260 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(seek_time, _)) | 271 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(seek_time, _)) |
| 261 .WillOnce(RunPipelineStatusCB1()); | 272 .WillOnce(RunPipelineStatusCB()); |
| 262 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) | 273 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) |
| 263 .WillOnce(RunClosure()); | 274 .WillOnce(RunClosure()); |
| 264 } | 275 } |
| 265 | 276 |
| 266 if (video_stream_) { | 277 if (video_stream_) { |
| 267 EXPECT_CALL(*mocks_->video_renderer(), Pause(_)) | 278 EXPECT_CALL(*mocks_->video_renderer(), Pause(_)) |
| 268 .WillOnce(RunClosure()); | 279 .WillOnce(RunClosure()); |
| 269 EXPECT_CALL(*mocks_->video_renderer(), Flush(_)) | 280 EXPECT_CALL(*mocks_->video_renderer(), Flush(_)) |
| 270 .WillOnce(RunClosure()); | 281 .WillOnce(RunClosure()); |
| 271 EXPECT_CALL(*mocks_->video_renderer(), Preroll(seek_time, _)) | 282 EXPECT_CALL(*mocks_->video_renderer(), Preroll(seek_time, _)) |
| 272 .WillOnce(RunPipelineStatusCB1()); | 283 .WillOnce(RunPipelineStatusCB()); |
| 273 EXPECT_CALL(*mocks_->video_renderer(), Play(_)) | 284 EXPECT_CALL(*mocks_->video_renderer(), Play(_)) |
| 274 .WillOnce(RunClosure()); | 285 .WillOnce(RunClosure()); |
| 275 } | 286 } |
| 276 | 287 |
| 277 // We expect a successful seek callback. | 288 // We expect a successful seek callback. |
| 278 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); | 289 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
| 279 } | 290 } |
| 280 | 291 |
| 281 void DoSeek(const base::TimeDelta& seek_time) { | 292 void DoSeek(const base::TimeDelta& seek_time) { |
| 282 pipeline_->Seek(seek_time, | 293 pipeline_->Seek(seek_time, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 collection.Pass(), | 385 collection.Pass(), |
| 375 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), | 386 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), |
| 376 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), | 387 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), |
| 377 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_))); | 388 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_))); |
| 378 message_loop_.RunAllPending(); | 389 message_loop_.RunAllPending(); |
| 379 EXPECT_FALSE(pipeline_->IsInitialized()); | 390 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 380 } | 391 } |
| 381 | 392 |
| 382 TEST_F(PipelineTest, URLNotFound) { | 393 TEST_F(PipelineTest, URLNotFound) { |
| 383 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) | 394 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) |
| 384 .WillOnce(RunPipelineStatusCB1WithStatus(PIPELINE_ERROR_URL_NOT_FOUND)); | 395 .WillOnce(RunPipelineStatusCBWithStatus(PIPELINE_ERROR_URL_NOT_FOUND)); |
| 385 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 396 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 386 .WillOnce(RunClosure()); | 397 .WillOnce(RunClosure()); |
| 387 | 398 |
| 388 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND); | 399 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND); |
| 389 EXPECT_FALSE(pipeline_->IsInitialized()); | 400 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 390 } | 401 } |
| 391 | 402 |
| 392 TEST_F(PipelineTest, NoStreams) { | 403 TEST_F(PipelineTest, NoStreams) { |
| 393 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) | 404 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) |
| 394 .WillOnce(RunPipelineStatusCB1()); | 405 .WillOnce(RunPipelineStatusCB()); |
| 395 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 406 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 396 .WillOnce(RunClosure()); | 407 .WillOnce(RunClosure()); |
| 397 | 408 |
| 398 InitializePipeline(PIPELINE_ERROR_COULD_NOT_RENDER); | 409 InitializePipeline(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 399 EXPECT_FALSE(pipeline_->IsInitialized()); | 410 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 400 } | 411 } |
| 401 | 412 |
| 402 TEST_F(PipelineTest, AudioStream) { | 413 TEST_F(PipelineTest, AudioStream) { |
| 403 CreateAudioStream(); | 414 CreateAudioStream(); |
| 404 MockDemuxerStreamVector streams; | 415 MockDemuxerStreamVector streams; |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 | 724 |
| 714 // Seek() isn't called as the demuxer errors out first. | 725 // Seek() isn't called as the demuxer errors out first. |
| 715 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) | 726 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) |
| 716 .WillOnce(RunClosure()); | 727 .WillOnce(RunClosure()); |
| 717 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) | 728 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) |
| 718 .WillOnce(RunClosure()); | 729 .WillOnce(RunClosure()); |
| 719 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) | 730 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) |
| 720 .WillOnce(RunClosure()); | 731 .WillOnce(RunClosure()); |
| 721 | 732 |
| 722 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) | 733 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) |
| 723 .WillOnce(RunPipelineStatusCB1WithStatus(PIPELINE_ERROR_READ)); | 734 .WillOnce(RunPipelineStatusCBWithStatus(PIPELINE_ERROR_READ)); |
| 724 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 735 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 725 .WillOnce(RunClosure()); | 736 .WillOnce(RunClosure()); |
| 726 | 737 |
| 727 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, | 738 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
| 728 base::Unretained(&callbacks_))); | 739 base::Unretained(&callbacks_))); |
| 729 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | 740 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 730 message_loop_.RunAllPending(); | 741 message_loop_.RunAllPending(); |
| 731 } | 742 } |
| 732 | 743 |
| 733 // Invoked function OnError. This asserts that the pipeline does not enqueue | 744 // Invoked function OnError. This asserts that the pipeline does not enqueue |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 | 780 |
| 770 // Seek() isn't called as the demuxer errors out first. | 781 // Seek() isn't called as the demuxer errors out first. |
| 771 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) | 782 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) |
| 772 .WillOnce(RunClosure()); | 783 .WillOnce(RunClosure()); |
| 773 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) | 784 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) |
| 774 .WillOnce(RunClosure()); | 785 .WillOnce(RunClosure()); |
| 775 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) | 786 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) |
| 776 .WillOnce(RunClosure()); | 787 .WillOnce(RunClosure()); |
| 777 | 788 |
| 778 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) | 789 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) |
| 779 .WillOnce(RunPipelineStatusCB1WithStatus(PIPELINE_ERROR_READ)); | 790 .WillOnce(RunPipelineStatusCBWithStatus(PIPELINE_ERROR_READ)); |
| 780 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 791 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 781 .WillOnce(RunClosure()); | 792 .WillOnce(RunClosure()); |
| 782 | 793 |
| 783 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, | 794 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
| 784 base::Unretained(&callbacks_))); | 795 base::Unretained(&callbacks_))); |
| 785 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | 796 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 786 message_loop_.RunAllPending(); | 797 message_loop_.RunAllPending(); |
| 787 } | 798 } |
| 788 | 799 |
| 789 TEST_F(PipelineTest, StartTimeIsZero) { | 800 TEST_F(PipelineTest, StartTimeIsZero) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 base::TimeDelta::FromMilliseconds(500)); | 867 base::TimeDelta::FromMilliseconds(500)); |
| 857 | 868 |
| 858 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 869 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 859 | 870 |
| 860 // Arrange to trigger a time update while the demuxer is in the middle of | 871 // Arrange to trigger a time update while the demuxer is in the middle of |
| 861 // seeking. This update should be ignored by the pipeline and the clock should | 872 // seeking. This update should be ignored by the pipeline and the clock should |
| 862 // not get updated. | 873 // not get updated. |
| 863 base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700); | 874 base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700); |
| 864 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) | 875 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _)) |
| 865 .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run), | 876 .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run), |
| 866 RunPipelineStatusCB1())); | 877 RunPipelineStatusCB())); |
| 867 | 878 |
| 868 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) | 879 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) |
| 869 .WillOnce(RunClosure()); | 880 .WillOnce(RunClosure()); |
| 870 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) | 881 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) |
| 871 .WillOnce(RunClosure()); | 882 .WillOnce(RunClosure()); |
| 872 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(seek_time, _)) | 883 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(seek_time, _)) |
| 873 .WillOnce(RunPipelineStatusCB1()); | 884 .WillOnce(RunPipelineStatusCB()); |
| 874 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) | 885 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) |
| 875 .WillOnce(RunClosure()); | 886 .WillOnce(RunClosure()); |
| 876 | 887 |
| 877 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); | 888 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
| 878 DoSeek(seek_time); | 889 DoSeek(seek_time); |
| 879 | 890 |
| 880 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time); | 891 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time); |
| 881 | 892 |
| 882 // Now that the seek is complete, verify that time updates advance the current | 893 // Now that the seek is complete, verify that time updates advance the current |
| 883 // time. | 894 // time. |
| 884 base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100); | 895 base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100); |
| 885 audio_time_cb_.Run(new_time, new_time); | 896 audio_time_cb_.Run(new_time, new_time); |
| 886 | 897 |
| 887 EXPECT_EQ(pipeline_->GetMediaTime(), new_time); | 898 EXPECT_EQ(pipeline_->GetMediaTime(), new_time); |
| 888 } | 899 } |
| 889 | 900 |
| 890 TEST_F(PipelineTest, InitFailure_Demuxer) { | 901 TEST_F(PipelineTest, InitFailure_Demuxer) { |
| 891 PipelineStatus expected_status = DEMUXER_ERROR_COULD_NOT_OPEN; | 902 PipelineStatus expected_status = DEMUXER_ERROR_COULD_NOT_OPEN; |
| 892 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) | 903 EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _)) |
| 893 .WillOnce(RunPipelineStatusCB1WithStatus(expected_status)); | 904 .WillOnce(RunPipelineStatusCBWithStatus(expected_status)); |
| 894 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 905 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 895 .WillOnce(RunClosure()); | 906 .WillOnce(RunClosure()); |
| 896 InitializePipeline(expected_status); | 907 InitializePipeline(expected_status); |
| 897 EXPECT_FALSE(pipeline_->IsInitialized()); | 908 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 898 } | 909 } |
| 899 | 910 |
| 900 TEST_F(PipelineTest, InitFailure_AudioDecoder) { | 911 TEST_F(PipelineTest, InitFailure_AudioDecoder) { |
| 901 CreateAudioStream(); | 912 CreateAudioStream(); |
| 902 MockDemuxerStreamVector streams; | 913 MockDemuxerStreamVector streams; |
| 903 streams.push_back(audio_stream()); | 914 streams.push_back(audio_stream()); |
| 904 | 915 |
| 905 InitializeDemuxer(&streams); | 916 InitializeDemuxer(&streams); |
| 906 | 917 |
| 907 PipelineStatus expected_status = PIPELINE_ERROR_DECODE; | 918 PipelineStatus expected_status = PIPELINE_ERROR_DECODE; |
| 908 scoped_refptr<DemuxerStream> stream = streams[0]; | 919 scoped_refptr<DemuxerStream> stream = streams[0]; |
| 909 EXPECT_CALL(*mocks_->audio_decoder(), Initialize(stream, _, _)) | 920 EXPECT_CALL(*mocks_->audio_decoder(), Initialize(stream, _, _)) |
| 910 .WillOnce(RunPipelineStatusCB1WithStatus(expected_status)); | 921 .WillOnce(RunPipelineStatusCBWithStatus(expected_status)); |
| 911 | 922 |
| 912 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 923 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 913 .WillOnce(RunClosure()); | 924 .WillOnce(RunClosure()); |
| 914 | 925 |
| 915 InitializePipeline(expected_status); | 926 InitializePipeline(expected_status); |
| 916 EXPECT_FALSE(pipeline_->IsInitialized()); | 927 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 917 EXPECT_FALSE(pipeline_->HasAudio()); | 928 EXPECT_FALSE(pipeline_->HasAudio()); |
| 918 } | 929 } |
| 919 | 930 |
| 920 TEST_F(PipelineTest, InitFailure_AudioRenderer) { | 931 TEST_F(PipelineTest, InitFailure_AudioRenderer) { |
| 921 CreateAudioStream(); | 932 CreateAudioStream(); |
| 922 MockDemuxerStreamVector streams; | 933 MockDemuxerStreamVector streams; |
| 923 streams.push_back(audio_stream()); | 934 streams.push_back(audio_stream()); |
| 924 | 935 |
| 925 InitializeDemuxer(&streams); | 936 InitializeDemuxer(&streams); |
| 926 InitializeAudioDecoder(audio_stream()); | 937 InitializeAudioDecoder(audio_stream()); |
| 927 | 938 |
| 928 PipelineStatus expected_status = PIPELINE_ERROR_INITIALIZATION_FAILED; | 939 PipelineStatus expected_status = PIPELINE_ERROR_INITIALIZATION_FAILED; |
| 929 EXPECT_CALL(*mocks_->audio_renderer(), Initialize( | 940 EXPECT_CALL(*mocks_->audio_renderer(), Initialize( |
| 930 scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), | 941 scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), |
| 931 _, _, _, _, _, _)) | 942 _, _, _, _, _, _)) |
| 932 .WillOnce(RunPipelineStatusCB1WithStatus(expected_status)); | 943 .WillOnce(RunPipelineStatusCBWithStatus(expected_status)); |
| 933 | 944 |
| 934 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 945 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 935 .WillOnce(RunClosure()); | 946 .WillOnce(RunClosure()); |
| 936 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) | 947 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) |
| 937 .WillOnce(RunClosure()); | 948 .WillOnce(RunClosure()); |
| 938 | 949 |
| 939 InitializePipeline(expected_status); | 950 InitializePipeline(expected_status); |
| 940 EXPECT_FALSE(pipeline_->IsInitialized()); | 951 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 941 EXPECT_TRUE(pipeline_->HasAudio()); | 952 EXPECT_TRUE(pipeline_->HasAudio()); |
| 942 } | 953 } |
| 943 | 954 |
| 944 TEST_F(PipelineTest, InitFailure_VideoDecoder) { | 955 TEST_F(PipelineTest, InitFailure_VideoDecoder) { |
| 945 CreateAudioStream(); | 956 CreateAudioStream(); |
| 946 CreateVideoStream(); | 957 CreateVideoStream(); |
| 947 MockDemuxerStreamVector streams; | 958 MockDemuxerStreamVector streams; |
| 948 streams.push_back(audio_stream()); | 959 streams.push_back(audio_stream()); |
| 949 streams.push_back(video_stream()); | 960 streams.push_back(video_stream()); |
| 950 | 961 |
| 951 InitializeDemuxer(&streams); | 962 InitializeDemuxer(&streams); |
| 952 InitializeAudioDecoder(audio_stream()); | 963 InitializeAudioDecoder(audio_stream()); |
| 953 InitializeAudioRenderer(); | 964 InitializeAudioRenderer(); |
| 954 | 965 |
| 955 PipelineStatus expected_status = PIPELINE_ERROR_DECODE; | 966 PipelineStatus expected_status = PIPELINE_ERROR_DECODE; |
| 956 scoped_refptr<DemuxerStream> stream = streams[1]; | 967 scoped_refptr<DemuxerStream> stream = streams[1]; |
| 957 EXPECT_CALL(*mocks_->video_decoder(), | 968 EXPECT_CALL(*mocks_->video_decoder(), |
| 958 Initialize(stream, _, _)) | 969 Initialize(stream, _, _)) |
| 959 .WillOnce(RunPipelineStatusCB1WithStatus(expected_status)); | 970 .WillOnce(RunPipelineStatusCBWithStatus(expected_status)); |
| 960 | 971 |
| 961 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 972 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 962 .WillOnce(RunClosure()); | 973 .WillOnce(RunClosure()); |
| 963 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) | 974 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) |
| 964 .WillOnce(RunClosure()); | 975 .WillOnce(RunClosure()); |
| 965 | 976 |
| 966 InitializePipeline(expected_status); | 977 InitializePipeline(expected_status); |
| 967 EXPECT_FALSE(pipeline_->IsInitialized()); | 978 EXPECT_FALSE(pipeline_->IsInitialized()); |
| 968 EXPECT_TRUE(pipeline_->HasAudio()); | 979 EXPECT_TRUE(pipeline_->HasAudio()); |
| 969 EXPECT_FALSE(pipeline_->HasVideo()); | 980 EXPECT_FALSE(pipeline_->HasVideo()); |
| 970 } | 981 } |
| 971 | 982 |
| 972 TEST_F(PipelineTest, InitFailure_VideoRenderer) { | 983 TEST_F(PipelineTest, InitFailure_VideoRenderer) { |
| 973 CreateAudioStream(); | 984 CreateAudioStream(); |
| 974 CreateVideoStream(); | 985 CreateVideoStream(); |
| 975 MockDemuxerStreamVector streams; | 986 MockDemuxerStreamVector streams; |
| 976 streams.push_back(audio_stream()); | 987 streams.push_back(audio_stream()); |
| 977 streams.push_back(video_stream()); | 988 streams.push_back(video_stream()); |
| 978 | 989 |
| 979 InitializeDemuxer(&streams); | 990 InitializeDemuxer(&streams); |
| 980 InitializeAudioDecoder(audio_stream()); | 991 InitializeAudioDecoder(audio_stream()); |
| 981 InitializeAudioRenderer(); | 992 InitializeAudioRenderer(); |
| 982 InitializeVideoDecoder(video_stream()); | 993 InitializeVideoDecoder(video_stream()); |
| 983 | 994 |
| 984 PipelineStatus expected_status = PIPELINE_ERROR_INITIALIZATION_FAILED; | 995 PipelineStatus expected_status = PIPELINE_ERROR_INITIALIZATION_FAILED; |
| 985 EXPECT_CALL(*mocks_->video_renderer(), Initialize( | 996 EXPECT_CALL(*mocks_->video_renderer(), Initialize( |
| 986 scoped_refptr<VideoDecoder>(mocks_->video_decoder()), | 997 scoped_refptr<VideoDecoder>(mocks_->video_decoder()), |
| 987 _, _, _, _, _, _, _, _)) | 998 _, _, _, _, _, _, _, _)) |
| 988 .WillOnce(RunPipelineStatusCB1WithStatus(expected_status)); | 999 .WillOnce(RunPipelineStatusCBWithStatus(expected_status)); |
| 989 | 1000 |
| 990 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) | 1001 EXPECT_CALL(*mocks_->demuxer(), Stop(_)) |
| 991 .WillOnce(RunClosure()); | 1002 .WillOnce(RunClosure()); |
| 992 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) | 1003 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)) |
| 993 .WillOnce(RunClosure()); | 1004 .WillOnce(RunClosure()); |
| 994 EXPECT_CALL(*mocks_->video_renderer(), Stop(_)) | 1005 EXPECT_CALL(*mocks_->video_renderer(), Stop(_)) |
| 995 .WillOnce(RunClosure()); | 1006 .WillOnce(RunClosure()); |
| 996 | 1007 |
| 997 InitializePipeline(expected_status); | 1008 InitializePipeline(expected_status); |
| 998 EXPECT_FALSE(pipeline_->IsInitialized()); | 1009 EXPECT_FALSE(pipeline_->IsInitialized()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 TEST(PipelineStatusNotificationTest, ImmediateCallback) { | 1057 TEST(PipelineStatusNotificationTest, ImmediateCallback) { |
| 1047 TestPipelineStatusNotification(base::TimeDelta::FromMilliseconds(0)); | 1058 TestPipelineStatusNotification(base::TimeDelta::FromMilliseconds(0)); |
| 1048 } | 1059 } |
| 1049 | 1060 |
| 1050 // Test that different-thread, some-delay callback (the expected common case) | 1061 // Test that different-thread, some-delay callback (the expected common case) |
| 1051 // works correctly. | 1062 // works correctly. |
| 1052 TEST(PipelineStatusNotificationTest, DelayedCallback) { | 1063 TEST(PipelineStatusNotificationTest, DelayedCallback) { |
| 1053 TestPipelineStatusNotification(base::TimeDelta::FromMilliseconds(20)); | 1064 TestPipelineStatusNotification(base::TimeDelta::FromMilliseconds(20)); |
| 1054 } | 1065 } |
| 1055 | 1066 |
| 1067 class PipelineTeardownTest : public PipelineTest { |
| 1068 public: |
| 1069 enum TeardownState { |
| 1070 kPausing, |
| 1071 kFlushing, |
| 1072 kSeeking, |
| 1073 kPrerolling, |
| 1074 kStarting, |
| 1075 kPlaying, |
| 1076 }; |
| 1077 |
| 1078 enum StopOrError { |
| 1079 kStop, |
| 1080 kError, |
| 1081 }; |
| 1082 |
| 1083 PipelineTeardownTest() { |
| 1084 CreateAudioStream(); |
| 1085 MockDemuxerStreamVector streams; |
| 1086 streams.push_back(audio_stream()); |
| 1087 |
| 1088 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000)); |
| 1089 InitializeAudioDecoder(audio_stream()); |
| 1090 InitializeAudioRenderer(); |
| 1091 InitializePipeline(PIPELINE_OK); |
| 1092 } |
| 1093 |
| 1094 void RunTest(TeardownState state, StopOrError stop_or_error) { |
| 1095 InSequence s; |
| 1096 switch (state) { |
| 1097 case kPausing: |
| 1098 case kFlushing: |
| 1099 case kSeeking: |
| 1100 case kPrerolling: |
| 1101 case kStarting: |
| 1102 if (stop_or_error == kStop) { |
| 1103 ExpectSeekStop(state); |
| 1104 } else { |
| 1105 ExpectSeekError(state); |
| 1106 } |
| 1107 DoSeek(); |
| 1108 break; |
| 1109 |
| 1110 case kPlaying: |
| 1111 if (stop_or_error == kStop) { |
| 1112 ExpectStop(); |
| 1113 DoStop(); |
| 1114 } else { |
| 1115 ExpectPlaybackError(); |
| 1116 DoPlaybackError(); |
| 1117 } |
| 1118 break; |
| 1119 } |
| 1120 } |
| 1121 |
| 1122 private: |
| 1123 // TODO(scherkus): We do radically different things whether teardown is |
| 1124 // invoked via stop vs error. The teardown path should be the same, |
| 1125 // see http://crbug.com/110228 |
| 1126 void ExpectSeekStop(TeardownState state) { |
| 1127 base::Closure stop_cb = base::Bind( |
| 1128 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); |
| 1129 |
| 1130 if (state == kPausing) { |
| 1131 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) |
| 1132 .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunClosure())); |
| 1133 } else { |
| 1134 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure()); |
| 1135 } |
| 1136 |
| 1137 if (state == kFlushing) { |
| 1138 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) |
| 1139 .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunClosure())); |
| 1140 } else { |
| 1141 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)).WillOnce(RunClosure()); |
| 1142 } |
| 1143 |
| 1144 if (state == kSeeking) { |
| 1145 EXPECT_CALL(*mocks_->demuxer(), Seek(_, _)) |
| 1146 .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunPipelineStatusCB())); |
| 1147 } else { |
| 1148 EXPECT_CALL(*mocks_->demuxer(), Seek(_, _)) |
| 1149 .WillOnce(RunPipelineStatusCB()); |
| 1150 } |
| 1151 |
| 1152 if (state == kPrerolling) { |
| 1153 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(_, _)) |
| 1154 .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunPipelineStatusCB())); |
| 1155 } else { |
| 1156 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(_, _)) |
| 1157 .WillOnce(RunPipelineStatusCB()); |
| 1158 } |
| 1159 |
| 1160 if (state == kStarting) { |
| 1161 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) |
| 1162 .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunClosure())); |
| 1163 } else { |
| 1164 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)).WillOnce(RunClosure()); |
| 1165 } |
| 1166 |
| 1167 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
| 1168 ExpectStop(); |
| 1169 } |
| 1170 |
| 1171 void ExpectSeekError(TeardownState state) { |
| 1172 SetSeekErrorExpectations(state); |
| 1173 |
| 1174 // Executed after the error is raised. |
| 1175 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 1176 EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure()); |
| 1177 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure()); |
| 1178 } |
| 1179 |
| 1180 void SetSeekErrorExpectations(TeardownState state) { |
| 1181 if (state == kPausing) { |
| 1182 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)) |
| 1183 .WillOnce(DoAll(SetError(pipeline_, PIPELINE_ERROR_READ), |
| 1184 RunClosure())); |
| 1185 return; |
| 1186 } |
| 1187 |
| 1188 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure()); |
| 1189 |
| 1190 if (state == kFlushing) { |
| 1191 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)) |
| 1192 .WillOnce(DoAll(SetError(pipeline_, PIPELINE_ERROR_READ), |
| 1193 RunClosure())); |
| 1194 return; |
| 1195 } |
| 1196 |
| 1197 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)).WillOnce(RunClosure()); |
| 1198 |
| 1199 if (state == kSeeking) { |
| 1200 EXPECT_CALL(*mocks_->demuxer(), Seek(_, _)) |
| 1201 .WillOnce(RunPipelineStatusCBWithStatus(PIPELINE_ERROR_READ)); |
| 1202 return; |
| 1203 } |
| 1204 |
| 1205 EXPECT_CALL(*mocks_->demuxer(), Seek(_, _)) |
| 1206 .WillOnce(RunPipelineStatusCB()); |
| 1207 |
| 1208 if (state == kPrerolling) { |
| 1209 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(_, _)) |
| 1210 .WillOnce(RunPipelineStatusCBWithStatus(PIPELINE_ERROR_READ)); |
| 1211 return; |
| 1212 } |
| 1213 |
| 1214 EXPECT_CALL(*mocks_->audio_renderer(), Preroll(_, _)) |
| 1215 .WillOnce(RunPipelineStatusCB()); |
| 1216 |
| 1217 if (state == kStarting) { |
| 1218 EXPECT_CALL(*mocks_->audio_renderer(), Play(_)) |
| 1219 .WillOnce(DoAll(SetError(pipeline_, PIPELINE_ERROR_READ), |
| 1220 RunClosure())); |
| 1221 return; |
| 1222 } |
| 1223 |
| 1224 NOTREACHED() << "Unexpected TeardownState: " << state; |
| 1225 } |
| 1226 |
| 1227 void ExpectStop() { |
| 1228 // TODO(scherkus): Don't pause+flush, see http://crbug.com/110228 |
| 1229 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure()); |
| 1230 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)).WillOnce(RunClosure()); |
| 1231 EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure()); |
| 1232 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure()); |
| 1233 |
| 1234 EXPECT_CALL(callbacks_, OnStop()); |
| 1235 } |
| 1236 |
| 1237 void ExpectPlaybackError() { |
| 1238 // TODO(scherkus): Don't pause+flush, see http://crbug.com/110228 |
| 1239 EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure()); |
| 1240 EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)).WillOnce(RunClosure()); |
| 1241 EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure()); |
| 1242 EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure()); |
| 1243 |
| 1244 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); |
| 1245 } |
| 1246 |
| 1247 void DoSeek() { |
| 1248 pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind( |
| 1249 &CallbackHelper::OnSeek, base::Unretained(&callbacks_))); |
| 1250 message_loop_.RunAllPending(); |
| 1251 } |
| 1252 |
| 1253 void DoStop() { |
| 1254 pipeline_->Stop(base::Bind( |
| 1255 &CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
| 1256 message_loop_.RunAllPending(); |
| 1257 } |
| 1258 |
| 1259 void DoPlaybackError() { |
| 1260 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); |
| 1261 message_loop_.RunAllPending(); |
| 1262 } |
| 1263 |
| 1264 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest); |
| 1265 }; |
| 1266 |
| 1267 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \ |
| 1268 TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \ |
| 1269 RunTest(k##state, k##stop_or_error); \ |
| 1270 } |
| 1271 |
| 1272 INSTANTIATE_TEARDOWN_TEST(Stop, Pausing); |
| 1273 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing); |
| 1274 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking); |
| 1275 INSTANTIATE_TEARDOWN_TEST(Stop, Prerolling); |
| 1276 INSTANTIATE_TEARDOWN_TEST(Stop, Starting); |
| 1277 INSTANTIATE_TEARDOWN_TEST(Stop, Playing); |
| 1278 |
| 1279 INSTANTIATE_TEARDOWN_TEST(Error, Pausing); |
| 1280 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); |
| 1281 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); |
| 1282 INSTANTIATE_TEARDOWN_TEST(Error, Prerolling); |
| 1283 INSTANTIATE_TEARDOWN_TEST(Error, Starting); |
| 1284 INSTANTIATE_TEARDOWN_TEST(Error, Playing); |
| 1285 |
| 1056 } // namespace media | 1286 } // namespace media |
| OLD | NEW |