Upload upstream chromium 108.0.5359.1
[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/bind.h"
10 #include "base/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 OnAddTextTrack(const TextTrackConfig& config,
151                       AddTextTrackDoneCB done_cb) override {}
152   void OnWaiting(WaitingReason reason) override {}
153   void OnVideoNaturalSizeChange(const gfx::Size& size) override {}
154   void OnAudioConfigChange(const AudioDecoderConfig& config) override {}
155   void OnVideoConfigChange(const VideoDecoderConfig& config) override {}
156   void OnVideoOpacityChange(bool opaque) override {}
157   void OnVideoFrameRateChange(absl::optional<int>) override {}
158   void OnVideoAverageKeyframeDistanceUpdate() override {}
159   void OnAudioPipelineInfoChange(const AudioPipelineInfo& info) override {}
160   void OnVideoPipelineInfoChange(const VideoPipelineInfo& info) override {}
161
162   base::test::SingleThreadTaskEnvironment task_environment_;
163
164   NiceMock<MockDemuxer> demuxer_;
165   raw_ptr<StrictMock<MockPipeline>> pipeline_;
166   PipelineController pipeline_controller_;
167
168   bool was_seeked_ = false;
169   bool last_seeked_time_updated_ = false;
170   bool was_suspended_ = false;
171   bool was_resuming_ = false;
172   bool was_resumed_ = false;
173   base::TimeDelta last_resume_time_;
174 };
175
176 TEST_F(PipelineControllerTest, Startup) {
177   PipelineStatusCallback start_cb = StartPipeline();
178   EXPECT_FALSE(was_seeked_);
179
180   Complete(std::move(start_cb));
181   EXPECT_TRUE(was_seeked_);
182   EXPECT_FALSE(last_seeked_time_updated_);
183   EXPECT_FALSE(was_suspended_);
184   EXPECT_TRUE(pipeline_controller_.IsStable());
185 }
186
187 TEST_F(PipelineControllerTest, StartSuspendedSeekAndResume) {
188   EXPECT_FALSE(pipeline_controller_.IsStable());
189   PipelineStatusCallback start_cb;
190   EXPECT_CALL(*pipeline_, OnStart(_, _, _, _)).WillOnce(MoveArg<3>(&start_cb));
191   pipeline_controller_.Start(Pipeline::StartType::kSuspendAfterMetadata,
192                              &demuxer_, this, false, true);
193   Mock::VerifyAndClear(pipeline_);
194
195   // Initiate a seek before the pipeline completes suspended startup.
196   base::TimeDelta seek_time = base::Seconds(5);
197   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time));
198   pipeline_controller_.Seek(seek_time, true);
199   base::RunLoop().RunUntilIdle();
200   EXPECT_FALSE(was_seeked_);
201
202   PipelineStatusCallback resume_cb;
203   EXPECT_CALL(*pipeline_, OnResume(_, _))
204       .WillOnce(DoAll(MoveArg<1>(&resume_cb)));
205   EXPECT_CALL(*pipeline_, GetMediaTime())
206       .WillRepeatedly(Return(base::TimeDelta()));
207
208   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(true));
209   EXPECT_FALSE(pipeline_controller_.IsStable());
210   Complete(std::move(start_cb));
211
212   EXPECT_FALSE(pipeline_controller_.IsStable());
213   EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended());
214   EXPECT_FALSE(pipeline_controller_.IsSuspended());
215   Mock::VerifyAndClear(pipeline_);
216
217   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(false));
218   Complete(std::move(resume_cb));
219   EXPECT_TRUE(was_seeked_);
220   was_seeked_ = false;
221
222   EXPECT_TRUE(pipeline_controller_.IsStable());
223   EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended());
224   EXPECT_FALSE(pipeline_controller_.IsSuspended());
225   Mock::VerifyAndClear(pipeline_);
226 }
227
228 TEST_F(PipelineControllerTest, StartSuspendedAndResume) {
229   EXPECT_FALSE(pipeline_controller_.IsStable());
230   PipelineStatusCallback start_cb;
231   EXPECT_CALL(*pipeline_, OnStart(_, _, _, _)).WillOnce(MoveArg<3>(&start_cb));
232   pipeline_controller_.Start(Pipeline::StartType::kSuspendAfterMetadata,
233                              &demuxer_, this, false, true);
234   Mock::VerifyAndClear(pipeline_);
235   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(true));
236   EXPECT_FALSE(pipeline_controller_.IsStable());
237   Complete(std::move(start_cb));
238   EXPECT_TRUE(was_seeked_);
239   was_seeked_ = false;
240
241   EXPECT_FALSE(pipeline_controller_.IsStable());
242   EXPECT_TRUE(pipeline_controller_.IsPipelineSuspended());
243   EXPECT_TRUE(pipeline_controller_.IsSuspended());
244   Mock::VerifyAndClear(pipeline_);
245
246   EXPECT_CALL(*pipeline_, IsSuspended()).WillRepeatedly(Return(false));
247   PipelineStatusCallback resume_cb = ResumePipeline();
248   EXPECT_TRUE(was_resuming_);
249   EXPECT_FALSE(was_resumed_);
250
251   Complete(std::move(resume_cb));
252   EXPECT_TRUE(was_resumed_);
253   EXPECT_TRUE(pipeline_controller_.IsStable());
254
255   // |was_seeked_| should not be affected by Suspend()/Resume() at all.
256   EXPECT_FALSE(was_seeked_);
257 }
258
259 TEST_F(PipelineControllerTest, SuspendResume) {
260   Complete(StartPipeline());
261   EXPECT_TRUE(was_seeked_);
262   was_seeked_ = false;
263
264   Complete(SuspendPipeline());
265   EXPECT_TRUE(was_suspended_);
266   EXPECT_FALSE(pipeline_controller_.IsStable());
267
268   PipelineStatusCallback resume_cb = ResumePipeline();
269   EXPECT_TRUE(was_resuming_);
270   EXPECT_FALSE(was_resumed_);
271
272   Complete(std::move(resume_cb));
273   EXPECT_TRUE(was_resumed_);
274   EXPECT_TRUE(pipeline_controller_.IsStable());
275
276   // |was_seeked_| should not be affected by Suspend()/Resume() at all.
277   EXPECT_FALSE(was_seeked_);
278 }
279
280 TEST_F(PipelineControllerTest, Seek) {
281   // Normal seeking should not result in a cancel.
282   EXPECT_CALL(demuxer_, CancelPendingSeek(_)).Times(0);
283
284   Complete(StartPipeline());
285   was_seeked_ = false;
286
287   base::TimeDelta seek_time = base::Seconds(5);
288   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time));
289   PipelineStatusCallback seek_cb = SeekPipeline(seek_time);
290   base::RunLoop().RunUntilIdle();
291   EXPECT_FALSE(was_seeked_);
292
293   Complete(std::move(seek_cb));
294   EXPECT_TRUE(was_seeked_);
295   EXPECT_TRUE(pipeline_controller_.IsStable());
296 }
297
298 // Makes sure OnDecoderStateLost() triggers a seek to the current media time.
299 TEST_F(PipelineControllerTest, DecoderStateLost) {
300   Complete(StartPipeline());
301
302   constexpr auto kCurrentMediaTime = base::Seconds(7);
303   EXPECT_CALL(*pipeline_, GetMediaTime())
304       .WillRepeatedly(Return(kCurrentMediaTime));
305
306   EXPECT_CALL(demuxer_, StartWaitingForSeek(kCurrentMediaTime));
307   EXPECT_CALL(*pipeline_, OnSeek(kCurrentMediaTime, _));
308
309   pipeline_controller_.OnDecoderStateLost();
310   base::RunLoop().RunUntilIdle();
311 }
312
313 // Makes sure OnDecoderStateLost() does not trigger a seek during pending seek.
314 TEST_F(PipelineControllerTest, DecoderStateLost_DuringPendingSeek) {
315   Complete(StartPipeline());
316
317   // Create a pending seek.
318   base::TimeDelta kSeekTime = base::Seconds(5);
319   EXPECT_CALL(demuxer_, StartWaitingForSeek(kSeekTime));
320   PipelineStatusCallback seek_cb = SeekPipeline(kSeekTime);
321   base::RunLoop().RunUntilIdle();
322   Mock::VerifyAndClear(&demuxer_);
323
324   // OnDecoderStateLost() should not trigger another seek.
325   EXPECT_CALL(*pipeline_, GetMediaTime()).Times(0);
326   pipeline_controller_.OnDecoderStateLost();
327   base::RunLoop().RunUntilIdle();
328
329   Complete(std::move(seek_cb));
330 }
331
332 TEST_F(PipelineControllerTest, SuspendResumeTime) {
333   Complete(StartPipeline());
334   Complete(SuspendPipeline());
335
336   base::TimeDelta seek_time = base::Seconds(5);
337   pipeline_controller_.Seek(seek_time, true);
338   base::RunLoop().RunUntilIdle();
339
340   Complete(ResumePipeline());
341   EXPECT_EQ(seek_time, last_resume_time_);
342 }
343
344 TEST_F(PipelineControllerTest, SuspendResumeTime_WithStreamingData) {
345   Complete(StartPipeline_WithStreamingData());
346   Complete(SuspendPipeline());
347
348   base::TimeDelta seek_time = base::Seconds(5);
349   pipeline_controller_.Seek(seek_time, true);
350   base::RunLoop().RunUntilIdle();
351
352   Complete(ResumePipeline());
353   EXPECT_EQ(base::TimeDelta(), last_resume_time_);
354 }
355
356 TEST_F(PipelineControllerTest, SeekAborted) {
357   Complete(StartPipeline());
358
359   // Create a first pending seek.
360   base::TimeDelta seek_time_1 = base::Seconds(5);
361   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_1));
362   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time_1);
363   base::RunLoop().RunUntilIdle();
364   Mock::VerifyAndClear(&demuxer_);
365
366   // Create a second seek; the first should be aborted.
367   base::TimeDelta seek_time_2 = base::Seconds(10);
368   EXPECT_CALL(demuxer_, CancelPendingSeek(seek_time_2));
369   pipeline_controller_.Seek(seek_time_2, true);
370   base::RunLoop().RunUntilIdle();
371   Mock::VerifyAndClear(&demuxer_);
372
373   // When the first seek is completed (or aborted) the second should be issued.
374   EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_2));
375   EXPECT_CALL(*pipeline_, OnSeek(seek_time_2, _));
376   Complete(std::move(seek_cb_1));
377 }
378
379 TEST_F(PipelineControllerTest, PendingSuspend) {
380   Complete(StartPipeline());
381
382   base::TimeDelta seek_time = base::Seconds(5);
383   PipelineStatusCallback seek_cb = SeekPipeline(seek_time);
384   base::RunLoop().RunUntilIdle();
385
386   // While the seek is ongoing, request a suspend.
387   // It will be a mock failure if pipeline_.Suspend() is called.
388   pipeline_controller_.Suspend();
389   base::RunLoop().RunUntilIdle();
390
391   // Expect the suspend to trigger when the seek is completed.
392   EXPECT_CALL(*pipeline_, OnSuspend(_));
393   Complete(std::move(seek_cb));
394 }
395
396 TEST_F(PipelineControllerTest, SeekMergesWithResume) {
397   Complete(StartPipeline());
398   Complete(SuspendPipeline());
399
400   // Pipeline startup always completes with a seek.
401   EXPECT_TRUE(was_seeked_);
402   was_seeked_ = false;
403
404   // Request a seek while suspended.
405   // It will be a mock failure if pipeline_.Seek() is called.
406   base::TimeDelta seek_time = base::Seconds(5);
407   pipeline_controller_.Seek(seek_time, true);
408   base::RunLoop().RunUntilIdle();
409   EXPECT_FALSE(was_seeked_);
410
411   // Resume and verify the resume time includes the seek.
412   Complete(ResumePipeline());
413   EXPECT_EQ(seek_time, last_resume_time_);
414   EXPECT_TRUE(last_seeked_time_updated_);
415 }
416
417 TEST_F(PipelineControllerTest, SeekMergesWithSeek) {
418   Complete(StartPipeline());
419
420   base::TimeDelta seek_time_1 = base::Seconds(5);
421   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time_1);
422   base::RunLoop().RunUntilIdle();
423
424   // Request another seek while the first is ongoing.
425   base::TimeDelta seek_time_2 = base::Seconds(10);
426   pipeline_controller_.Seek(seek_time_2, true);
427   base::RunLoop().RunUntilIdle();
428
429   // Request a third seek. (It should replace the second.)
430   base::TimeDelta seek_time_3 = base::Seconds(15);
431   pipeline_controller_.Seek(seek_time_3, true);
432   base::RunLoop().RunUntilIdle();
433
434   // Expect the third seek to trigger when the first seek completes.
435   EXPECT_CALL(*pipeline_, OnSeek(seek_time_3, _));
436   Complete(std::move(seek_cb_1));
437 }
438
439 TEST_F(PipelineControllerTest, SeekToSeekTimeElided) {
440   Complete(StartPipeline());
441
442   base::TimeDelta seek_time = base::Seconds(5);
443   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time);
444   base::RunLoop().RunUntilIdle();
445
446   // Request a seek to the same time again.
447   pipeline_controller_.Seek(seek_time, true);
448   base::RunLoop().RunUntilIdle();
449
450   // Complete the first seek.
451   // It would be a mock error if the second seek was dispatched here.
452   Complete(std::move(seek_cb_1));
453   EXPECT_TRUE(pipeline_controller_.IsStable());
454 }
455
456 TEST_F(PipelineControllerTest, SeekToSeekTimeNotElided) {
457   Complete(StartPipeline_WithDynamicData());
458
459   base::TimeDelta seek_time = base::Seconds(5);
460   PipelineStatusCallback seek_cb_1 = SeekPipeline(seek_time);
461   base::RunLoop().RunUntilIdle();
462
463   // Request a seek to the same time again.
464   pipeline_controller_.Seek(seek_time, true);
465   base::RunLoop().RunUntilIdle();
466
467   // Expect the second seek to trigger when the first seek completes.
468   EXPECT_CALL(*pipeline_, OnSeek(seek_time, _));
469   Complete(std::move(seek_cb_1));
470 }
471
472 TEST_F(PipelineControllerTest, VideoTrackChangeWhileSuspending) {
473   Complete(StartPipeline());
474   EXPECT_CALL(*pipeline_, OnSuspend(_));
475   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _)).Times(0);
476   pipeline_controller_.Suspend();
477   pipeline_controller_.OnSelectedVideoTrackChanged({});
478 }
479
480 TEST_F(PipelineControllerTest, AudioTrackChangeWhileSuspending) {
481   Complete(StartPipeline());
482   EXPECT_CALL(*pipeline_, OnSuspend(_));
483   EXPECT_CALL(*pipeline_, OnEnabledAudioTracksChanged(_, _)).Times(0);
484   pipeline_controller_.Suspend();
485   pipeline_controller_.OnEnabledAudioTracksChanged({});
486 }
487
488 TEST_F(PipelineControllerTest, AudioTrackChangeDuringVideoTrackChange) {
489   Complete(StartPipeline());
490
491   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _));
492   pipeline_controller_.OnSelectedVideoTrackChanged({});
493   pipeline_controller_.OnEnabledAudioTracksChanged({});
494   EXPECT_CALL(*pipeline_, OnEnabledAudioTracksChanged(_, _));
495
496   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
497       PipelineController::State::PLAYING);
498
499   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
500       PipelineController::State::PLAYING);
501 }
502
503 TEST_F(PipelineControllerTest, SuspendDuringVideoTrackChange) {
504   Complete(StartPipeline());
505   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _));
506   was_resumed_ = false;
507   pipeline_controller_.OnSelectedVideoTrackChanged({});
508   pipeline_controller_.Suspend();
509
510   base::RunLoop loop;
511   EXPECT_CALL(*pipeline_, OnSuspend(_))
512       .WillOnce(RunOnceClosure(loop.QuitClosure()));
513
514   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
515       PipelineController::State::PLAYING);
516
517   loop.Run();
518   EXPECT_FALSE(was_resumed_);
519 }
520
521 TEST_F(PipelineControllerTest, SuspendDuringAudioTrackChange) {
522   Complete(StartPipeline());
523   EXPECT_CALL(*pipeline_, OnEnabledAudioTracksChanged(_, _));
524   was_resumed_ = false;
525
526   pipeline_controller_.OnEnabledAudioTracksChanged({});
527   pipeline_controller_.Suspend();
528
529   base::RunLoop loop;
530   EXPECT_CALL(*pipeline_, OnSuspend(_))
531       .WillOnce(RunOnceClosure(loop.QuitClosure()));
532
533   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
534       PipelineController::State::PLAYING);
535
536   loop.Run();
537   EXPECT_FALSE(was_resumed_);
538 }
539
540 TEST_F(PipelineControllerTest, ResumePlaybackDuringSwitchingTracksState) {
541   Complete(StartPipeline());
542   Complete(SuspendPipeline());
543   EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _)).Times(1);
544   EXPECT_CALL(*pipeline_, GetMediaTime()).Times(1);
545   EXPECT_CALL(*pipeline_, OnResume(_, _)).Times(1);
546
547   pipeline_controller_.OnSelectedVideoTrackChanged({});
548   pipeline_controller_.Resume();
549   pipeline_controller_.FireOnTrackChangeCompleteForTesting(
550       PipelineController::State::SUSPENDED);
551 }
552
553 TEST_F(PipelineControllerTest, PreservesPitch) {
554   Complete(StartPipeline());
555   EXPECT_CALL(*pipeline_, SetPreservesPitch(false));
556   pipeline_controller_.SetPreservesPitch(false);
557
558   EXPECT_CALL(*pipeline_, SetPreservesPitch(true));
559   pipeline_controller_.SetPreservesPitch(true);
560 }
561
562 }  // namespace media