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

Side by Side Diff: media/base/pipeline_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698