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 "media/base/pipeline.h" | 5 #include "media/base/pipeline_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
15 #include "base/test/simple_test_tick_clock.h" | 15 #include "base/test/simple_test_tick_clock.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 return base::MessageLoop::current()->PostTask( | 65 return base::MessageLoop::current()->PostTask( |
66 FROM_HERE, base::Bind(::std::tr1::get<k>(args), p0)); | 66 FROM_HERE, base::Bind(::std::tr1::get<k>(args), p0)); |
67 } | 67 } |
68 | 68 |
69 // TODO(scherkus): even though some filters are initialized on separate | 69 // TODO(scherkus): even though some filters are initialized on separate |
70 // threads these test aren't flaky... why? It's because filters' Initialize() | 70 // threads these test aren't flaky... why? It's because filters' Initialize() |
71 // is executed on |message_loop_| and the mock filters instantly call | 71 // is executed on |message_loop_| and the mock filters instantly call |
72 // InitializationComplete(), which keeps the pipeline humming along. If | 72 // InitializationComplete(), which keeps the pipeline humming along. If |
73 // either filters don't call InitializationComplete() immediately or filter | 73 // either filters don't call InitializationComplete() immediately or filter |
74 // initialization is moved to a separate thread this test will become flaky. | 74 // initialization is moved to a separate thread this test will become flaky. |
75 class PipelineTest : public ::testing::Test { | 75 class PipelineImplTest : public ::testing::Test { |
76 public: | 76 public: |
77 // Used for setting expectations on pipeline callbacks. Using a StrictMock | 77 // Used for setting expectations on pipeline callbacks. Using a StrictMock |
78 // also lets us test for missing callbacks. | 78 // also lets us test for missing callbacks. |
79 class CallbackHelper { | 79 class CallbackHelper { |
80 public: | 80 public: |
81 CallbackHelper() {} | 81 CallbackHelper() {} |
82 virtual ~CallbackHelper() {} | 82 virtual ~CallbackHelper() {} |
83 | 83 |
84 MOCK_METHOD1(OnStart, void(PipelineStatus)); | 84 MOCK_METHOD1(OnStart, void(PipelineStatus)); |
85 MOCK_METHOD1(OnSeek, void(PipelineStatus)); | 85 MOCK_METHOD1(OnSeek, void(PipelineStatus)); |
86 MOCK_METHOD1(OnSuspend, void(PipelineStatus)); | 86 MOCK_METHOD1(OnSuspend, void(PipelineStatus)); |
87 MOCK_METHOD1(OnResume, void(PipelineStatus)); | 87 MOCK_METHOD1(OnResume, void(PipelineStatus)); |
88 MOCK_METHOD0(OnStop, void()); | 88 MOCK_METHOD0(OnStop, void()); |
89 MOCK_METHOD0(OnEnded, void()); | 89 MOCK_METHOD0(OnEnded, void()); |
90 MOCK_METHOD1(OnError, void(PipelineStatus)); | 90 MOCK_METHOD1(OnError, void(PipelineStatus)); |
91 MOCK_METHOD1(OnMetadata, void(PipelineMetadata)); | 91 MOCK_METHOD1(OnMetadata, void(PipelineMetadata)); |
92 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); | 92 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); |
93 MOCK_METHOD0(OnDurationChange, void()); | 93 MOCK_METHOD0(OnDurationChange, void()); |
94 | 94 |
95 private: | 95 private: |
96 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); | 96 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); |
97 }; | 97 }; |
98 | 98 |
99 PipelineTest() | 99 PipelineImplTest() |
100 : pipeline_(new Pipeline(message_loop_.task_runner(), | 100 : pipeline_( |
101 new MediaLog())), | 101 new PipelineImpl(message_loop_.task_runner(), new MediaLog())), |
102 demuxer_(new StrictMock<MockDemuxer>()), | 102 demuxer_(new StrictMock<MockDemuxer>()), |
103 scoped_renderer_(new StrictMock<MockRenderer>()), | 103 scoped_renderer_(new StrictMock<MockRenderer>()), |
104 renderer_(scoped_renderer_.get()) { | 104 renderer_(scoped_renderer_.get()) { |
105 // SetDemuxerExpectations() adds overriding expectations for expected | 105 // SetDemuxerExpectations() adds overriding expectations for expected |
106 // non-NULL streams. | 106 // non-NULL streams. |
107 DemuxerStream* null_pointer = NULL; | 107 DemuxerStream* null_pointer = NULL; |
108 EXPECT_CALL(*demuxer_, GetStream(_)) | 108 EXPECT_CALL(*demuxer_, GetStream(_)).WillRepeatedly(Return(null_pointer)); |
109 .WillRepeatedly(Return(null_pointer)); | |
110 | 109 |
111 EXPECT_CALL(*demuxer_, GetTimelineOffset()) | 110 EXPECT_CALL(*demuxer_, GetTimelineOffset()) |
112 .WillRepeatedly(Return(base::Time())); | 111 .WillRepeatedly(Return(base::Time())); |
113 | 112 |
114 EXPECT_CALL(*renderer_, GetMediaTime()) | 113 EXPECT_CALL(*renderer_, GetMediaTime()) |
115 .WillRepeatedly(Return(base::TimeDelta())); | 114 .WillRepeatedly(Return(base::TimeDelta())); |
116 | 115 |
117 EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_)); | 116 EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_)); |
118 } | 117 } |
119 | 118 |
120 virtual ~PipelineTest() { | 119 virtual ~PipelineImplTest() { |
121 if (!pipeline_ || !pipeline_->IsRunning()) | 120 if (!pipeline_ || !pipeline_->IsRunning()) |
122 return; | 121 return; |
123 | 122 |
124 ExpectDemuxerStop(); | 123 ExpectDemuxerStop(); |
125 | 124 |
126 // The mock demuxer doesn't stop the fake text track stream, | 125 // The mock demuxer doesn't stop the fake text track stream, |
127 // so just stop it manually. | 126 // so just stop it manually. |
128 if (text_stream_) { | 127 if (text_stream_) { |
129 text_stream_->Stop(); | 128 text_stream_->Stop(); |
130 message_loop_.RunUntilIdle(); | 129 message_loop_.RunUntilIdle(); |
131 } | 130 } |
132 | 131 |
133 // Expect a stop callback if we were started. | 132 // Expect a stop callback if we were started. |
134 ExpectPipelineStopAndDestroyPipeline(); | 133 ExpectPipelineStopAndDestroyPipeline(); |
135 pipeline_->Stop(base::Bind(&CallbackHelper::OnStop, | 134 pipeline_->Stop( |
136 base::Unretained(&callbacks_))); | 135 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
137 message_loop_.RunUntilIdle(); | 136 message_loop_.RunUntilIdle(); |
138 } | 137 } |
139 | 138 |
140 void OnDemuxerError() { | 139 void OnDemuxerError() { |
141 // Cast because OnDemuxerError is private in Pipeline. | 140 // Cast because OnDemuxerError is private in Pipeline. |
142 static_cast<DemuxerHost*>(pipeline_.get()) | 141 static_cast<DemuxerHost*>(pipeline_.get()) |
143 ->OnDemuxerError(PIPELINE_ERROR_ABORT); | 142 ->OnDemuxerError(PIPELINE_ERROR_ABORT); |
144 } | 143 } |
145 | 144 |
146 protected: | 145 protected: |
(...skipping 12 matching lines...) Expand all Loading... |
159 EXPECT_CALL(*demuxer_, GetStream(stream->type())) | 158 EXPECT_CALL(*demuxer_, GetStream(stream->type())) |
160 .WillRepeatedly(Return(stream)); | 159 .WillRepeatedly(Return(stream)); |
161 } | 160 } |
162 } | 161 } |
163 | 162 |
164 void SetDemuxerExpectations(MockDemuxerStreamVector* streams) { | 163 void SetDemuxerExpectations(MockDemuxerStreamVector* streams) { |
165 // Initialize with a default non-zero duration. | 164 // Initialize with a default non-zero duration. |
166 SetDemuxerExpectations(streams, base::TimeDelta::FromSeconds(10)); | 165 SetDemuxerExpectations(streams, base::TimeDelta::FromSeconds(10)); |
167 } | 166 } |
168 | 167 |
169 scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream( | 168 scoped_ptr<StrictMock<MockDemuxerStream>> CreateStream( |
170 DemuxerStream::Type type) { | 169 DemuxerStream::Type type) { |
171 scoped_ptr<StrictMock<MockDemuxerStream> > stream( | 170 scoped_ptr<StrictMock<MockDemuxerStream>> stream( |
172 new StrictMock<MockDemuxerStream>(type)); | 171 new StrictMock<MockDemuxerStream>(type)); |
173 return stream; | 172 return stream; |
174 } | 173 } |
175 | 174 |
176 // Sets up expectations to allow the video renderer to initialize. | 175 // Sets up expectations to allow the video renderer to initialize. |
177 void SetRendererExpectations() { | 176 void SetRendererExpectations() { |
178 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 177 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
179 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), | 178 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), |
180 SaveArg<4>(&ended_cb_), | 179 SaveArg<4>(&ended_cb_), PostCallback<1>(PIPELINE_OK))); |
181 PostCallback<1>(PIPELINE_OK))); | |
182 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); | 180 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); |
183 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); | 181 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); |
184 } | 182 } |
185 | 183 |
186 void AddTextStream() { | 184 void AddTextStream() { |
187 EXPECT_CALL(*this, OnAddTextTrack(_,_)) | 185 EXPECT_CALL(*this, OnAddTextTrack(_, _)) |
188 .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack)); | 186 .WillOnce(Invoke(this, &PipelineImplTest::DoOnAddTextTrack)); |
189 static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(), | 187 static_cast<DemuxerHost*>(pipeline_.get()) |
190 TextTrackConfig(kTextSubtitles, "", "", "")); | 188 ->AddTextStream(text_stream(), |
| 189 TextTrackConfig(kTextSubtitles, "", "", "")); |
191 message_loop_.RunUntilIdle(); | 190 message_loop_.RunUntilIdle(); |
192 } | 191 } |
193 | 192 |
194 void StartPipeline() { | 193 void StartPipeline() { |
195 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); | 194 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); |
196 pipeline_->Start( | 195 pipeline_->Start( |
197 demuxer_.get(), std::move(scoped_renderer_), | 196 demuxer_.get(), std::move(scoped_renderer_), |
198 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), | 197 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), |
199 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), | 198 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), |
200 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)), | 199 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)), |
201 base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)), | 200 base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)), |
202 base::Bind(&CallbackHelper::OnBufferingStateChange, | 201 base::Bind(&CallbackHelper::OnBufferingStateChange, |
203 base::Unretained(&callbacks_)), | 202 base::Unretained(&callbacks_)), |
204 base::Bind(&CallbackHelper::OnDurationChange, | 203 base::Bind(&CallbackHelper::OnDurationChange, |
205 base::Unretained(&callbacks_)), | 204 base::Unretained(&callbacks_)), |
206 base::Bind(&PipelineTest::OnAddTextTrack, base::Unretained(this)), | 205 base::Bind(&PipelineImplTest::OnAddTextTrack, base::Unretained(this)), |
207 base::Bind(&PipelineTest::OnWaitingForDecryptionKey, | 206 base::Bind(&PipelineImplTest::OnWaitingForDecryptionKey, |
208 base::Unretained(this))); | 207 base::Unretained(this))); |
209 } | 208 } |
210 | 209 |
211 // Sets up expectations on the callback and initializes the pipeline. Called | 210 // Sets up expectations on the callback and initializes the pipeline. Called |
212 // after tests have set expectations any filters they wish to use. | 211 // after tests have set expectations any filters they wish to use. |
213 void StartPipelineAndExpect(PipelineStatus start_status) { | 212 void StartPipelineAndExpect(PipelineStatus start_status) { |
214 EXPECT_CALL(callbacks_, OnStart(start_status)); | 213 EXPECT_CALL(callbacks_, OnStart(start_status)); |
215 | 214 |
216 if (start_status == PIPELINE_OK) { | 215 if (start_status == PIPELINE_OK) { |
217 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); | 216 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); |
218 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); | 217 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); |
219 EXPECT_CALL(*renderer_, SetVolume(1.0f)); | 218 EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
220 EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_)) | 219 EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_)) |
221 .WillOnce(SetBufferingState(&buffering_state_cb_, | 220 .WillOnce( |
222 BUFFERING_HAVE_ENOUGH)); | 221 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); |
223 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 222 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
224 } | 223 } |
225 | 224 |
226 StartPipeline(); | 225 StartPipeline(); |
227 message_loop_.RunUntilIdle(); | 226 message_loop_.RunUntilIdle(); |
228 } | 227 } |
229 | 228 |
230 void CreateAudioStream() { | 229 void CreateAudioStream() { |
231 audio_stream_ = CreateStream(DemuxerStream::AUDIO); | 230 audio_stream_ = CreateStream(DemuxerStream::AUDIO); |
232 } | 231 } |
233 | 232 |
234 void CreateVideoStream() { | 233 void CreateVideoStream() { |
235 video_stream_ = CreateStream(DemuxerStream::VIDEO); | 234 video_stream_ = CreateStream(DemuxerStream::VIDEO); |
236 video_stream_->set_video_decoder_config(video_decoder_config_); | 235 video_stream_->set_video_decoder_config(video_decoder_config_); |
237 } | 236 } |
238 | 237 |
239 void CreateTextStream() { | 238 void CreateTextStream() { |
240 scoped_ptr<FakeTextTrackStream> text_stream(new FakeTextTrackStream()); | 239 scoped_ptr<FakeTextTrackStream> text_stream(new FakeTextTrackStream()); |
241 EXPECT_CALL(*text_stream, OnRead()).Times(AnyNumber()); | 240 EXPECT_CALL(*text_stream, OnRead()).Times(AnyNumber()); |
242 text_stream_ = std::move(text_stream); | 241 text_stream_ = std::move(text_stream); |
243 } | 242 } |
244 | 243 |
245 MockDemuxerStream* audio_stream() { | 244 MockDemuxerStream* audio_stream() { return audio_stream_.get(); } |
246 return audio_stream_.get(); | |
247 } | |
248 | 245 |
249 MockDemuxerStream* video_stream() { | 246 MockDemuxerStream* video_stream() { return video_stream_.get(); } |
250 return video_stream_.get(); | |
251 } | |
252 | 247 |
253 FakeTextTrackStream* text_stream() { | 248 FakeTextTrackStream* text_stream() { return text_stream_.get(); } |
254 return text_stream_.get(); | |
255 } | |
256 | 249 |
257 void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) { | 250 void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) { |
258 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 251 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
259 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 252 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
260 | 253 |
261 EXPECT_CALL(*renderer_, Flush(_)) | 254 EXPECT_CALL(*renderer_, Flush(_)) |
262 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, | 255 .WillOnce(DoAll( |
263 BUFFERING_HAVE_NOTHING), | 256 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
264 RunClosure<0>())); | 257 RunClosure<0>())); |
265 EXPECT_CALL(*renderer_, SetPlaybackRate(_)); | 258 EXPECT_CALL(*renderer_, SetPlaybackRate(_)); |
266 EXPECT_CALL(*renderer_, SetVolume(_)); | 259 EXPECT_CALL(*renderer_, SetVolume(_)); |
267 EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) | 260 EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) |
268 .WillOnce(SetBufferingState(&buffering_state_cb_, | 261 .WillOnce( |
269 BUFFERING_HAVE_ENOUGH)); | 262 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); |
270 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 263 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
271 | 264 |
272 // We expect a successful seek callback followed by a buffering update. | 265 // We expect a successful seek callback followed by a buffering update. |
273 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); | 266 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
274 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 267 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
275 } | 268 } |
276 | 269 |
277 void DoSeek(const base::TimeDelta& seek_time) { | 270 void DoSeek(const base::TimeDelta& seek_time) { |
278 pipeline_->Seek(seek_time, | 271 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
279 base::Bind(&CallbackHelper::OnSeek, | 272 base::Unretained(&callbacks_))); |
280 base::Unretained(&callbacks_))); | |
281 message_loop_.RunUntilIdle(); | 273 message_loop_.RunUntilIdle(); |
282 } | 274 } |
283 | 275 |
284 void ExpectSuspend() { | 276 void ExpectSuspend() { |
285 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); | 277 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); |
286 EXPECT_CALL(*renderer_, Flush(_)) | 278 EXPECT_CALL(*renderer_, Flush(_)) |
287 .WillOnce(DoAll( | 279 .WillOnce(DoAll( |
288 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 280 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
289 RunClosure<0>())); | 281 RunClosure<0>())); |
290 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 282 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 | 322 |
331 void ExpectDemuxerStop() { | 323 void ExpectDemuxerStop() { |
332 if (demuxer_) | 324 if (demuxer_) |
333 EXPECT_CALL(*demuxer_, Stop()); | 325 EXPECT_CALL(*demuxer_, Stop()); |
334 } | 326 } |
335 | 327 |
336 void ExpectPipelineStopAndDestroyPipeline() { | 328 void ExpectPipelineStopAndDestroyPipeline() { |
337 // After the Pipeline is stopped, it could be destroyed any time. Always | 329 // After the Pipeline is stopped, it could be destroyed any time. Always |
338 // destroy the pipeline immediately after OnStop() to test this. | 330 // destroy the pipeline immediately after OnStop() to test this. |
339 EXPECT_CALL(callbacks_, OnStop()) | 331 EXPECT_CALL(callbacks_, OnStop()) |
340 .WillOnce(Invoke(this, &PipelineTest::DestroyPipeline)); | 332 .WillOnce(Invoke(this, &PipelineImplTest::DestroyPipeline)); |
341 } | 333 } |
342 | 334 |
343 MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&, | 335 MOCK_METHOD2(OnAddTextTrack, |
344 const AddTextTrackDoneCB&)); | 336 void(const TextTrackConfig&, const AddTextTrackDoneCB&)); |
345 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); | 337 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); |
346 | 338 |
347 void DoOnAddTextTrack(const TextTrackConfig& config, | 339 void DoOnAddTextTrack(const TextTrackConfig& config, |
348 const AddTextTrackDoneCB& done_cb) { | 340 const AddTextTrackDoneCB& done_cb) { |
349 scoped_ptr<TextTrack> text_track(new MockTextTrack); | 341 scoped_ptr<TextTrack> text_track(new MockTextTrack); |
350 done_cb.Run(std::move(text_track)); | 342 done_cb.Run(std::move(text_track)); |
351 } | 343 } |
352 | 344 |
353 // Fixture members. | 345 // Fixture members. |
354 StrictMock<CallbackHelper> callbacks_; | 346 StrictMock<CallbackHelper> callbacks_; |
355 base::SimpleTestTickClock test_tick_clock_; | 347 base::SimpleTestTickClock test_tick_clock_; |
356 base::MessageLoop message_loop_; | 348 base::MessageLoop message_loop_; |
357 scoped_ptr<Pipeline> pipeline_; | 349 scoped_ptr<PipelineImpl> pipeline_; |
358 | 350 |
359 scoped_ptr<StrictMock<MockDemuxer> > demuxer_; | 351 scoped_ptr<StrictMock<MockDemuxer>> demuxer_; |
360 scoped_ptr<StrictMock<MockRenderer> > scoped_renderer_; | 352 scoped_ptr<StrictMock<MockRenderer>> scoped_renderer_; |
361 StrictMock<MockRenderer>* renderer_; | 353 StrictMock<MockRenderer>* renderer_; |
362 StrictMock<CallbackHelper> text_renderer_callbacks_; | 354 StrictMock<CallbackHelper> text_renderer_callbacks_; |
363 TextRenderer* text_renderer_; | 355 TextRenderer* text_renderer_; |
364 scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_; | 356 scoped_ptr<StrictMock<MockDemuxerStream>> audio_stream_; |
365 scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_; | 357 scoped_ptr<StrictMock<MockDemuxerStream>> video_stream_; |
366 scoped_ptr<FakeTextTrackStream> text_stream_; | 358 scoped_ptr<FakeTextTrackStream> text_stream_; |
367 BufferingStateCB buffering_state_cb_; | 359 BufferingStateCB buffering_state_cb_; |
368 base::Closure ended_cb_; | 360 base::Closure ended_cb_; |
369 VideoDecoderConfig video_decoder_config_; | 361 VideoDecoderConfig video_decoder_config_; |
370 PipelineMetadata metadata_; | 362 PipelineMetadata metadata_; |
371 base::TimeDelta start_time_; | 363 base::TimeDelta start_time_; |
372 | 364 |
373 private: | 365 private: |
374 DISALLOW_COPY_AND_ASSIGN(PipelineTest); | 366 DISALLOW_COPY_AND_ASSIGN(PipelineImplTest); |
375 }; | 367 }; |
376 | 368 |
377 // Test that playback controls methods no-op when the pipeline hasn't been | 369 // Test that playback controls methods no-op when the pipeline hasn't been |
378 // started. | 370 // started. |
379 TEST_F(PipelineTest, NotStarted) { | 371 TEST_F(PipelineImplTest, NotStarted) { |
380 const base::TimeDelta kZero; | 372 const base::TimeDelta kZero; |
381 | 373 |
382 EXPECT_FALSE(pipeline_->IsRunning()); | 374 EXPECT_FALSE(pipeline_->IsRunning()); |
383 | 375 |
384 // Setting should still work. | 376 // Setting should still work. |
385 EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate()); | 377 EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate()); |
386 pipeline_->SetPlaybackRate(-1.0); | 378 pipeline_->SetPlaybackRate(-1.0); |
387 EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate()); | 379 EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate()); |
388 pipeline_->SetPlaybackRate(1.0); | 380 pipeline_->SetPlaybackRate(1.0); |
389 EXPECT_EQ(1.0f, pipeline_->GetPlaybackRate()); | 381 EXPECT_EQ(1.0f, pipeline_->GetPlaybackRate()); |
390 | 382 |
391 // Setting should still work. | 383 // Setting should still work. |
392 EXPECT_EQ(1.0f, pipeline_->GetVolume()); | 384 EXPECT_EQ(1.0f, pipeline_->GetVolume()); |
393 pipeline_->SetVolume(-1.0f); | 385 pipeline_->SetVolume(-1.0f); |
394 EXPECT_EQ(1.0f, pipeline_->GetVolume()); | 386 EXPECT_EQ(1.0f, pipeline_->GetVolume()); |
395 pipeline_->SetVolume(0.0f); | 387 pipeline_->SetVolume(0.0f); |
396 EXPECT_EQ(0.0f, pipeline_->GetVolume()); | 388 EXPECT_EQ(0.0f, pipeline_->GetVolume()); |
397 | 389 |
398 EXPECT_TRUE(kZero == pipeline_->GetMediaTime()); | 390 EXPECT_TRUE(kZero == pipeline_->GetMediaTime()); |
399 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); | 391 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); |
400 EXPECT_TRUE(kZero == pipeline_->GetMediaDuration()); | 392 EXPECT_TRUE(kZero == pipeline_->GetMediaDuration()); |
401 } | 393 } |
402 | 394 |
403 TEST_F(PipelineTest, NeverInitializes) { | 395 TEST_F(PipelineImplTest, NeverInitializes) { |
404 // Don't execute the callback passed into Initialize(). | 396 // Don't execute the callback passed into Initialize(). |
405 EXPECT_CALL(*demuxer_, Initialize(_, _, _)); | 397 EXPECT_CALL(*demuxer_, Initialize(_, _, _)); |
406 | 398 |
407 // This test hangs during initialization by never calling | 399 // This test hangs during initialization by never calling |
408 // InitializationComplete(). StrictMock<> will ensure that the callback is | 400 // InitializationComplete(). StrictMock<> will ensure that the callback is |
409 // never executed. | 401 // never executed. |
410 StartPipeline(); | 402 StartPipeline(); |
411 message_loop_.RunUntilIdle(); | 403 message_loop_.RunUntilIdle(); |
412 | 404 |
413 // Because our callback will get executed when the test tears down, we'll | 405 // Because our callback will get executed when the test tears down, we'll |
414 // verify that nothing has been called, then set our expectation for the call | 406 // verify that nothing has been called, then set our expectation for the call |
415 // made during tear down. | 407 // made during tear down. |
416 Mock::VerifyAndClear(&callbacks_); | 408 Mock::VerifyAndClear(&callbacks_); |
417 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); | 409 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); |
418 } | 410 } |
419 | 411 |
420 TEST_F(PipelineTest, StopWithoutStart) { | 412 TEST_F(PipelineImplTest, StopWithoutStart) { |
421 ExpectPipelineStopAndDestroyPipeline(); | 413 ExpectPipelineStopAndDestroyPipeline(); |
422 pipeline_->Stop( | 414 pipeline_->Stop( |
423 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 415 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
424 message_loop_.RunUntilIdle(); | 416 message_loop_.RunUntilIdle(); |
425 } | 417 } |
426 | 418 |
427 TEST_F(PipelineTest, StartThenStopImmediately) { | 419 TEST_F(PipelineImplTest, StartThenStopImmediately) { |
428 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 420 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
429 .WillOnce(PostCallback<1>(PIPELINE_OK)); | 421 .WillOnce(PostCallback<1>(PIPELINE_OK)); |
430 EXPECT_CALL(*demuxer_, Stop()); | 422 EXPECT_CALL(*demuxer_, Stop()); |
431 | 423 |
432 EXPECT_CALL(callbacks_, OnStart(_)); | 424 EXPECT_CALL(callbacks_, OnStart(_)); |
433 StartPipeline(); | 425 StartPipeline(); |
434 | 426 |
435 // Expect a stop callback if we were started. | 427 // Expect a stop callback if we were started. |
436 ExpectPipelineStopAndDestroyPipeline(); | 428 ExpectPipelineStopAndDestroyPipeline(); |
437 pipeline_->Stop( | 429 pipeline_->Stop( |
438 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 430 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
439 message_loop_.RunUntilIdle(); | 431 message_loop_.RunUntilIdle(); |
440 } | 432 } |
441 | 433 |
442 TEST_F(PipelineTest, DemuxerErrorDuringStop) { | 434 TEST_F(PipelineImplTest, DemuxerErrorDuringStop) { |
443 CreateAudioStream(); | 435 CreateAudioStream(); |
444 MockDemuxerStreamVector streams; | 436 MockDemuxerStreamVector streams; |
445 streams.push_back(audio_stream()); | 437 streams.push_back(audio_stream()); |
446 | 438 |
447 SetDemuxerExpectations(&streams); | 439 SetDemuxerExpectations(&streams); |
448 SetRendererExpectations(); | 440 SetRendererExpectations(); |
449 | 441 |
450 StartPipelineAndExpect(PIPELINE_OK); | 442 StartPipelineAndExpect(PIPELINE_OK); |
451 | 443 |
452 EXPECT_CALL(*demuxer_, Stop()) | 444 EXPECT_CALL(*demuxer_, Stop()) |
453 .WillOnce(InvokeWithoutArgs(this, &PipelineTest::OnDemuxerError)); | 445 .WillOnce(InvokeWithoutArgs(this, &PipelineImplTest::OnDemuxerError)); |
454 ExpectPipelineStopAndDestroyPipeline(); | 446 ExpectPipelineStopAndDestroyPipeline(); |
455 | 447 |
456 pipeline_->Stop( | 448 pipeline_->Stop( |
457 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 449 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
458 message_loop_.RunUntilIdle(); | 450 message_loop_.RunUntilIdle(); |
459 } | 451 } |
460 | 452 |
461 TEST_F(PipelineTest, URLNotFound) { | 453 TEST_F(PipelineImplTest, URLNotFound) { |
462 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 454 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
463 .WillOnce(PostCallback<1>(PIPELINE_ERROR_URL_NOT_FOUND)); | 455 .WillOnce(PostCallback<1>(PIPELINE_ERROR_URL_NOT_FOUND)); |
464 EXPECT_CALL(*demuxer_, Stop()); | 456 EXPECT_CALL(*demuxer_, Stop()); |
465 | 457 |
466 StartPipelineAndExpect(PIPELINE_ERROR_URL_NOT_FOUND); | 458 StartPipelineAndExpect(PIPELINE_ERROR_URL_NOT_FOUND); |
467 } | 459 } |
468 | 460 |
469 TEST_F(PipelineTest, NoStreams) { | 461 TEST_F(PipelineImplTest, NoStreams) { |
470 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 462 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
471 .WillOnce(PostCallback<1>(PIPELINE_OK)); | 463 .WillOnce(PostCallback<1>(PIPELINE_OK)); |
472 EXPECT_CALL(*demuxer_, Stop()); | 464 EXPECT_CALL(*demuxer_, Stop()); |
473 EXPECT_CALL(callbacks_, OnMetadata(_)); | 465 EXPECT_CALL(callbacks_, OnMetadata(_)); |
474 | 466 |
475 StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER); | 467 StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER); |
476 } | 468 } |
477 | 469 |
478 TEST_F(PipelineTest, AudioStream) { | 470 TEST_F(PipelineImplTest, AudioStream) { |
479 CreateAudioStream(); | 471 CreateAudioStream(); |
480 MockDemuxerStreamVector streams; | 472 MockDemuxerStreamVector streams; |
481 streams.push_back(audio_stream()); | 473 streams.push_back(audio_stream()); |
482 | 474 |
483 SetDemuxerExpectations(&streams); | 475 SetDemuxerExpectations(&streams); |
484 SetRendererExpectations(); | 476 SetRendererExpectations(); |
485 | 477 |
486 StartPipelineAndExpect(PIPELINE_OK); | 478 StartPipelineAndExpect(PIPELINE_OK); |
487 EXPECT_TRUE(metadata_.has_audio); | 479 EXPECT_TRUE(metadata_.has_audio); |
488 EXPECT_FALSE(metadata_.has_video); | 480 EXPECT_FALSE(metadata_.has_video); |
489 } | 481 } |
490 | 482 |
491 TEST_F(PipelineTest, VideoStream) { | 483 TEST_F(PipelineImplTest, VideoStream) { |
492 CreateVideoStream(); | 484 CreateVideoStream(); |
493 MockDemuxerStreamVector streams; | 485 MockDemuxerStreamVector streams; |
494 streams.push_back(video_stream()); | 486 streams.push_back(video_stream()); |
495 | 487 |
496 SetDemuxerExpectations(&streams); | 488 SetDemuxerExpectations(&streams); |
497 SetRendererExpectations(); | 489 SetRendererExpectations(); |
498 | 490 |
499 StartPipelineAndExpect(PIPELINE_OK); | 491 StartPipelineAndExpect(PIPELINE_OK); |
500 EXPECT_FALSE(metadata_.has_audio); | 492 EXPECT_FALSE(metadata_.has_audio); |
501 EXPECT_TRUE(metadata_.has_video); | 493 EXPECT_TRUE(metadata_.has_video); |
502 } | 494 } |
503 | 495 |
504 TEST_F(PipelineTest, AudioVideoStream) { | 496 TEST_F(PipelineImplTest, AudioVideoStream) { |
505 CreateAudioStream(); | 497 CreateAudioStream(); |
506 CreateVideoStream(); | 498 CreateVideoStream(); |
507 MockDemuxerStreamVector streams; | 499 MockDemuxerStreamVector streams; |
508 streams.push_back(audio_stream()); | 500 streams.push_back(audio_stream()); |
509 streams.push_back(video_stream()); | 501 streams.push_back(video_stream()); |
510 | 502 |
511 SetDemuxerExpectations(&streams); | 503 SetDemuxerExpectations(&streams); |
512 SetRendererExpectations(); | 504 SetRendererExpectations(); |
513 | 505 |
514 StartPipelineAndExpect(PIPELINE_OK); | 506 StartPipelineAndExpect(PIPELINE_OK); |
515 EXPECT_TRUE(metadata_.has_audio); | 507 EXPECT_TRUE(metadata_.has_audio); |
516 EXPECT_TRUE(metadata_.has_video); | 508 EXPECT_TRUE(metadata_.has_video); |
517 } | 509 } |
518 | 510 |
519 TEST_F(PipelineTest, VideoTextStream) { | 511 TEST_F(PipelineImplTest, VideoTextStream) { |
520 CreateVideoStream(); | 512 CreateVideoStream(); |
521 CreateTextStream(); | 513 CreateTextStream(); |
522 MockDemuxerStreamVector streams; | 514 MockDemuxerStreamVector streams; |
523 streams.push_back(video_stream()); | 515 streams.push_back(video_stream()); |
524 | 516 |
525 SetDemuxerExpectations(&streams); | 517 SetDemuxerExpectations(&streams); |
526 SetRendererExpectations(); | 518 SetRendererExpectations(); |
527 | 519 |
528 StartPipelineAndExpect(PIPELINE_OK); | 520 StartPipelineAndExpect(PIPELINE_OK); |
529 EXPECT_FALSE(metadata_.has_audio); | 521 EXPECT_FALSE(metadata_.has_audio); |
530 EXPECT_TRUE(metadata_.has_video); | 522 EXPECT_TRUE(metadata_.has_video); |
531 | 523 |
532 AddTextStream(); | 524 AddTextStream(); |
533 } | 525 } |
534 | 526 |
535 TEST_F(PipelineTest, VideoAudioTextStream) { | 527 TEST_F(PipelineImplTest, VideoAudioTextStream) { |
536 CreateVideoStream(); | 528 CreateVideoStream(); |
537 CreateAudioStream(); | 529 CreateAudioStream(); |
538 CreateTextStream(); | 530 CreateTextStream(); |
539 MockDemuxerStreamVector streams; | 531 MockDemuxerStreamVector streams; |
540 streams.push_back(video_stream()); | 532 streams.push_back(video_stream()); |
541 streams.push_back(audio_stream()); | 533 streams.push_back(audio_stream()); |
542 | 534 |
543 SetDemuxerExpectations(&streams); | 535 SetDemuxerExpectations(&streams); |
544 SetRendererExpectations(); | 536 SetRendererExpectations(); |
545 | 537 |
546 StartPipelineAndExpect(PIPELINE_OK); | 538 StartPipelineAndExpect(PIPELINE_OK); |
547 EXPECT_TRUE(metadata_.has_audio); | 539 EXPECT_TRUE(metadata_.has_audio); |
548 EXPECT_TRUE(metadata_.has_video); | 540 EXPECT_TRUE(metadata_.has_video); |
549 | 541 |
550 AddTextStream(); | 542 AddTextStream(); |
551 } | 543 } |
552 | 544 |
553 TEST_F(PipelineTest, Seek) { | 545 TEST_F(PipelineImplTest, Seek) { |
554 CreateAudioStream(); | 546 CreateAudioStream(); |
555 CreateVideoStream(); | 547 CreateVideoStream(); |
556 CreateTextStream(); | 548 CreateTextStream(); |
557 MockDemuxerStreamVector streams; | 549 MockDemuxerStreamVector streams; |
558 streams.push_back(audio_stream()); | 550 streams.push_back(audio_stream()); |
559 streams.push_back(video_stream()); | 551 streams.push_back(video_stream()); |
560 | 552 |
561 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); | 553 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
562 SetRendererExpectations(); | 554 SetRendererExpectations(); |
563 | 555 |
564 // Initialize then seek! | 556 // Initialize then seek! |
565 StartPipelineAndExpect(PIPELINE_OK); | 557 StartPipelineAndExpect(PIPELINE_OK); |
566 | 558 |
567 // Every filter should receive a call to Seek(). | 559 // Every filter should receive a call to Seek(). |
568 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); | 560 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); |
569 ExpectSeek(expected, false); | 561 ExpectSeek(expected, false); |
570 DoSeek(expected); | 562 DoSeek(expected); |
571 } | 563 } |
572 | 564 |
573 TEST_F(PipelineTest, SeekAfterError) { | 565 TEST_F(PipelineImplTest, SeekAfterError) { |
574 CreateAudioStream(); | 566 CreateAudioStream(); |
575 MockDemuxerStreamVector streams; | 567 MockDemuxerStreamVector streams; |
576 streams.push_back(audio_stream()); | 568 streams.push_back(audio_stream()); |
577 | 569 |
578 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); | 570 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
579 SetRendererExpectations(); | 571 SetRendererExpectations(); |
580 | 572 |
581 // Initialize then seek! | 573 // Initialize then seek! |
582 StartPipelineAndExpect(PIPELINE_OK); | 574 StartPipelineAndExpect(PIPELINE_OK); |
583 | 575 |
584 EXPECT_CALL(*demuxer_, Stop()); | 576 EXPECT_CALL(*demuxer_, Stop()); |
585 EXPECT_CALL(callbacks_, OnError(_)); | 577 EXPECT_CALL(callbacks_, OnError(_)); |
586 | 578 |
587 static_cast<DemuxerHost*>(pipeline_.get()) | 579 static_cast<DemuxerHost*>(pipeline_.get()) |
588 ->OnDemuxerError(PIPELINE_ERROR_ABORT); | 580 ->OnDemuxerError(PIPELINE_ERROR_ABORT); |
589 message_loop_.RunUntilIdle(); | 581 message_loop_.RunUntilIdle(); |
590 | 582 |
591 pipeline_->Seek( | 583 pipeline_->Seek( |
592 base::TimeDelta::FromMilliseconds(100), | 584 base::TimeDelta::FromMilliseconds(100), |
593 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); | 585 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); |
594 message_loop_.RunUntilIdle(); | 586 message_loop_.RunUntilIdle(); |
595 } | 587 } |
596 | 588 |
597 TEST_F(PipelineTest, SuspendResume) { | 589 TEST_F(PipelineImplTest, SuspendResume) { |
598 CreateAudioStream(); | 590 CreateAudioStream(); |
599 CreateVideoStream(); | 591 CreateVideoStream(); |
600 CreateTextStream(); | 592 CreateTextStream(); |
601 MockDemuxerStreamVector streams; | 593 MockDemuxerStreamVector streams; |
602 streams.push_back(audio_stream()); | 594 streams.push_back(audio_stream()); |
603 streams.push_back(video_stream()); | 595 streams.push_back(video_stream()); |
604 | 596 |
605 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); | 597 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
606 SetRendererExpectations(); | 598 SetRendererExpectations(); |
607 | 599 |
608 StartPipelineAndExpect(PIPELINE_OK); | 600 StartPipelineAndExpect(PIPELINE_OK); |
609 | 601 |
610 ExpectSuspend(); | 602 ExpectSuspend(); |
611 DoSuspend(); | 603 DoSuspend(); |
612 | 604 |
613 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); | 605 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); |
614 ExpectResume(expected); | 606 ExpectResume(expected); |
615 DoResume(expected); | 607 DoResume(expected); |
616 } | 608 } |
617 | 609 |
618 TEST_F(PipelineTest, SetVolume) { | 610 TEST_F(PipelineImplTest, SetVolume) { |
619 CreateAudioStream(); | 611 CreateAudioStream(); |
620 MockDemuxerStreamVector streams; | 612 MockDemuxerStreamVector streams; |
621 streams.push_back(audio_stream()); | 613 streams.push_back(audio_stream()); |
622 | 614 |
623 SetDemuxerExpectations(&streams); | 615 SetDemuxerExpectations(&streams); |
624 SetRendererExpectations(); | 616 SetRendererExpectations(); |
625 | 617 |
626 // The audio renderer should receive a call to SetVolume(). | 618 // The audio renderer should receive a call to SetVolume(). |
627 float expected = 0.5f; | 619 float expected = 0.5f; |
628 EXPECT_CALL(*renderer_, SetVolume(expected)); | 620 EXPECT_CALL(*renderer_, SetVolume(expected)); |
629 | 621 |
630 // Initialize then set volume! | 622 // Initialize then set volume! |
631 StartPipelineAndExpect(PIPELINE_OK); | 623 StartPipelineAndExpect(PIPELINE_OK); |
632 pipeline_->SetVolume(expected); | 624 pipeline_->SetVolume(expected); |
633 } | 625 } |
634 | 626 |
635 TEST_F(PipelineTest, Properties) { | 627 TEST_F(PipelineImplTest, Properties) { |
636 CreateVideoStream(); | 628 CreateVideoStream(); |
637 MockDemuxerStreamVector streams; | 629 MockDemuxerStreamVector streams; |
638 streams.push_back(video_stream()); | 630 streams.push_back(video_stream()); |
639 | 631 |
640 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); | 632 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
641 SetDemuxerExpectations(&streams, kDuration); | 633 SetDemuxerExpectations(&streams, kDuration); |
642 SetRendererExpectations(); | 634 SetRendererExpectations(); |
643 | 635 |
644 StartPipelineAndExpect(PIPELINE_OK); | 636 StartPipelineAndExpect(PIPELINE_OK); |
645 EXPECT_EQ(kDuration.ToInternalValue(), | 637 EXPECT_EQ(kDuration.ToInternalValue(), |
646 pipeline_->GetMediaDuration().ToInternalValue()); | 638 pipeline_->GetMediaDuration().ToInternalValue()); |
647 EXPECT_FALSE(pipeline_->DidLoadingProgress()); | 639 EXPECT_FALSE(pipeline_->DidLoadingProgress()); |
648 } | 640 } |
649 | 641 |
650 TEST_F(PipelineTest, GetBufferedTimeRanges) { | 642 TEST_F(PipelineImplTest, GetBufferedTimeRanges) { |
651 CreateVideoStream(); | 643 CreateVideoStream(); |
652 MockDemuxerStreamVector streams; | 644 MockDemuxerStreamVector streams; |
653 streams.push_back(video_stream()); | 645 streams.push_back(video_stream()); |
654 | 646 |
655 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); | 647 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
656 SetDemuxerExpectations(&streams, kDuration); | 648 SetDemuxerExpectations(&streams, kDuration); |
657 SetRendererExpectations(); | 649 SetRendererExpectations(); |
658 | 650 |
659 StartPipelineAndExpect(PIPELINE_OK); | 651 StartPipelineAndExpect(PIPELINE_OK); |
660 | 652 |
661 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); | 653 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); |
662 | 654 |
663 EXPECT_FALSE(pipeline_->DidLoadingProgress()); | 655 EXPECT_FALSE(pipeline_->DidLoadingProgress()); |
664 Ranges<base::TimeDelta> ranges; | 656 Ranges<base::TimeDelta> ranges; |
665 ranges.Add(base::TimeDelta(), kDuration / 8); | 657 ranges.Add(base::TimeDelta(), kDuration / 8); |
666 pipeline_->OnBufferedTimeRangesChanged(ranges); | 658 pipeline_->OnBufferedTimeRangesChanged(ranges); |
667 EXPECT_TRUE(pipeline_->DidLoadingProgress()); | 659 EXPECT_TRUE(pipeline_->DidLoadingProgress()); |
668 EXPECT_FALSE(pipeline_->DidLoadingProgress()); | 660 EXPECT_FALSE(pipeline_->DidLoadingProgress()); |
669 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); | 661 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); |
670 EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0)); | 662 EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0)); |
671 EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0)); | 663 EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0)); |
672 | 664 |
673 base::TimeDelta kSeekTime = kDuration / 2; | 665 base::TimeDelta kSeekTime = kDuration / 2; |
674 ExpectSeek(kSeekTime, false); | 666 ExpectSeek(kSeekTime, false); |
675 DoSeek(kSeekTime); | 667 DoSeek(kSeekTime); |
676 | 668 |
677 EXPECT_FALSE(pipeline_->DidLoadingProgress()); | 669 EXPECT_FALSE(pipeline_->DidLoadingProgress()); |
678 } | 670 } |
679 | 671 |
680 TEST_F(PipelineTest, EndedCallback) { | 672 TEST_F(PipelineImplTest, EndedCallback) { |
681 CreateAudioStream(); | 673 CreateAudioStream(); |
682 CreateVideoStream(); | 674 CreateVideoStream(); |
683 CreateTextStream(); | 675 CreateTextStream(); |
684 MockDemuxerStreamVector streams; | 676 MockDemuxerStreamVector streams; |
685 streams.push_back(audio_stream()); | 677 streams.push_back(audio_stream()); |
686 streams.push_back(video_stream()); | 678 streams.push_back(video_stream()); |
687 | 679 |
688 SetDemuxerExpectations(&streams); | 680 SetDemuxerExpectations(&streams); |
689 SetRendererExpectations(); | 681 SetRendererExpectations(); |
690 StartPipelineAndExpect(PIPELINE_OK); | 682 StartPipelineAndExpect(PIPELINE_OK); |
691 | 683 |
692 AddTextStream(); | 684 AddTextStream(); |
693 | 685 |
694 // The ended callback shouldn't run until all renderers have ended. | 686 // The ended callback shouldn't run until all renderers have ended. |
695 ended_cb_.Run(); | 687 ended_cb_.Run(); |
696 message_loop_.RunUntilIdle(); | 688 message_loop_.RunUntilIdle(); |
697 | 689 |
698 EXPECT_CALL(callbacks_, OnEnded()); | 690 EXPECT_CALL(callbacks_, OnEnded()); |
699 text_stream()->SendEosNotification(); | 691 text_stream()->SendEosNotification(); |
700 message_loop_.RunUntilIdle(); | 692 message_loop_.RunUntilIdle(); |
701 } | 693 } |
702 | 694 |
703 TEST_F(PipelineTest, ErrorDuringSeek) { | 695 TEST_F(PipelineImplTest, ErrorDuringSeek) { |
704 CreateAudioStream(); | 696 CreateAudioStream(); |
705 MockDemuxerStreamVector streams; | 697 MockDemuxerStreamVector streams; |
706 streams.push_back(audio_stream()); | 698 streams.push_back(audio_stream()); |
707 | 699 |
708 SetDemuxerExpectations(&streams); | 700 SetDemuxerExpectations(&streams); |
709 SetRendererExpectations(); | 701 SetRendererExpectations(); |
710 StartPipelineAndExpect(PIPELINE_OK); | 702 StartPipelineAndExpect(PIPELINE_OK); |
711 | 703 |
712 double playback_rate = 1.0; | 704 double playback_rate = 1.0; |
713 EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate)); | 705 EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate)); |
714 pipeline_->SetPlaybackRate(playback_rate); | 706 pipeline_->SetPlaybackRate(playback_rate); |
715 message_loop_.RunUntilIdle(); | 707 message_loop_.RunUntilIdle(); |
716 | 708 |
717 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 709 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
718 | 710 |
719 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 711 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
720 EXPECT_CALL(*renderer_, Flush(_)) | 712 EXPECT_CALL(*renderer_, Flush(_)) |
721 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, | 713 .WillOnce( |
722 BUFFERING_HAVE_NOTHING), | 714 DoAll(SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
723 RunClosure<0>())); | 715 RunClosure<0>())); |
724 | 716 |
725 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 717 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
726 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); | 718 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
727 EXPECT_CALL(*demuxer_, Stop()); | 719 EXPECT_CALL(*demuxer_, Stop()); |
728 | 720 |
729 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, | 721 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
730 base::Unretained(&callbacks_))); | 722 base::Unretained(&callbacks_))); |
731 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | 723 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
732 message_loop_.RunUntilIdle(); | 724 message_loop_.RunUntilIdle(); |
733 } | 725 } |
734 | 726 |
735 // Invoked function OnError. This asserts that the pipeline does not enqueue | 727 // Invoked function OnError. This asserts that the pipeline does not enqueue |
736 // non-teardown related tasks while tearing down. | 728 // non-teardown related tasks while tearing down. |
737 static void TestNoCallsAfterError( | 729 static void TestNoCallsAfterError(PipelineImpl* pipeline, |
738 Pipeline* pipeline, base::MessageLoop* message_loop, | 730 base::MessageLoop* message_loop, |
739 PipelineStatus /* status */) { | 731 PipelineStatus /* status */) { |
740 CHECK(pipeline); | 732 CHECK(pipeline); |
741 CHECK(message_loop); | 733 CHECK(message_loop); |
742 | 734 |
743 // When we get to this stage, the message loop should be empty. | 735 // When we get to this stage, the message loop should be empty. |
744 EXPECT_TRUE(message_loop->IsIdleForTesting()); | 736 EXPECT_TRUE(message_loop->IsIdleForTesting()); |
745 | 737 |
746 // Make calls on pipeline after error has occurred. | 738 // Make calls on pipeline after error has occurred. |
747 pipeline->SetPlaybackRate(0.5); | 739 pipeline->SetPlaybackRate(0.5); |
748 pipeline->SetVolume(0.5f); | 740 pipeline->SetVolume(0.5f); |
749 | 741 |
750 // No additional tasks should be queued as a result of these calls. | 742 // No additional tasks should be queued as a result of these calls. |
751 EXPECT_TRUE(message_loop->IsIdleForTesting()); | 743 EXPECT_TRUE(message_loop->IsIdleForTesting()); |
752 } | 744 } |
753 | 745 |
754 TEST_F(PipelineTest, NoMessageDuringTearDownFromError) { | 746 TEST_F(PipelineImplTest, NoMessageDuringTearDownFromError) { |
755 CreateAudioStream(); | 747 CreateAudioStream(); |
756 MockDemuxerStreamVector streams; | 748 MockDemuxerStreamVector streams; |
757 streams.push_back(audio_stream()); | 749 streams.push_back(audio_stream()); |
758 | 750 |
759 SetDemuxerExpectations(&streams); | 751 SetDemuxerExpectations(&streams); |
760 SetRendererExpectations(); | 752 SetRendererExpectations(); |
761 StartPipelineAndExpect(PIPELINE_OK); | 753 StartPipelineAndExpect(PIPELINE_OK); |
762 | 754 |
763 // Trigger additional requests on the pipeline during tear down from error. | 755 // Trigger additional requests on the pipeline during tear down from error. |
764 base::Callback<void(PipelineStatus)> cb = base::Bind( | 756 base::Callback<void(PipelineStatus)> cb = |
765 &TestNoCallsAfterError, pipeline_.get(), &message_loop_); | 757 base::Bind(&TestNoCallsAfterError, pipeline_.get(), &message_loop_); |
766 ON_CALL(callbacks_, OnError(_)) | 758 ON_CALL(callbacks_, OnError(_)) |
767 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); | 759 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); |
768 | 760 |
769 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 761 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
770 | 762 |
771 // Seek() isn't called as the demuxer errors out first. | 763 // Seek() isn't called as the demuxer errors out first. |
772 EXPECT_CALL(*renderer_, Flush(_)) | 764 EXPECT_CALL(*renderer_, Flush(_)) |
773 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, | 765 .WillOnce( |
774 BUFFERING_HAVE_NOTHING), | 766 DoAll(SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
775 RunClosure<0>())); | 767 RunClosure<0>())); |
776 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 768 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
777 | 769 |
778 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 770 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
779 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); | 771 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
780 EXPECT_CALL(*demuxer_, Stop()); | 772 EXPECT_CALL(*demuxer_, Stop()); |
781 | 773 |
782 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, | 774 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
783 base::Unretained(&callbacks_))); | 775 base::Unretained(&callbacks_))); |
784 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | 776 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
785 message_loop_.RunUntilIdle(); | 777 message_loop_.RunUntilIdle(); |
786 } | 778 } |
787 | 779 |
788 TEST_F(PipelineTest, DestroyAfterStop) { | 780 TEST_F(PipelineImplTest, DestroyAfterStop) { |
789 CreateAudioStream(); | 781 CreateAudioStream(); |
790 MockDemuxerStreamVector streams; | 782 MockDemuxerStreamVector streams; |
791 streams.push_back(audio_stream()); | 783 streams.push_back(audio_stream()); |
792 SetDemuxerExpectations(&streams); | 784 SetDemuxerExpectations(&streams); |
793 SetRendererExpectations(); | 785 SetRendererExpectations(); |
794 StartPipelineAndExpect(PIPELINE_OK); | 786 StartPipelineAndExpect(PIPELINE_OK); |
795 | 787 |
796 ExpectDemuxerStop(); | 788 ExpectDemuxerStop(); |
797 | 789 |
798 ExpectPipelineStopAndDestroyPipeline(); | 790 ExpectPipelineStopAndDestroyPipeline(); |
799 pipeline_->Stop( | 791 pipeline_->Stop( |
800 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 792 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
801 message_loop_.RunUntilIdle(); | 793 message_loop_.RunUntilIdle(); |
802 } | 794 } |
803 | 795 |
804 TEST_F(PipelineTest, Underflow) { | 796 TEST_F(PipelineImplTest, Underflow) { |
805 CreateAudioStream(); | 797 CreateAudioStream(); |
806 CreateVideoStream(); | 798 CreateVideoStream(); |
807 MockDemuxerStreamVector streams; | 799 MockDemuxerStreamVector streams; |
808 streams.push_back(audio_stream()); | 800 streams.push_back(audio_stream()); |
809 streams.push_back(video_stream()); | 801 streams.push_back(video_stream()); |
810 | 802 |
811 SetDemuxerExpectations(&streams); | 803 SetDemuxerExpectations(&streams); |
812 SetRendererExpectations(); | 804 SetRendererExpectations(); |
813 StartPipelineAndExpect(PIPELINE_OK); | 805 StartPipelineAndExpect(PIPELINE_OK); |
814 | 806 |
815 // Simulate underflow. | 807 // Simulate underflow. |
816 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 808 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
817 buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | 809 buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); |
818 | 810 |
819 // Seek while underflowed. | 811 // Seek while underflowed. |
820 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); | 812 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); |
821 ExpectSeek(expected, true); | 813 ExpectSeek(expected, true); |
822 DoSeek(expected); | 814 DoSeek(expected); |
823 } | 815 } |
824 | 816 |
825 TEST_F(PipelineTest, PositiveStartTime) { | 817 TEST_F(PipelineImplTest, PositiveStartTime) { |
826 start_time_ = base::TimeDelta::FromSeconds(1); | 818 start_time_ = base::TimeDelta::FromSeconds(1); |
827 EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_)); | 819 EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_)); |
828 CreateAudioStream(); | 820 CreateAudioStream(); |
829 MockDemuxerStreamVector streams; | 821 MockDemuxerStreamVector streams; |
830 streams.push_back(audio_stream()); | 822 streams.push_back(audio_stream()); |
831 SetDemuxerExpectations(&streams); | 823 SetDemuxerExpectations(&streams); |
832 SetRendererExpectations(); | 824 SetRendererExpectations(); |
833 StartPipelineAndExpect(PIPELINE_OK); | 825 StartPipelineAndExpect(PIPELINE_OK); |
834 ExpectDemuxerStop(); | 826 ExpectDemuxerStop(); |
835 ExpectPipelineStopAndDestroyPipeline(); | 827 ExpectPipelineStopAndDestroyPipeline(); |
836 pipeline_->Stop( | 828 pipeline_->Stop( |
837 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 829 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
838 message_loop_.RunUntilIdle(); | 830 message_loop_.RunUntilIdle(); |
839 } | 831 } |
840 | 832 |
841 class PipelineTeardownTest : public PipelineTest { | 833 class PipelineTeardownTest : public PipelineImplTest { |
842 public: | 834 public: |
843 enum TeardownState { | 835 enum TeardownState { |
844 kInitDemuxer, | 836 kInitDemuxer, |
845 kInitRenderer, | 837 kInitRenderer, |
846 kFlushing, | 838 kFlushing, |
847 kSeeking, | 839 kSeeking, |
848 kPlaying, | 840 kPlaying, |
849 kSuspending, | 841 kSuspending, |
850 kSuspended, | 842 kSuspended, |
851 kResuming, | 843 kResuming, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 SetInitializeExpectations(state, stop_or_error); | 888 SetInitializeExpectations(state, stop_or_error); |
897 | 889 |
898 EXPECT_CALL(callbacks_, OnStart(expected_status)); | 890 EXPECT_CALL(callbacks_, OnStart(expected_status)); |
899 StartPipeline(); | 891 StartPipeline(); |
900 message_loop_.RunUntilIdle(); | 892 message_loop_.RunUntilIdle(); |
901 } | 893 } |
902 | 894 |
903 PipelineStatus SetInitializeExpectations(TeardownState state, | 895 PipelineStatus SetInitializeExpectations(TeardownState state, |
904 StopOrError stop_or_error) { | 896 StopOrError stop_or_error) { |
905 PipelineStatus status = PIPELINE_OK; | 897 PipelineStatus status = PIPELINE_OK; |
906 base::Closure stop_cb = base::Bind( | 898 base::Closure stop_cb = |
907 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); | 899 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)); |
908 | 900 |
909 if (state == kInitDemuxer) { | 901 if (state == kInitDemuxer) { |
910 if (stop_or_error == kStop) { | 902 if (stop_or_error == kStop) { |
911 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 903 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
912 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 904 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), |
913 PostCallback<1>(PIPELINE_OK))); | 905 PostCallback<1>(PIPELINE_OK))); |
914 ExpectPipelineStopAndDestroyPipeline(); | 906 ExpectPipelineStopAndDestroyPipeline(); |
915 } else { | 907 } else { |
916 status = DEMUXER_ERROR_COULD_NOT_OPEN; | 908 status = DEMUXER_ERROR_COULD_NOT_OPEN; |
917 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 909 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 944 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
953 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), | 945 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), |
954 PostCallback<1>(PIPELINE_OK))); | 946 PostCallback<1>(PIPELINE_OK))); |
955 | 947 |
956 EXPECT_CALL(callbacks_, OnMetadata(_)); | 948 EXPECT_CALL(callbacks_, OnMetadata(_)); |
957 | 949 |
958 // If we get here it's a successful initialization. | 950 // If we get here it's a successful initialization. |
959 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); | 951 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); |
960 EXPECT_CALL(*renderer_, SetVolume(1.0f)); | 952 EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
961 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) | 953 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) |
962 .WillOnce(SetBufferingState(&buffering_state_cb_, | 954 .WillOnce( |
963 BUFFERING_HAVE_ENOUGH)); | 955 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); |
964 | 956 |
965 if (status == PIPELINE_OK) | 957 if (status == PIPELINE_OK) |
966 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 958 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
967 | 959 |
968 return status; | 960 return status; |
969 } | 961 } |
970 | 962 |
971 void DoSeek(TeardownState state, StopOrError stop_or_error) { | 963 void DoSeek(TeardownState state, StopOrError stop_or_error) { |
972 InSequence s; | 964 InSequence s; |
973 PipelineStatus status = SetSeekExpectations(state, stop_or_error); | 965 PipelineStatus status = SetSeekExpectations(state, stop_or_error); |
974 | 966 |
975 EXPECT_CALL(*demuxer_, Stop()); | 967 EXPECT_CALL(*demuxer_, Stop()); |
976 EXPECT_CALL(callbacks_, OnSeek(status)); | 968 EXPECT_CALL(callbacks_, OnSeek(status)); |
977 | 969 |
978 if (status == PIPELINE_OK) { | 970 if (status == PIPELINE_OK) { |
979 ExpectPipelineStopAndDestroyPipeline(); | 971 ExpectPipelineStopAndDestroyPipeline(); |
980 } | 972 } |
981 | 973 |
982 pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind( | 974 pipeline_->Seek( |
983 &CallbackHelper::OnSeek, base::Unretained(&callbacks_))); | 975 base::TimeDelta::FromSeconds(10), |
| 976 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); |
984 message_loop_.RunUntilIdle(); | 977 message_loop_.RunUntilIdle(); |
985 } | 978 } |
986 | 979 |
987 PipelineStatus SetSeekExpectations(TeardownState state, | 980 PipelineStatus SetSeekExpectations(TeardownState state, |
988 StopOrError stop_or_error) { | 981 StopOrError stop_or_error) { |
989 PipelineStatus status = PIPELINE_OK; | 982 PipelineStatus status = PIPELINE_OK; |
990 base::Closure stop_cb = base::Bind( | 983 base::Closure stop_cb = |
991 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); | 984 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)); |
992 | 985 |
993 if (state == kFlushing) { | 986 if (state == kFlushing) { |
994 if (stop_or_error == kStop) { | 987 if (stop_or_error == kStop) { |
995 EXPECT_CALL(*renderer_, Flush(_)) | 988 EXPECT_CALL(*renderer_, Flush(_)) |
996 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 989 .WillOnce(DoAll( |
997 SetBufferingState(&buffering_state_cb_, | 990 Stop(pipeline_.get(), stop_cb), |
998 BUFFERING_HAVE_NOTHING), | 991 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
999 RunClosure<0>())); | 992 RunClosure<0>())); |
1000 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 993 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
1001 } else { | 994 } else { |
1002 status = PIPELINE_ERROR_READ; | 995 status = PIPELINE_ERROR_READ; |
1003 EXPECT_CALL(*renderer_, Flush(_)) | 996 EXPECT_CALL(*renderer_, Flush(_)) |
1004 .WillOnce(DoAll(SetError(pipeline_.get(), status), | 997 .WillOnce(DoAll( |
1005 SetBufferingState(&buffering_state_cb_, | 998 SetError(pipeline_.get(), status), |
1006 BUFFERING_HAVE_NOTHING), | 999 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
1007 RunClosure<0>())); | 1000 RunClosure<0>())); |
1008 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 1001 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
1009 } | 1002 } |
1010 | 1003 |
1011 return status; | 1004 return status; |
1012 } | 1005 } |
1013 | 1006 |
1014 EXPECT_CALL(*renderer_, Flush(_)) | 1007 EXPECT_CALL(*renderer_, Flush(_)) |
1015 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, | 1008 .WillOnce(DoAll( |
1016 BUFFERING_HAVE_NOTHING), | 1009 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
1017 RunClosure<0>())); | 1010 RunClosure<0>())); |
1018 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 1011 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
1019 | 1012 |
1020 if (state == kSeeking) { | 1013 if (state == kSeeking) { |
1021 if (stop_or_error == kStop) { | 1014 if (stop_or_error == kStop) { |
1022 EXPECT_CALL(*demuxer_, Seek(_, _)) | 1015 EXPECT_CALL(*demuxer_, Seek(_, _)) |
1023 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 1016 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), |
1024 RunCallback<1>(PIPELINE_OK))); | 1017 RunCallback<1>(PIPELINE_OK))); |
1025 } else { | 1018 } else { |
1026 status = PIPELINE_ERROR_READ; | 1019 status = PIPELINE_ERROR_READ; |
1027 EXPECT_CALL(*demuxer_, Seek(_, _)) | 1020 EXPECT_CALL(*demuxer_, Seek(_, _)).WillOnce(RunCallback<1>(status)); |
1028 .WillOnce(RunCallback<1>(status)); | |
1029 } | 1021 } |
1030 | 1022 |
1031 return status; | 1023 return status; |
1032 } | 1024 } |
1033 | 1025 |
1034 NOTREACHED() << "State not supported: " << state; | 1026 NOTREACHED() << "State not supported: " << state; |
1035 return status; | 1027 return status; |
1036 } | 1028 } |
1037 | 1029 |
1038 void DoSuspend(TeardownState state, StopOrError stop_or_error) { | 1030 void DoSuspend(TeardownState state, StopOrError stop_or_error) { |
1039 PipelineStatus status = SetSuspendExpectations(state, stop_or_error); | 1031 PipelineStatus status = SetSuspendExpectations(state, stop_or_error); |
1040 | 1032 |
1041 if (state != kSuspended) { | 1033 if (state != kSuspended) { |
1042 // DoStopOrError() handles these for kSuspended. | 1034 // DoStopOrError() handles these for kSuspended. |
1043 EXPECT_CALL(*demuxer_, Stop()); | 1035 EXPECT_CALL(*demuxer_, Stop()); |
1044 if (status == PIPELINE_OK) { | 1036 if (status == PIPELINE_OK) { |
1045 ExpectPipelineStopAndDestroyPipeline(); | 1037 ExpectPipelineStopAndDestroyPipeline(); |
1046 } | 1038 } |
1047 } | 1039 } |
1048 | 1040 |
1049 PipelineTest::DoSuspend(); | 1041 PipelineImplTest::DoSuspend(); |
1050 | 1042 |
1051 if (state == kSuspended) { | 1043 if (state == kSuspended) { |
1052 DoStopOrError(stop_or_error); | 1044 DoStopOrError(stop_or_error); |
1053 } else if (state == kResuming) { | 1045 } else if (state == kResuming) { |
1054 PipelineTest::DoResume(base::TimeDelta()); | 1046 PipelineImplTest::DoResume(base::TimeDelta()); |
1055 } | 1047 } |
1056 } | 1048 } |
1057 | 1049 |
1058 PipelineStatus SetSuspendExpectations(TeardownState state, | 1050 PipelineStatus SetSuspendExpectations(TeardownState state, |
1059 StopOrError stop_or_error) { | 1051 StopOrError stop_or_error) { |
1060 PipelineStatus status = PIPELINE_OK; | 1052 PipelineStatus status = PIPELINE_OK; |
1061 base::Closure stop_cb = | 1053 base::Closure stop_cb = |
1062 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)); | 1054 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)); |
1063 | 1055 |
1064 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); | 1056 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 } | 1097 } |
1106 | 1098 |
1107 void DoStopOrError(StopOrError stop_or_error) { | 1099 void DoStopOrError(StopOrError stop_or_error) { |
1108 InSequence s; | 1100 InSequence s; |
1109 | 1101 |
1110 EXPECT_CALL(*demuxer_, Stop()); | 1102 EXPECT_CALL(*demuxer_, Stop()); |
1111 | 1103 |
1112 switch (stop_or_error) { | 1104 switch (stop_or_error) { |
1113 case kStop: | 1105 case kStop: |
1114 ExpectPipelineStopAndDestroyPipeline(); | 1106 ExpectPipelineStopAndDestroyPipeline(); |
1115 pipeline_->Stop(base::Bind( | 1107 pipeline_->Stop( |
1116 &CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 1108 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
1117 break; | 1109 break; |
1118 | 1110 |
1119 case kError: | 1111 case kError: |
1120 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); | 1112 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); |
1121 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); | 1113 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); |
1122 break; | 1114 break; |
1123 | 1115 |
1124 case kErrorAndStop: | 1116 case kErrorAndStop: |
1125 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); | 1117 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); |
1126 ExpectPipelineStopAndDestroyPipeline(); | 1118 ExpectPipelineStopAndDestroyPipeline(); |
1127 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); | 1119 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); |
1128 message_loop_.RunUntilIdle(); | 1120 message_loop_.RunUntilIdle(); |
1129 pipeline_->Stop(base::Bind( | 1121 pipeline_->Stop( |
1130 &CallbackHelper::OnStop, base::Unretained(&callbacks_))); | 1122 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); |
1131 break; | 1123 break; |
1132 } | 1124 } |
1133 | 1125 |
1134 message_loop_.RunUntilIdle(); | 1126 message_loop_.RunUntilIdle(); |
1135 } | 1127 } |
1136 | 1128 |
1137 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest); | 1129 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest); |
1138 }; | 1130 }; |
1139 | 1131 |
1140 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \ | 1132 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \ |
1141 TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \ | 1133 TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \ |
1142 RunTest(k##state, k##stop_or_error); \ | 1134 RunTest(k##state, k##stop_or_error); \ |
1143 } | 1135 } |
1144 | 1136 |
1145 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer); | 1137 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer); |
1146 INSTANTIATE_TEARDOWN_TEST(Stop, InitRenderer); | 1138 INSTANTIATE_TEARDOWN_TEST(Stop, InitRenderer); |
1147 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing); | 1139 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing); |
1148 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking); | 1140 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking); |
1149 INSTANTIATE_TEARDOWN_TEST(Stop, Playing); | 1141 INSTANTIATE_TEARDOWN_TEST(Stop, Playing); |
1150 INSTANTIATE_TEARDOWN_TEST(Stop, Suspending); | 1142 INSTANTIATE_TEARDOWN_TEST(Stop, Suspending); |
1151 INSTANTIATE_TEARDOWN_TEST(Stop, Suspended); | 1143 INSTANTIATE_TEARDOWN_TEST(Stop, Suspended); |
1152 INSTANTIATE_TEARDOWN_TEST(Stop, Resuming); | 1144 INSTANTIATE_TEARDOWN_TEST(Stop, Resuming); |
1153 | 1145 |
1154 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); | 1146 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); |
1155 INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer); | 1147 INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer); |
1156 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); | 1148 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); |
1157 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); | 1149 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); |
1158 INSTANTIATE_TEARDOWN_TEST(Error, Playing); | 1150 INSTANTIATE_TEARDOWN_TEST(Error, Playing); |
1159 INSTANTIATE_TEARDOWN_TEST(Error, Suspending); | 1151 INSTANTIATE_TEARDOWN_TEST(Error, Suspending); |
1160 INSTANTIATE_TEARDOWN_TEST(Error, Suspended); | 1152 INSTANTIATE_TEARDOWN_TEST(Error, Suspended); |
1161 INSTANTIATE_TEARDOWN_TEST(Error, Resuming); | 1153 INSTANTIATE_TEARDOWN_TEST(Error, Resuming); |
1162 | 1154 |
1163 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); | 1155 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); |
1164 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Suspended); | 1156 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Suspended); |
1165 | 1157 |
1166 } // namespace media | 1158 } // namespace media |
OLD | NEW |