| 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/run_loop.h" |
| 15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 16 #include "media/base/mock_filters.h" | 17 #include "media/base/mock_filters.h" |
| 17 #include "media/base/pipeline.h" | 18 #include "media/base/pipeline.h" |
| 18 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 21 using ::testing::_; | 22 using ::testing::_; |
| 22 using ::testing::DoAll; | 23 using ::testing::DoAll; |
| 23 using ::testing::Mock; | 24 using ::testing::Mock; |
| 24 using ::testing::NiceMock; | 25 using ::testing::NiceMock; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 .WillRepeatedly(Return(base::TimeDelta())); | 95 .WillRepeatedly(Return(base::TimeDelta())); |
| 95 pipeline_controller_.Resume(); | 96 pipeline_controller_.Resume(); |
| 96 Mock::VerifyAndClear(&pipeline_); | 97 Mock::VerifyAndClear(&pipeline_); |
| 97 EXPECT_FALSE(pipeline_controller_.IsStable()); | 98 EXPECT_FALSE(pipeline_controller_.IsStable()); |
| 98 EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended()); | 99 EXPECT_FALSE(pipeline_controller_.IsPipelineSuspended()); |
| 99 return resume_cb; | 100 return resume_cb; |
| 100 } | 101 } |
| 101 | 102 |
| 102 void Complete(const PipelineStatusCB& cb) { | 103 void Complete(const PipelineStatusCB& cb) { |
| 103 cb.Run(PIPELINE_OK); | 104 cb.Run(PIPELINE_OK); |
| 104 message_loop_.RunUntilIdle(); | 105 base::RunLoop().RunUntilIdle(); |
| 105 } | 106 } |
| 106 | 107 |
| 107 protected: | 108 protected: |
| 108 std::unique_ptr<Renderer> CreateRenderer() { | 109 std::unique_ptr<Renderer> CreateRenderer() { |
| 109 return std::unique_ptr<Renderer>(); | 110 return std::unique_ptr<Renderer>(); |
| 110 } | 111 } |
| 111 | 112 |
| 112 void OnSeeked(bool time_updated) { | 113 void OnSeeked(bool time_updated) { |
| 113 was_seeked_ = true; | 114 was_seeked_ = true; |
| 114 last_seeked_time_updated_ = time_updated; | 115 last_seeked_time_updated_ = time_updated; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 TEST_F(PipelineControllerTest, Seek) { | 173 TEST_F(PipelineControllerTest, Seek) { |
| 173 // Normal seeking should not result in a cancel. | 174 // Normal seeking should not result in a cancel. |
| 174 EXPECT_CALL(demuxer_, CancelPendingSeek(_)).Times(0); | 175 EXPECT_CALL(demuxer_, CancelPendingSeek(_)).Times(0); |
| 175 | 176 |
| 176 Complete(StartPipeline()); | 177 Complete(StartPipeline()); |
| 177 was_seeked_ = false; | 178 was_seeked_ = false; |
| 178 | 179 |
| 179 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 180 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 180 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time)); | 181 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time)); |
| 181 PipelineStatusCB seek_cb = SeekPipeline(seek_time); | 182 PipelineStatusCB seek_cb = SeekPipeline(seek_time); |
| 182 message_loop_.RunUntilIdle(); | 183 base::RunLoop().RunUntilIdle(); |
| 183 EXPECT_FALSE(was_seeked_); | 184 EXPECT_FALSE(was_seeked_); |
| 184 | 185 |
| 185 Complete(seek_cb); | 186 Complete(seek_cb); |
| 186 EXPECT_TRUE(was_seeked_); | 187 EXPECT_TRUE(was_seeked_); |
| 187 EXPECT_TRUE(pipeline_controller_.IsStable()); | 188 EXPECT_TRUE(pipeline_controller_.IsStable()); |
| 188 } | 189 } |
| 189 | 190 |
| 190 TEST_F(PipelineControllerTest, SuspendResumeTime) { | 191 TEST_F(PipelineControllerTest, SuspendResumeTime) { |
| 191 Complete(StartPipeline()); | 192 Complete(StartPipeline()); |
| 192 Complete(SuspendPipeline()); | 193 Complete(SuspendPipeline()); |
| 193 | 194 |
| 194 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 195 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 195 pipeline_controller_.Seek(seek_time, true); | 196 pipeline_controller_.Seek(seek_time, true); |
| 196 message_loop_.RunUntilIdle(); | 197 base::RunLoop().RunUntilIdle(); |
| 197 | 198 |
| 198 Complete(ResumePipeline()); | 199 Complete(ResumePipeline()); |
| 199 EXPECT_EQ(seek_time, last_resume_time_); | 200 EXPECT_EQ(seek_time, last_resume_time_); |
| 200 } | 201 } |
| 201 | 202 |
| 202 TEST_F(PipelineControllerTest, SuspendResumeTime_WithStreamingData) { | 203 TEST_F(PipelineControllerTest, SuspendResumeTime_WithStreamingData) { |
| 203 Complete(StartPipeline_WithStreamingData()); | 204 Complete(StartPipeline_WithStreamingData()); |
| 204 Complete(SuspendPipeline()); | 205 Complete(SuspendPipeline()); |
| 205 | 206 |
| 206 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 207 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 207 pipeline_controller_.Seek(seek_time, true); | 208 pipeline_controller_.Seek(seek_time, true); |
| 208 message_loop_.RunUntilIdle(); | 209 base::RunLoop().RunUntilIdle(); |
| 209 | 210 |
| 210 Complete(ResumePipeline()); | 211 Complete(ResumePipeline()); |
| 211 EXPECT_EQ(base::TimeDelta(), last_resume_time_); | 212 EXPECT_EQ(base::TimeDelta(), last_resume_time_); |
| 212 } | 213 } |
| 213 | 214 |
| 214 TEST_F(PipelineControllerTest, SeekAborted) { | 215 TEST_F(PipelineControllerTest, SeekAborted) { |
| 215 Complete(StartPipeline()); | 216 Complete(StartPipeline()); |
| 216 | 217 |
| 217 // Create a first pending seek. | 218 // Create a first pending seek. |
| 218 base::TimeDelta seek_time_1 = base::TimeDelta::FromSeconds(5); | 219 base::TimeDelta seek_time_1 = base::TimeDelta::FromSeconds(5); |
| 219 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_1)); | 220 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_1)); |
| 220 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time_1); | 221 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time_1); |
| 221 message_loop_.RunUntilIdle(); | 222 base::RunLoop().RunUntilIdle(); |
| 222 Mock::VerifyAndClear(&demuxer_); | 223 Mock::VerifyAndClear(&demuxer_); |
| 223 | 224 |
| 224 // Create a second seek; the first should be aborted. | 225 // Create a second seek; the first should be aborted. |
| 225 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); | 226 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); |
| 226 EXPECT_CALL(demuxer_, CancelPendingSeek(seek_time_2)); | 227 EXPECT_CALL(demuxer_, CancelPendingSeek(seek_time_2)); |
| 227 pipeline_controller_.Seek(seek_time_2, true); | 228 pipeline_controller_.Seek(seek_time_2, true); |
| 228 message_loop_.RunUntilIdle(); | 229 base::RunLoop().RunUntilIdle(); |
| 229 Mock::VerifyAndClear(&demuxer_); | 230 Mock::VerifyAndClear(&demuxer_); |
| 230 | 231 |
| 231 // When the first seek is completed (or aborted) the second should be issued. | 232 // When the first seek is completed (or aborted) the second should be issued. |
| 232 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_2)); | 233 EXPECT_CALL(demuxer_, StartWaitingForSeek(seek_time_2)); |
| 233 EXPECT_CALL(pipeline_, Seek(seek_time_2, _)); | 234 EXPECT_CALL(pipeline_, Seek(seek_time_2, _)); |
| 234 Complete(seek_cb_1); | 235 Complete(seek_cb_1); |
| 235 } | 236 } |
| 236 | 237 |
| 237 TEST_F(PipelineControllerTest, PendingSuspend) { | 238 TEST_F(PipelineControllerTest, PendingSuspend) { |
| 238 Complete(StartPipeline()); | 239 Complete(StartPipeline()); |
| 239 | 240 |
| 240 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 241 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 241 PipelineStatusCB seek_cb = SeekPipeline(seek_time); | 242 PipelineStatusCB seek_cb = SeekPipeline(seek_time); |
| 242 message_loop_.RunUntilIdle(); | 243 base::RunLoop().RunUntilIdle(); |
| 243 | 244 |
| 244 // While the seek is ongoing, request a suspend. | 245 // While the seek is ongoing, request a suspend. |
| 245 // It will be a mock failure if pipeline_.Suspend() is called. | 246 // It will be a mock failure if pipeline_.Suspend() is called. |
| 246 pipeline_controller_.Suspend(); | 247 pipeline_controller_.Suspend(); |
| 247 message_loop_.RunUntilIdle(); | 248 base::RunLoop().RunUntilIdle(); |
| 248 | 249 |
| 249 // Expect the suspend to trigger when the seek is completed. | 250 // Expect the suspend to trigger when the seek is completed. |
| 250 EXPECT_CALL(pipeline_, Suspend(_)); | 251 EXPECT_CALL(pipeline_, Suspend(_)); |
| 251 Complete(seek_cb); | 252 Complete(seek_cb); |
| 252 } | 253 } |
| 253 | 254 |
| 254 TEST_F(PipelineControllerTest, SeekMergesWithResume) { | 255 TEST_F(PipelineControllerTest, SeekMergesWithResume) { |
| 255 Complete(StartPipeline()); | 256 Complete(StartPipeline()); |
| 256 Complete(SuspendPipeline()); | 257 Complete(SuspendPipeline()); |
| 257 | 258 |
| 258 // Request a seek while suspended. | 259 // Request a seek while suspended. |
| 259 // It will be a mock failure if pipeline_.Seek() is called. | 260 // It will be a mock failure if pipeline_.Seek() is called. |
| 260 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 261 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 261 pipeline_controller_.Seek(seek_time, true); | 262 pipeline_controller_.Seek(seek_time, true); |
| 262 message_loop_.RunUntilIdle(); | 263 base::RunLoop().RunUntilIdle(); |
| 263 | 264 |
| 264 // Resume and verify the resume time includes the seek. | 265 // Resume and verify the resume time includes the seek. |
| 265 Complete(ResumePipeline()); | 266 Complete(ResumePipeline()); |
| 266 EXPECT_EQ(seek_time, last_resume_time_); | 267 EXPECT_EQ(seek_time, last_resume_time_); |
| 267 EXPECT_TRUE(last_seeked_time_updated_); | 268 EXPECT_TRUE(last_seeked_time_updated_); |
| 268 } | 269 } |
| 269 | 270 |
| 270 TEST_F(PipelineControllerTest, SeekMergesWithSeek) { | 271 TEST_F(PipelineControllerTest, SeekMergesWithSeek) { |
| 271 Complete(StartPipeline()); | 272 Complete(StartPipeline()); |
| 272 | 273 |
| 273 base::TimeDelta seek_time_1 = base::TimeDelta::FromSeconds(5); | 274 base::TimeDelta seek_time_1 = base::TimeDelta::FromSeconds(5); |
| 274 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time_1); | 275 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time_1); |
| 275 message_loop_.RunUntilIdle(); | 276 base::RunLoop().RunUntilIdle(); |
| 276 | 277 |
| 277 // Request another seek while the first is ongoing. | 278 // Request another seek while the first is ongoing. |
| 278 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); | 279 base::TimeDelta seek_time_2 = base::TimeDelta::FromSeconds(10); |
| 279 pipeline_controller_.Seek(seek_time_2, true); | 280 pipeline_controller_.Seek(seek_time_2, true); |
| 280 message_loop_.RunUntilIdle(); | 281 base::RunLoop().RunUntilIdle(); |
| 281 | 282 |
| 282 // Request a third seek. (It should replace the second.) | 283 // Request a third seek. (It should replace the second.) |
| 283 base::TimeDelta seek_time_3 = base::TimeDelta::FromSeconds(15); | 284 base::TimeDelta seek_time_3 = base::TimeDelta::FromSeconds(15); |
| 284 pipeline_controller_.Seek(seek_time_3, true); | 285 pipeline_controller_.Seek(seek_time_3, true); |
| 285 message_loop_.RunUntilIdle(); | 286 base::RunLoop().RunUntilIdle(); |
| 286 | 287 |
| 287 // Expect the third seek to trigger when the first seek completes. | 288 // Expect the third seek to trigger when the first seek completes. |
| 288 EXPECT_CALL(pipeline_, Seek(seek_time_3, _)); | 289 EXPECT_CALL(pipeline_, Seek(seek_time_3, _)); |
| 289 Complete(seek_cb_1); | 290 Complete(seek_cb_1); |
| 290 } | 291 } |
| 291 | 292 |
| 292 TEST_F(PipelineControllerTest, SeekToSeekTimeElided) { | 293 TEST_F(PipelineControllerTest, SeekToSeekTimeElided) { |
| 293 Complete(StartPipeline()); | 294 Complete(StartPipeline()); |
| 294 | 295 |
| 295 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 296 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 296 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time); | 297 PipelineStatusCB seek_cb_1 = SeekPipeline(seek_time); |
| 297 message_loop_.RunUntilIdle(); | 298 base::RunLoop().RunUntilIdle(); |
| 298 | 299 |
| 299 // Request a seek to the same time again. | 300 // Request a seek to the same time again. |
| 300 pipeline_controller_.Seek(seek_time, true); | 301 pipeline_controller_.Seek(seek_time, true); |
| 301 message_loop_.RunUntilIdle(); | 302 base::RunLoop().RunUntilIdle(); |
| 302 | 303 |
| 303 // Complete the first seek. | 304 // Complete the first seek. |
| 304 // It would be a mock error if the second seek was dispatched here. | 305 // It would be a mock error if the second seek was dispatched here. |
| 305 Complete(seek_cb_1); | 306 Complete(seek_cb_1); |
| 306 EXPECT_TRUE(pipeline_controller_.IsStable()); | 307 EXPECT_TRUE(pipeline_controller_.IsStable()); |
| 307 } | 308 } |
| 308 | 309 |
| 309 TEST_F(PipelineControllerTest, SeekToSeekTimeNotElided) { | 310 TEST_F(PipelineControllerTest, SeekToSeekTimeNotElided) { |
| 310 Complete(StartPipeline_WithDynamicData()); | 311 Complete(StartPipeline_WithDynamicData()); |
| 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 message_loop_.RunUntilIdle(); | 315 base::RunLoop().RunUntilIdle(); |
| 315 | 316 |
| 316 // Request a seek to the same time again. | 317 // Request a seek to the same time again. |
| 317 pipeline_controller_.Seek(seek_time, true); | 318 pipeline_controller_.Seek(seek_time, true); |
| 318 message_loop_.RunUntilIdle(); | 319 base::RunLoop().RunUntilIdle(); |
| 319 | 320 |
| 320 // Expect the second seek to trigger when the first seek completes. | 321 // Expect the second seek to trigger when the first seek completes. |
| 321 EXPECT_CALL(pipeline_, Seek(seek_time, _)); | 322 EXPECT_CALL(pipeline_, Seek(seek_time, _)); |
| 322 Complete(seek_cb_1); | 323 Complete(seek_cb_1); |
| 323 } | 324 } |
| 324 | 325 |
| 325 } // namespace media | 326 } // namespace media |
| OLD | NEW |