Revert "[M120 Migration]Fix for crash during chrome exit"
[platform/framework/web/chromium-efl.git] / media / filters / pipeline_controller_unittest.cc
1 // Copyright 2016 The Chromium Authors
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/filters/pipeline_controller.h"
6
7 #include <memory>
8
9 #include "base/functional/bind.h"
10 #include "base/functional/callback_helpers.h"
11 #include "base/memory/raw_ptr.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/notreached.h"
14 #include "base/run_loop.h"
15 #include "base/test/gmock_callback_support.h"
16 #include "base/test/gmock_move_support.h"
17 #include "base/test/task_environment.h"
18 #include "base/time/time.h"
19 #include "media/base/mock_filters.h"
20 #include "media/base/pipeline.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using ::base::test::RunOnceClosure;
25 using ::testing::_;
26 using ::testing::AnyNumber;
27 using ::testing::DoAll;
28 using ::testing::Mock;
29 using ::testing::NiceMock;
30 using ::testing::Return;
31 using ::testing::SaveArg;
32 using ::testing::StrictMock;
33
34 namespace media {
35
36 class PipelineControllerTest : public ::testing::Test, public Pipeline::Client {
37  public:
38   PipelineControllerTest()
39       : pipeline_(new StrictMock<MockPipeline>()),
40         pipeline_controller_(
41             std::unique_ptr<Pipeline>(pipeline_),
42             base::BindRepeating(&PipelineControllerTest::OnSeeked,
43                                 base::Unretained(this)),
44             base::BindRepeating(&PipelineControllerTest::OnSuspended,
45                                 base::Unretained(this)),
46             base::BindRepeating(&PipelineControllerTest::OnBeforeResume,
47                                 base::Unretained(this)),
48             base::BindRepeating(&PipelineControllerTest::OnResumed,
49                                 base::Unretained(this)),
50             base::BindRepeating(&PipelineControllerTest::OnError,
51                                 base::Unretained(this))) {}
52
53   PipelineControllerTest(const PipelineControllerTest&) = delete;
54   PipelineControllerTest& operator=(const PipelineControllerTest&) = delete;
55
56   ~PipelineControllerTest() override = default;
57
58   PipelineStatusCallback StartPipeline(bool is_streaming, bool is_static) {
59     EXPECT_FALSE(pipeline_controller_.IsStable());
60     PipelineStatusCallback start_cb;
61     EXPECT_CALL(*pipeline_, OnStart(_, _, _, _))
62         .WillOnce(MoveArg<3>(&start_cb));
63     pipeline_controller_.Start(Pipeline::StartType::kNormal, &demuxer_, this,
64                                is_streaming, is_static);
65     Mock::VerifyAndClear(pipeline_);
66     EXPECT_CALL(*pipeline_, IsSuspended())
67         .Times(AnyNumber())
68         .WillOnce(Return(false));
69     EXPECT_FALSE(pipeline_controller_.IsStable());
70     return start_cb;
71   }
72
73   PipelineStatusCallback StartPipeline() { return StartPipeline(false, true); }
74
75   PipelineStatusCallback StartPipeline_WithDynamicData() {
76     return StartPipeline(false, false);
77   }
78
79   PipelineStatusCallback StartPipeline_WithStreamingData() {
80     return StartPipeline(true, false);
81   }
82
83   PipelineStatusCallback SeekPipeline(base::TimeDelta time) {
84     EXPECT_TRUE(pipeline_controller_.IsStable());
85     PipelineStatusCallback seek_cb;
86     EXPECT_CALL(*pipeline_, OnSeek(time, _)).WillOnce(MoveArg<1>(&seek_cb));
87     pipeline_controller_.Seek(time, true);
88     Mock::VerifyAndClear(pipeline_);
89     EXPECT_FALSE(pipeline_controller_.IsStable());
90     return seek_cb;
91   }
92
93   PipelineStatusCallback SuspendPipeline() {
94     EXPECT_TRUE(pipeline_controller_.IsStable());
95     PipelineStatusCallback suspend_cb;
96     EXPECT_CALL(*pipeline_, OnSuspend(_)).WillOnce(MoveArg<0>(&suspend_cb));
97     pipeline_controller_.Suspend();
98     Mock::VerifyAndClear(pipeline_);
99     EXPECT_CALL(*pipeline_, IsSuspended())
100         .Times(AnyNumber())
101         .WillOnce(Return(true));
102     EXPECT_TRUE(pipeline_controller_.IsSuspended());
103     EXPECT_FALSE(pipeline_controller_.IsStable());
104     EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended());
105     return suspend_cb;
106   }
107
108   PipelineStatusCallback ResumePipeline() {
109     EXPECT_TRUE(pipeline_controller_.IsPipelineSuspended());
110     PipelineStatusCallback resume_cb;
111     EXPECT_CALL(*pipeline_, OnResume(_, _))
112         .WillOnce(
113             DoAll(SaveArg<0>(&last_resume_time_), MoveArg<1>(&resume_cb)));
114     EXPECT_CALL(*pipeline_, GetMediaTime())
115         .WillRepeatedly(Return(base::TimeDelta()));
116     pipeline_controller_.Resume();
117     Mock::VerifyAndClear(pipeline_);
118     EXPECT_CALL(*pipeline_, IsSuspended())
119         .Times(AnyNumber())
120         .WillOnce(Return(false));
121     EXPECT_FALSE(pipeline_controller_.IsSuspended());
122     EXPECT_FALSE(pipeline_controller_.IsStable());
123     EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended());
124     return resume_cb;
125   }
126
127   void Complete(PipelineStatusCallback cb) {
128     std::move(cb).Run(PIPELINE_OK);
129     base::RunLoop().RunUntilIdle();
130   }
131
132  protected:
133   void OnSeeked(bool time_updated) {
134     was_seeked_ = true;
135     last_seeked_time_updated_ = time_updated;
136   }
137
138   void OnSuspended() { was_suspended_ = true; }
139   void OnBeforeResume() { was_resuming_ = true; }
140   void OnResumed() { was_resumed_ = true; }
141
142   // Pipeline::Client overrides
143   void OnError(PipelineStatus status) override { NOTREACHED(); }
144   void OnFallback(PipelineStatus status) override { NOTREACHED(); }
145   void OnEnded() override {}
146   void OnMetadata(const PipelineMetadata& metadata) override {}
147   void OnBufferingStateChange(BufferingState state,
148                               BufferingStateChangeReason reason) override {}
149   void OnDurationChange() override {}
150   void OnWaiting(WaitingReason reason) override {}
151   void OnVideoNaturalSizeChange(const gfx::Size& size) override {}
152   void OnAudioConfigChange(const AudioDecoderConfig& config) override {}
153   void OnVideoConfigChange(const VideoDecoderConfig& config) override {}
154   void OnVideoOpacityChange(bool opaque) override {}
155   void OnVideoFrameRateChange(absl::optional<int>) override {}
156   void OnVideoAverageKeyframeDistanceUpdate() override {}
157   void OnAudioPipelineInfoChange(const AudioPipelineInfo& info) override {}
158   void OnVideoPipelineInfoChange(const VideoPipelineInfo& info) override {}
159
160   base::test::SingleThreadTaskEnvironment task_environment_;
161
162   NiceMock<MockDemuxer> demuxer_;
163   raw_ptr<StrictMock<MockPipeline>, DanglingUntriaged> pipeline_;
164   PipelineController pipeline_controller_;
165
166   bool was_seeked_ = false;
167   bool last_seeked_time_updated_ = false;
168   bool was_suspended_ = false;
169   bool was_resuming_ = false;
170   bool was_resumed_ = false;
171   base::TimeDelta last_resume_time_;
172 };
173
174 TEST_F(PipelineControllerTest, Startup) {
175   PipelineStatusCallback start_cb = StartPipeline();
176   EXPECT_FALSE(was_seeked_);
177
178   Complete(std::move(start_cb));
179   EXPECT_TRUE(was_seeked_);
180   EXPECT_FALSE(last_seeked_time_updated_);
181   EXPECT_FALSE(was_suspended_);
182   EXPECT_TRUE(pipeline_controller_.IsStable());
183 }
184
185 TEST_F(PipelineControllerTest, StartSuspendedSeekAndResume) {
186   EXPECT_FALSE(pipeline_controller_.IsStable());
187   PipelineStatusCallback start_cb;
188   EXPECT_CALL(*pipeline_, OnStart(_, _, _, _)).WillOnce(MoveArg<3>(&start_cb));
189   pipeline_controller_.Start(Pipeline::StartType::kSuspendAfterMetadata,
190                              &demuxer_, this, false, true);
191   Mock::VerifyAndClear(pipeline_);
192
193   // Initiate a seek before the pipeline completes suspended startup.
194   base::TimeDelta seek_time = base::Seconds(5);
195   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time));
196   pipeline_controller_.Seek(seek_time, true);
197   base::RunLoop().RunUntilIdle();
198   EXPECT_FALSE(was_seeked_);
199
200   PipelineStatusCallback resume_cb;
201   EXPECT_CALL(*pipeline_, OnResume(_, _))
202       .WillOnce(DoAll(MoveArg<1>(&resume_cb)));
203   EXPECT_CALL(*pipeline_, GetMediaTime())
204       .WillRepeatedly(Return(base::TimeDelta()));
205
206   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(true));
207   EXPECT_FALSE(pipeline_controller_.IsStable());
208   Complete(std::move(start_cb));
209
210   EXPECT_FALSE(pipeline_controller_.IsStable());
211   EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended());
212   EXPECT_FALSE(pipeline_controller_.IsSuspended());
213   Mock::VerifyAndClear(pipeline_);
214
215   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(false));
216   Complete(std::move(resume_cb));
217   EXPECT_TRUE(was_seeked_);
218   was_seeked_ = false;
219
220   EXPECT_TRUE(pipeline_controller_.IsStable());
221   EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended());
222   EXPECT_FALSE(pipeline_controller_.IsSuspended());
223   Mock::VerifyAndClear(pipeline_);
224 }
225
226 TEST_F(PipelineControllerTest, StartSuspendedAndResume) {
227   EXPECT_FALSE(pipeline_controller_.IsStable());
228   PipelineStatusCallback start_cb;
229   EXPECT_CALL(*pipeline_, OnStart(_, _, _, _)).WillOnce(MoveArg<3>(&start_cb));
230   pipeline_controller_.Start(Pipeline::StartType::kSuspendAfterMetadata,
231                              &demuxer_, this, false, true);
232   Mock::VerifyAndClear(pipeline_);
233   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(true));
234   EXPECT_FALSE(pipeline_controller_.IsStable());
235   Complete(std::move(start_cb));
236   EXPECT_TRUE(was_seeked_);
237   was_seeked_ = false;
238
239   EXPECT_FALSE(pipeline_controller_.IsStable());
240   EXPECT_TRUE(pipeline_controller_.IsPipelineSuspended());
241   EXPECT_TRUE(pipeline_controller_.IsSuspended());
242   Mock::VerifyAndClear(pipeline_);
243
244   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(false));
245   PipelineStatusCallback resume_cb = ResumePipeline();
246   EXPECT_TRUE(was_resuming_);
247   EXPECT_FALSE(was_resumed_);
248
249   Complete(std::move(resume_cb));
250   EXPECT_TRUE(was_resumed_);
251   EXPECT_TRUE(pipeline_controller_.IsStable());
252
253   // |was_seeked_| should not be affected by Suspend()/Resume() at all.
254   EXPECT_FALSE(was_seeked_);
255 }
256
257 TEST_F(PipelineControllerTest, SuspendResume) {
258   Complete(StartPipeline());
259   EXPECT_TRUE(was_seeked_);
260   was_seeked_ = false;
261
262   Complete(SuspendPipeline());
263   EXPECT_TRUE(was_suspended_);
264   EXPECT_FALSE(pipeline_controller_.IsStable());
265
266   PipelineStatusCallback resume_cb = ResumePipeline();
267   EXPECT_TRUE(was_resuming_);
268   EXPECT_FALSE(was_resumed_);
269
270   Complete(std::move(resume_cb));
271   EXPECT_TRUE(was_resumed_);
272   EXPECT_TRUE(pipeline_controller_.IsStable());
273
274   // |was_seeked_| should not be affected by Suspend()/Resume() at all.
275   EXPECT_FALSE(was_seeked_);
276 }
277
278 TEST_F(PipelineControllerTest, Seek) {
279   // Normal seeking should not result in a cancel.
280   EXPECT_CALL(demuxer_, CancelPendingSeek(_)).Times(0);
281
282   Complete(StartPipeline());
283   was_seeked_ = false;
284
285   base::TimeDelta seek_time = base::Seconds(5);
286   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time));
287   PipelineStatusCallback seek_cb = SeekPipeline(seek_time);
288   base::RunLoop().RunUntilIdle();
289   EXPECT_FALSE(was_seeked_);
290
291   Complete(std::move(seek_cb));
292   EXPECT_TRUE(was_seeked_);
293   EXPECT_TRUE(pipeline_controller_.IsStable());
294 }
295
296 // Makes sure OnDecoderStateLost() triggers a seek to the current media time.
297 TEST_F(PipelineControllerTest, DecoderStateLost) {
298   Complete(StartPipeline());
299
300   constexpr auto kCurrentMediaTime = base::Seconds(7);
301   EXPECT_CALL(*pipeline_, GetMediaTime())
302       .WillRepeatedly(Return(kCurrentMediaTime));
303
304   EXPECT_CALL(demuxer_, StartWaitingForSeek(kCurrentMediaTime));
305   EXPECT_CALL(*pipeline_, OnSeek(kCurrentMediaTime, _));
306
307   pipeline_controller_.OnDecoderStateLost();
308   base::RunLoop().RunUntilIdle();
309 }
310
311 // Makes sure OnDecoderStateLost() does not trigger a seek during pending seek.
312 TEST_F(PipelineControllerTest, DecoderStateLost_DuringPendingSeek) {
313   Complete(StartPipeline());
314
315   // Create a pending seek.
316   base::TimeDelta kSeekTime = base::Seconds(5);
317   EXPECT_CALL(demuxer_, StartWaitingForSeek(kSeekTime));
318   PipelineStatusCallback seek_cb = SeekPipeline(kSeekTime);
319   base::RunLoop().RunUntilIdle();
320   Mock::VerifyAndClear(&demuxer_);
321
322   // OnDecoderStateLost() should not trigger another seek.
323   EXPECT_CALL(*pipeline_, GetMediaTime()).Times(0);
324   pipeline_controller_.OnDecoderStateLost();
325   base::RunLoop().RunUntilIdle();
326
327   Complete(std::move(seek_cb));
328 }
329
330 TEST_F(PipelineControllerTest, SuspendResumeTime) {
331   Complete(StartPipeline());
332   Complete(SuspendPipeline());
333
334   base::TimeDelta seek_time = base::Seconds(5);
335   pipeline_controller_.Seek(seek_time, true);
336   base::RunLoop().RunUntilIdle();
337
338   Complete(ResumePipeline());
339   EXPECT_EQ(seek_time, last_resume_time_);
340 }
341
342 TEST_F(PipelineControllerTest, SuspendResumeTime_WithStreamingData) {
343   Complete(StartPipeline_WithStreamingData());
344   Complete(SuspendPipeline());
345
346   base::TimeDelta seek_time = base::Seconds(5);
347   pipeline_controller_.Seek(seek_time, true);
348   base::RunLoop().RunUntilIdle();
349
350   Complete(ResumePipeline());
351   EXPECT_EQ(base::TimeDelta(), last_resume_time_);
352 }
353
354 TEST_F(PipelineControllerTest, SeekAborted) {
355   Complete(StartPipeline());
356
357   // Create a first pending seek.
358   base::TimeDelta seek_time_1 = base::Seconds(5);
359   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_1));
360   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time_1);
361   base::RunLoop().RunUntilIdle();
362   Mock::VerifyAndClear(&demuxer_);
363
364   // Create a second seek; the first should be aborted.
365   base::TimeDelta seek_time_2 = base::Seconds(10);
366   EXPECT_CALL(demuxer_, CancelPendingSeek(seek_time_2));
367   pipeline_controller_.Seek(seek_time_2, true);
368   base::RunLoop().RunUntilIdle();
369   Mock::VerifyAndClear(&demuxer_);
370
371   // When the first seek is completed (or aborted) the second should be issued.
372   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_2));
373   EXPECT_CALL(*pipeline_, OnSeek(seek_time_2, _));
374   Complete(std::move(seek_cb_1));
375 }
376
377 TEST_F(PipelineControllerTest, PendingSuspend) {
378   Complete(StartPipeline());
379
380   base::TimeDelta seek_time = base::Seconds(5);
381   PipelineStatusCallback seek_cb = SeekPipeline(seek_time);
382   base::RunLoop().RunUntilIdle();
383
384   // While the seek is ongoing, request a suspend.
385   // It will be a mock failure if pipeline_.Suspend() is called.
386   pipeline_controller_.Suspend();
387   base::RunLoop().RunUntilIdle();
388
389   // Expect the suspend to trigger when the seek is completed.
390   EXPECT_CALL(*pipeline_, OnSuspend(_));
391   Complete(std::move(seek_cb));
392 }
393
394 TEST_F(PipelineControllerTest, SeekMergesWithResume) {
395   Complete(StartPipeline());
396   Complete(SuspendPipeline());
397
398   // Pipeline startup always completes with a seek.
399   EXPECT_TRUE(was_seeked_);
400   was_seeked_ = false;
401
402   // Request a seek while suspended.
403   // It will be a mock failure if pipeline_.Seek() is called.
404   base::TimeDelta seek_time = base::Seconds(5);
405   pipeline_controller_.Seek(seek_time, true);
406   base::RunLoop().RunUntilIdle();
407   EXPECT_FALSE(was_seeked_);
408
409   // Resume and verify the resume time includes the seek.
410   Complete(ResumePipeline());
411   EXPECT_EQ(seek_time, last_resume_time_);
412   EXPECT_TRUE(last_seeked_time_updated_);
413 }
414
415 TEST_F(PipelineControllerTest, SeekMergesWithSeek) {
416   Complete(StartPipeline());
417
418   base::TimeDelta seek_time_1 = base::Seconds(5);
419   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time_1);
420   base::RunLoop().RunUntilIdle();
421
422   // Request another seek while the first is ongoing.
423   base::TimeDelta seek_time_2 = base::Seconds(10);
424   pipeline_controller_.Seek(seek_time_2, true);
425   base::RunLoop().RunUntilIdle();
426
427   // Request a third seek. (It should replace the second.)
428   base::TimeDelta seek_time_3 = base::Seconds(15);
429   pipeline_controller_.Seek(seek_time_3, true);
430   base::RunLoop().RunUntilIdle();
431
432   // Expect the third seek to trigger when the first seek completes.
433   EXPECT_CALL(*pipeline_, OnSeek(seek_time_3, _));
434   Complete(std::move(seek_cb_1));
435 }
436
437 TEST_F(PipelineControllerTest, SeekToSeekTimeElided) {
438   Complete(StartPipeline());
439
440   base::TimeDelta seek_time = base::Seconds(5);
441   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time);
442   base::RunLoop().RunUntilIdle();
443
444   // Request a seek to the same time again.
445   pipeline_controller_.Seek(seek_time, true);
446   base::RunLoop().RunUntilIdle();
447
448   // Complete the first seek.
449   // It would be a mock error if the second seek was dispatched here.
450   Complete(std::move(seek_cb_1));
451   EXPECT_TRUE(pipeline_controller_.IsStable());
452 }
453
454 TEST_F(PipelineControllerTest, SeekToSeekTimeNotElided) {
455   Complete(StartPipeline_WithDynamicData());
456
457   base::TimeDelta seek_time = base::Seconds(5);
458   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time);
459   base::RunLoop().RunUntilIdle();
460
461   // Request a seek to the same time again.
462   pipeline_controller_.Seek(seek_time, true);
463   base::RunLoop().RunUntilIdle();
464
465   // Expect the second seek to trigger when the first seek completes.
466   EXPECT_CALL(*pipeline_, OnSeek(seek_time, _));
467   Complete(std::move(seek_cb_1));
468 }
469
470 TEST_F(PipelineControllerTest, VideoTrackChangeWhileSuspending) {
471   Complete(StartPipeline());
472   EXPECT_CALL(*pipeline_, OnSuspend(_));
473   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _)).Times(0);
474   pipeline_controller_.Suspend();
475   pipeline_controller_.OnSelectedVideoTrackChanged({});
476 }
477
478 TEST_F(PipelineControllerTest, AudioTrackChangeWhileSuspending) {
479   Complete(StartPipeline());
480   EXPECT_CALL(*pipeline_, OnSuspend(_));
481   EXPECT_CALL(*pipeline_, OnEnabledAudioTracksChanged(_, _)).Times(0);
482   pipeline_controller_.Suspend();
483   pipeline_controller_.OnEnabledAudioTracksChanged({});
484 }
485
486 TEST_F(PipelineControllerTest, AudioTrackChangeDuringVideoTrackChange) {
487   Complete(StartPipeline());
488
489   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _));
490   pipeline_controller_.OnSelectedVideoTrackChanged({});
491   pipeline_controller_.OnEnabledAudioTracksChanged({});
492   EXPECT_CALL(*pipeline_, OnEnabledAudioTracksChanged(_, _));
493
494   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
495       PipelineController::State::PLAYING);
496
497   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
498       PipelineController::State::PLAYING);
499 }
500
501 TEST_F(PipelineControllerTest, SuspendDuringVideoTrackChange) {
502   Complete(StartPipeline());
503   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _));
504   was_resumed_ = false;
505   pipeline_controller_.OnSelectedVideoTrackChanged({});
506   pipeline_controller_.Suspend();
507
508   base::RunLoop loop;
509   EXPECT_CALL(*pipeline_, OnSuspend(_))
510       .WillOnce(RunOnceClosure(loop.QuitClosure()));
511
512   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
513       PipelineController::State::PLAYING);
514
515   loop.Run();
516   EXPECT_FALSE(was_resumed_);
517 }
518
519 TEST_F(PipelineControllerTest, SuspendDuringAudioTrackChange) {
520   Complete(StartPipeline());
521   EXPECT_CALL(*pipeline_, OnEnabledAudioTracksChanged(_, _));
522   was_resumed_ = false;
523
524   pipeline_controller_.OnEnabledAudioTracksChanged({});
525   pipeline_controller_.Suspend();
526
527   base::RunLoop loop;
528   EXPECT_CALL(*pipeline_, OnSuspend(_))
529       .WillOnce(RunOnceClosure(loop.QuitClosure()));
530
531   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
532       PipelineController::State::PLAYING);
533
534   loop.Run();
535   EXPECT_FALSE(was_resumed_);
536 }
537
538 TEST_F(PipelineControllerTest, ResumePlaybackDuringSwitchingTracksState) {
539   Complete(StartPipeline());
540   Complete(SuspendPipeline());
541   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _)).Times(1);
542   EXPECT_CALL(*pipeline_, GetMediaTime()).Times(1);
543   EXPECT_CALL(*pipeline_, OnResume(_, _)).Times(1);
544
545   pipeline_controller_.OnSelectedVideoTrackChanged({});
546   pipeline_controller_.Resume();
547   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
548       PipelineController::State::SUSPENDED);
549 }
550
551 TEST_F(PipelineControllerTest, PreservesPitch) {
552   Complete(StartPipeline());
553   EXPECT_CALL(*pipeline_, SetPreservesPitch(false));
554   pipeline_controller_.SetPreservesPitch(false);
555
556   EXPECT_CALL(*pipeline_, SetPreservesPitch(true));
557   pipeline_controller_.SetPreservesPitch(true);
558 }
559
560 }  // namespace media