| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/filters/pipeline_controller.h" | 5 #include "media/filters/pipeline_controller.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 using ::testing::NiceMock; | 25 using ::testing::NiceMock; |
| 26 using ::testing::Return; | 26 using ::testing::Return; |
| 27 using ::testing::SaveArg; | 27 using ::testing::SaveArg; |
| 28 using ::testing::StrictMock; | 28 using ::testing::StrictMock; |
| 29 | 29 |
| 30 namespace media { | 30 namespace media { |
| 31 | 31 |
| 32 class PipelineControllerTest : public ::testing::Test, public Pipeline::Client { | 32 class PipelineControllerTest : public ::testing::Test, public Pipeline::Client { |
| 33 public: | 33 public: |
| 34 PipelineControllerTest() | 34 PipelineControllerTest() |
| 35 : pipeline_controller_(&pipeline_, | 35 : pipeline_(new StrictMock<MockPipeline>()), |
| 36 pipeline_controller_(std::unique_ptr<Pipeline>(pipeline_), |
| 36 base::Bind(&PipelineControllerTest::CreateRenderer, | 37 base::Bind(&PipelineControllerTest::CreateRenderer, |
| 37 base::Unretained(this)), | 38 base::Unretained(this)), |
| 38 base::Bind(&PipelineControllerTest::OnSeeked, | 39 base::Bind(&PipelineControllerTest::OnSeeked, |
| 39 base::Unretained(this)), | 40 base::Unretained(this)), |
| 40 base::Bind(&PipelineControllerTest::OnSuspended, | 41 base::Bind(&PipelineControllerTest::OnSuspended, |
| 41 base::Unretained(this)), | 42 base::Unretained(this)), |
| 42 base::Bind(&PipelineControllerTest::OnBeforeResume, | 43 base::Bind(&PipelineControllerTest::OnBeforeResume, |
| 43 base::Unretained(this)), | 44 base::Unretained(this)), |
| 44 base::Bind(&PipelineControllerTest::OnResumed, | 45 base::Bind(&PipelineControllerTest::OnResumed, |
| 45 base::Unretained(this)), | 46 base::Unretained(this)), |
| 46 base::Bind(&PipelineControllerTest::OnError, | 47 base::Bind(&PipelineControllerTest::OnError, |
| 47 base::Unretained(this))) {} | 48 base::Unretained(this))) {} |
| 48 | 49 |
| 49 ~PipelineControllerTest() override {} | 50 ~PipelineControllerTest() override {} |
| 50 | 51 |
| 51 PipelineStatusCB StartPipeline(bool is_streaming, bool is_static) { | 52 PipelineStatusCB StartPipeline(bool is_streaming, bool is_static) { |
| 52 EXPECT_FALSE(pipeline_controller_.IsStable()); | 53 EXPECT_FALSE(pipeline_controller_.IsStable()); |
| 53 PipelineStatusCB start_cb; | 54 PipelineStatusCB start_cb; |
| 54 EXPECT_CALL(pipeline_, Start(_, _, _, _)).WillOnce(SaveArg<3>(&start_cb)); | 55 EXPECT_CALL(*pipeline_, Start(_, _, _, _)).WillOnce(SaveArg<3>(&start_cb)); |
| 55 pipeline_controller_.Start(&demuxer_, this, is_streaming, is_static); | 56 pipeline_controller_.Start(&demuxer_, this, is_streaming, is_static); |
| 56 Mock::VerifyAndClear(&pipeline_); | 57 Mock::VerifyAndClear(pipeline_); |
| 57 EXPECT_FALSE(pipeline_controller_.IsStable()); | 58 EXPECT_FALSE(pipeline_controller_.IsStable()); |
| 58 return start_cb; | 59 return start_cb; |
| 59 } | 60 } |
| 60 | 61 |
| 61 PipelineStatusCB StartPipeline() { return StartPipeline(false, true); } | 62 PipelineStatusCB StartPipeline() { return StartPipeline(false, true); } |
| 62 | 63 |
| 63 PipelineStatusCB StartPipeline_WithDynamicData() { | 64 PipelineStatusCB StartPipeline_WithDynamicData() { |
| 64 return StartPipeline(false, false); | 65 return StartPipeline(false, false); |
| 65 } | 66 } |
| 66 | 67 |
| 67 PipelineStatusCB StartPipeline_WithStreamingData() { | 68 PipelineStatusCB StartPipeline_WithStreamingData() { |
| 68 return StartPipeline(true, false); | 69 return StartPipeline(true, false); |
| 69 } | 70 } |
| 70 | 71 |
| 71 PipelineStatusCB SeekPipeline(base::TimeDelta time) { | 72 PipelineStatusCB SeekPipeline(base::TimeDelta time) { |
| 72 EXPECT_TRUE(pipeline_controller_.IsStable()); | 73 EXPECT_TRUE(pipeline_controller_.IsStable()); |
| 73 PipelineStatusCB seek_cb; | 74 PipelineStatusCB seek_cb; |
| 74 EXPECT_CALL(pipeline_, Seek(time, _)).WillOnce(SaveArg<1>(&seek_cb)); | 75 EXPECT_CALL(*pipeline_, Seek(time, _)).WillOnce(SaveArg<1>(&seek_cb)); |
| 75 pipeline_controller_.Seek(time, true); | 76 pipeline_controller_.Seek(time, true); |
| 76 Mock::VerifyAndClear(&pipeline_); | 77 Mock::VerifyAndClear(pipeline_); |
| 77 EXPECT_FALSE(pipeline_controller_.IsStable()); | 78 EXPECT_FALSE(pipeline_controller_.IsStable()); |
| 78 return seek_cb; | 79 return seek_cb; |
| 79 } | 80 } |
| 80 | 81 |
| 81 PipelineStatusCB SuspendPipeline() { | 82 PipelineStatusCB SuspendPipeline() { |
| 82 EXPECT_TRUE(pipeline_controller_.IsStable()); | 83 EXPECT_TRUE(pipeline_controller_.IsStable()); |
| 83 PipelineStatusCB suspend_cb; | 84 PipelineStatusCB suspend_cb; |
| 84 EXPECT_CALL(pipeline_, Suspend(_)).WillOnce(SaveArg<0>(&suspend_cb)); | 85 EXPECT_CALL(*pipeline_, Suspend(_)).WillOnce(SaveArg<0>(&suspend_cb)); |
| 85 pipeline_controller_.Suspend(); | 86 pipeline_controller_.Suspend(); |
| 86 Mock::VerifyAndClear(&pipeline_); | 87 Mock::VerifyAndClear(pipeline_); |
| 87 EXPECT_TRUE(pipeline_controller_.IsSuspended()); | 88 EXPECT_TRUE(pipeline_controller_.IsSuspended()); |
| 88 EXPECT_FALSE(pipeline_controller_.IsStable()); | 89 EXPECT_FALSE(pipeline_controller_.IsStable()); |
| 89 EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended()); | 90 EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended()); |
| 90 return suspend_cb; | 91 return suspend_cb; |
| 91 } | 92 } |
| 92 | 93 |
| 93 PipelineStatusCB ResumePipeline() { | 94 PipelineStatusCB ResumePipeline() { |
| 94 EXPECT_TRUE(pipeline_controller_.IsPipelineSuspended()); | 95 EXPECT_TRUE(pipeline_controller_.IsPipelineSuspended()); |
| 95 PipelineStatusCB resume_cb; | 96 PipelineStatusCB resume_cb; |
| 96 EXPECT_CALL(pipeline_, Resume(_, _, _)) | 97 EXPECT_CALL(*pipeline_, Resume(_, _, _)) |
| 97 .WillOnce( | 98 .WillOnce( |
| 98 DoAll(SaveArg<1>(&last_resume_time_), SaveArg<2>(&resume_cb))); | 99 DoAll(SaveArg<1>(&last_resume_time_), SaveArg<2>(&resume_cb))); |
| 99 EXPECT_CALL(pipeline_, GetMediaTime()) | 100 EXPECT_CALL(*pipeline_, GetMediaTime()) |
| 100 .WillRepeatedly(Return(base::TimeDelta())); | 101 .WillRepeatedly(Return(base::TimeDelta())); |
| 101 pipeline_controller_.Resume(); | 102 pipeline_controller_.Resume(); |
| 102 Mock::VerifyAndClear(&pipeline_); | 103 Mock::VerifyAndClear(pipeline_); |
| 103 EXPECT_FALSE(pipeline_controller_.IsSuspended()); | 104 EXPECT_FALSE(pipeline_controller_.IsSuspended()); |
| 104 EXPECT_FALSE(pipeline_controller_.IsStable()); | 105 EXPECT_FALSE(pipeline_controller_.IsStable()); |
| 105 EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended()); | 106 EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended()); |
| 106 return resume_cb; | 107 return resume_cb; |
| 107 } | 108 } |
| 108 | 109 |
| 109 void Complete(const PipelineStatusCB& cb) { | 110 void Complete(const PipelineStatusCB& cb) { |
| 110 cb.Run(PIPELINE_OK); | 111 cb.Run(PIPELINE_OK); |
| 111 base::RunLoop().RunUntilIdle(); | 112 base::RunLoop().RunUntilIdle(); |
| 112 } | 113 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 134 void OnAddTextTrack(const TextTrackConfig& config, | 135 void OnAddTextTrack(const TextTrackConfig& config, |
| 135 const AddTextTrackDoneCB& done_cb) override {} | 136 const AddTextTrackDoneCB& done_cb) override {} |
| 136 void OnWaitingForDecryptionKey() override {} | 137 void OnWaitingForDecryptionKey() override {} |
| 137 void OnVideoNaturalSizeChange(const gfx::Size& size) override {} | 138 void OnVideoNaturalSizeChange(const gfx::Size& size) override {} |
| 138 void OnVideoOpacityChange(bool opaque) override {} | 139 void OnVideoOpacityChange(bool opaque) override {} |
| 139 void OnVideoAverageKeyframeDistanceUpdate() override {} | 140 void OnVideoAverageKeyframeDistanceUpdate() override {} |
| 140 | 141 |
| 141 base::MessageLoop message_loop_; | 142 base::MessageLoop message_loop_; |
| 142 | 143 |
| 143 NiceMock<MockDemuxer> demuxer_; | 144 NiceMock<MockDemuxer> demuxer_; |
| 144 StrictMock<MockPipeline> pipeline_; | 145 StrictMock<MockPipeline>* pipeline_; |
| 145 PipelineController pipeline_controller_; | 146 PipelineController pipeline_controller_; |
| 146 | 147 |
| 147 bool was_seeked_ = false; | 148 bool was_seeked_ = false; |
| 148 bool last_seeked_time_updated_ = false; | 149 bool last_seeked_time_updated_ = false; |
| 149 bool was_suspended_ = false; | 150 bool was_suspended_ = false; |
| 150 bool was_resuming_ = false; | 151 bool was_resuming_ = false; |
| 151 bool was_resumed_ = false; | 152 bool was_resumed_ = false; |
| 152 base::TimeDelta last_resume_time_; | 153 base::TimeDelta last_resume_time_; |
| 153 | 154 |
| 154 DISALLOW_COPY_AND_ASSIGN(PipelineControllerTest); | 155 DISALLOW_COPY_AND_ASSIGN(PipelineControllerTest); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 241 |
| 241 // Create a second seek; the first should be aborted. | 242 // Create a second seek; the first should be aborted. |
| 242 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); | 243 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); |
| 243 EXPECT_CALL(demuxer_, CancelPendingSeek(seek_time_2)); | 244 EXPECT_CALL(demuxer_, CancelPendingSeek(seek_time_2)); |
| 244 pipeline_controller_.Seek(seek_time_2, true); | 245 pipeline_controller_.Seek(seek_time_2, true); |
| 245 base::RunLoop().RunUntilIdle(); | 246 base::RunLoop().RunUntilIdle(); |
| 246 Mock::VerifyAndClear(&demuxer_); | 247 Mock::VerifyAndClear(&demuxer_); |
| 247 | 248 |
| 248 // When the first seek is completed (or aborted) the second should be issued. | 249 // When the first seek is completed (or aborted) the second should be issued. |
| 249 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_2)); | 250 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_2)); |
| 250 EXPECT_CALL(pipeline_, Seek(seek_time_2, _)); | 251 EXPECT_CALL(*pipeline_, Seek(seek_time_2, _)); |
| 251 Complete(seek_cb_1); | 252 Complete(seek_cb_1); |
| 252 } | 253 } |
| 253 | 254 |
| 254 TEST_F(PipelineControllerTest, PendingSuspend) { | 255 TEST_F(PipelineControllerTest, PendingSuspend) { |
| 255 Complete(StartPipeline()); | 256 Complete(StartPipeline()); |
| 256 | 257 |
| 257 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 258 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 258 PipelineStatusCB seek_cb = SeekPipeline(seek_time); | 259 PipelineStatusCB seek_cb = SeekPipeline(seek_time); |
| 259 base::RunLoop().RunUntilIdle(); | 260 base::RunLoop().RunUntilIdle(); |
| 260 | 261 |
| 261 // While the seek is ongoing, request a suspend. | 262 // While the seek is ongoing, request a suspend. |
| 262 // It will be a mock failure if pipeline_.Suspend() is called. | 263 // It will be a mock failure if pipeline_.Suspend() is called. |
| 263 pipeline_controller_.Suspend(); | 264 pipeline_controller_.Suspend(); |
| 264 base::RunLoop().RunUntilIdle(); | 265 base::RunLoop().RunUntilIdle(); |
| 265 | 266 |
| 266 // Expect the suspend to trigger when the seek is completed. | 267 // Expect the suspend to trigger when the seek is completed. |
| 267 EXPECT_CALL(pipeline_, Suspend(_)); | 268 EXPECT_CALL(*pipeline_, Suspend(_)); |
| 268 Complete(seek_cb); | 269 Complete(seek_cb); |
| 269 } | 270 } |
| 270 | 271 |
| 271 TEST_F(PipelineControllerTest, SeekMergesWithResume) { | 272 TEST_F(PipelineControllerTest, SeekMergesWithResume) { |
| 272 Complete(StartPipeline()); | 273 Complete(StartPipeline()); |
| 273 Complete(SuspendPipeline()); | 274 Complete(SuspendPipeline()); |
| 274 | 275 |
| 275 // Request a seek while suspended. | 276 // Request a seek while suspended. |
| 276 // It will be a mock failure if pipeline_.Seek() is called. | 277 // It will be a mock failure if pipeline_.Seek() is called. |
| 277 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 278 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 295 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); | 296 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); |
| 296 pipeline_controller_.Seek(seek_time_2, true); | 297 pipeline_controller_.Seek(seek_time_2, true); |
| 297 base::RunLoop().RunUntilIdle(); | 298 base::RunLoop().RunUntilIdle(); |
| 298 | 299 |
| 299 // Request a third seek. (It should replace the second.) | 300 // Request a third seek. (It should replace the second.) |
| 300 base::TimeDelta seek_time_3 = base::TimeDelta::FromSeconds(15); | 301 base::TimeDelta seek_time_3 = base::TimeDelta::FromSeconds(15); |
| 301 pipeline_controller_.Seek(seek_time_3, true); | 302 pipeline_controller_.Seek(seek_time_3, true); |
| 302 base::RunLoop().RunUntilIdle(); | 303 base::RunLoop().RunUntilIdle(); |
| 303 | 304 |
| 304 // Expect the third seek to trigger when the first seek completes. | 305 // Expect the third seek to trigger when the first seek completes. |
| 305 EXPECT_CALL(pipeline_, Seek(seek_time_3, _)); | 306 EXPECT_CALL(*pipeline_, Seek(seek_time_3, _)); |
| 306 Complete(seek_cb_1); | 307 Complete(seek_cb_1); |
| 307 } | 308 } |
| 308 | 309 |
| 309 TEST_F(PipelineControllerTest, SeekToSeekTimeElided) { | 310 TEST_F(PipelineControllerTest, SeekToSeekTimeElided) { |
| 310 Complete(StartPipeline()); | 311 Complete(StartPipeline()); |
| 311 | 312 |
| 312 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 313 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 313 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time); | 314 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time); |
| 314 base::RunLoop().RunUntilIdle(); | 315 base::RunLoop().RunUntilIdle(); |
| 315 | 316 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 328 | 329 |
| 329 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 330 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 330 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time); | 331 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time); |
| 331 base::RunLoop().RunUntilIdle(); | 332 base::RunLoop().RunUntilIdle(); |
| 332 | 333 |
| 333 // Request a seek to the same time again. | 334 // Request a seek to the same time again. |
| 334 pipeline_controller_.Seek(seek_time, true); | 335 pipeline_controller_.Seek(seek_time, true); |
| 335 base::RunLoop().RunUntilIdle(); | 336 base::RunLoop().RunUntilIdle(); |
| 336 | 337 |
| 337 // Expect the second seek to trigger when the first seek completes. | 338 // Expect the second seek to trigger when the first seek completes. |
| 338 EXPECT_CALL(pipeline_, Seek(seek_time, _)); | 339 EXPECT_CALL(*pipeline_, Seek(seek_time, _)); |
| 339 Complete(seek_cb_1); | 340 Complete(seek_cb_1); |
| 340 } | 341 } |
| 341 | 342 |
| 342 } // namespace media | 343 } // namespace media |
| OLD | NEW |