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 "base/bind.h" 6 #include "base/callback_helpers.h" 7 #include "base/message_loop/message_loop.h" 8 #include "media/base/gmock_callback_support.h" 9 #include "media/base/mock_filters.h" 10 #include "media/base/test_helpers.h" 11 #include "media/filters/fake_demuxer_stream.h" 12 #include "media/filters/fake_video_decoder.h" 13 #include "media/filters/video_frame_stream.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 using ::testing::_; 17 using ::testing::Assign; 18 using ::testing::Invoke; 19 using ::testing::NiceMock; 20 using ::testing::Return; 21 using ::testing::SaveArg; 22 23 static const int kNumConfigs = 3; 24 static const int kNumBuffersInOneConfig = 5; 25 static const int kDecodingDelay = 7; 26 27 namespace media { 28 29 class VideoFrameStreamTest : public testing::TestWithParam<bool> { 30 public: 31 VideoFrameStreamTest() 32 : demuxer_stream_(new FakeDemuxerStream(kNumConfigs, 33 kNumBuffersInOneConfig, 34 GetParam())), 35 decryptor_(new NiceMock<MockDecryptor>()), 36 decoder_(new FakeVideoDecoder(kDecodingDelay)), 37 is_initialized_(false), 38 num_decoded_frames_(0), 39 pending_read_(false), 40 pending_reset_(false), 41 pending_stop_(false), 42 total_bytes_decoded_(0) { 43 ScopedVector<VideoDecoder> decoders; 44 decoders.push_back(decoder_); 45 46 video_frame_stream_.reset(new VideoFrameStream( 47 message_loop_.message_loop_proxy(), 48 decoders.Pass(), 49 base::Bind(&VideoFrameStreamTest::SetDecryptorReadyCallback, 50 base::Unretained(this)))); 51 52 EXPECT_CALL(*this, SetDecryptorReadyCallback(_)) 53 .WillRepeatedly(RunCallback<0>(decryptor_.get())); 54 55 // Decryptor can only decrypt (not decrypt-and-decode) so that 56 // DecryptingDemuxerStream will be used. 57 EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _)) 58 .WillRepeatedly(RunCallback<1>(false)); 59 EXPECT_CALL(*decryptor_, Decrypt(_, _, _)) 60 .WillRepeatedly(Invoke(this, &VideoFrameStreamTest::Decrypt)); 61 } 62 63 ~VideoFrameStreamTest() { 64 DCHECK(!pending_read_); 65 DCHECK(!pending_reset_); 66 DCHECK(!pending_stop_); 67 68 // Check that the pipeline statistics callback was fired correctly. 69 if (decoder_) 70 EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_); 71 72 if (is_initialized_) 73 Stop(); 74 EXPECT_FALSE(is_initialized_); 75 } 76 77 MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&)); 78 MOCK_METHOD2(OnInitialized, void(bool, bool)); 79 80 void OnStatistics(const PipelineStatistics& statistics) { 81 total_bytes_decoded_ += statistics.video_bytes_decoded; 82 } 83 84 // Fake Decrypt() function used by DecryptingDemuxerStream. It does nothing 85 // but removes the DecryptConfig to make the buffer unencrypted. 86 void Decrypt(Decryptor::StreamType stream_type, 87 const scoped_refptr<DecoderBuffer>& encrypted, 88 const Decryptor::DecryptCB& decrypt_cb) { 89 DCHECK_EQ(stream_type, Decryptor::kVideo); 90 scoped_refptr<DecoderBuffer> decrypted = DecoderBuffer::CopyFrom( 91 encrypted->data(), encrypted->data_size()); 92 decrypted->set_timestamp(encrypted->timestamp()); 93 decrypted->set_duration(encrypted->duration()); 94 decrypt_cb.Run(Decryptor::kSuccess, decrypted); 95 } 96 97 // Callback for VideoFrameStream::Read(). 98 void FrameReady(VideoFrameStream::Status status, 99 const scoped_refptr<VideoFrame>& frame) { 100 DCHECK(pending_read_); 101 // TODO(xhwang): Add test cases where the fake decoder returns error or 102 // the fake demuxer aborts demuxer read. 103 ASSERT_TRUE(status == VideoFrameStream::OK || 104 status == VideoFrameStream::ABORTED); 105 frame_read_ = frame; 106 if (frame.get() && !frame->IsEndOfStream()) 107 num_decoded_frames_++; 108 pending_read_ = false; 109 } 110 111 void OnReset() { 112 DCHECK(!pending_read_); 113 DCHECK(pending_reset_); 114 pending_reset_ = false; 115 } 116 117 void OnStopped() { 118 DCHECK(!pending_read_); 119 DCHECK(!pending_reset_); 120 DCHECK(pending_stop_); 121 pending_stop_ = false; 122 is_initialized_ = false; 123 } 124 125 void ReadUntilPending() { 126 do { 127 frame_read_ = NULL; 128 pending_read_ = true; 129 video_frame_stream_->Read(base::Bind( 130 &VideoFrameStreamTest::FrameReady, base::Unretained(this))); 131 message_loop_.RunUntilIdle(); 132 } while (!pending_read_); 133 } 134 135 enum PendingState { 136 NOT_PENDING, 137 DEMUXER_READ_NORMAL, 138 DEMUXER_READ_CONFIG_CHANGE, 139 DECODER_INIT, 140 DECODER_REINIT, 141 DECODER_READ, 142 DECODER_RESET, 143 DECODER_STOP 144 }; 145 146 void EnterPendingState(PendingState state) { 147 DCHECK_NE(state, NOT_PENDING); 148 switch (state) { 149 case DEMUXER_READ_NORMAL: 150 demuxer_stream_->HoldNextRead(); 151 ReadUntilPending(); 152 break; 153 154 case DEMUXER_READ_CONFIG_CHANGE: 155 demuxer_stream_->HoldNextConfigChangeRead(); 156 ReadUntilPending(); 157 break; 158 159 case DECODER_INIT: 160 decoder_->HoldNextInit(); 161 video_frame_stream_->Initialize( 162 demuxer_stream_.get(), 163 base::Bind(&VideoFrameStreamTest::OnStatistics, 164 base::Unretained(this)), 165 base::Bind(&VideoFrameStreamTest::OnInitialized, 166 base::Unretained(this))); 167 message_loop_.RunUntilIdle(); 168 break; 169 170 case DECODER_REINIT: 171 decoder_->HoldNextInit(); 172 ReadUntilPending(); 173 break; 174 175 case DECODER_READ: 176 decoder_->HoldNextRead(); 177 ReadUntilPending(); 178 break; 179 180 case DECODER_RESET: 181 decoder_->HoldNextReset(); 182 pending_reset_ = true; 183 video_frame_stream_->Reset(base::Bind(&VideoFrameStreamTest::OnReset, 184 base::Unretained(this))); 185 message_loop_.RunUntilIdle(); 186 break; 187 188 case DECODER_STOP: 189 decoder_->HoldNextStop(); 190 pending_stop_ = true; 191 video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped, 192 base::Unretained(this))); 193 message_loop_.RunUntilIdle(); 194 break; 195 196 case NOT_PENDING: 197 NOTREACHED(); 198 break; 199 } 200 } 201 202 void SatisfyPendingCallback(PendingState state) { 203 DCHECK_NE(state, NOT_PENDING); 204 switch (state) { 205 case DEMUXER_READ_NORMAL: 206 case DEMUXER_READ_CONFIG_CHANGE: 207 demuxer_stream_->SatisfyRead(); 208 break; 209 210 case DECODER_INIT: 211 EXPECT_CALL(*this, OnInitialized(true, false)) 212 .WillOnce(SaveArg<0>(&is_initialized_)); 213 decoder_->SatisfyInit(); 214 break; 215 216 case DECODER_REINIT: 217 decoder_->SatisfyInit(); 218 break; 219 220 case DECODER_READ: 221 DCHECK(pending_read_); 222 decoder_->SatisfyRead(); 223 break; 224 225 case DECODER_RESET: 226 DCHECK(pending_reset_); 227 decoder_->SatisfyReset(); 228 break; 229 230 case DECODER_STOP: 231 DCHECK(pending_stop_); 232 decoder_->SatisfyStop(); 233 break; 234 235 case NOT_PENDING: 236 NOTREACHED(); 237 break; 238 } 239 240 message_loop_.RunUntilIdle(); 241 if (!is_initialized_) 242 decoder_ = NULL; 243 } 244 245 void Initialize() { 246 EnterPendingState(DECODER_INIT); 247 SatisfyPendingCallback(DECODER_INIT); 248 } 249 250 void Read() { 251 EnterPendingState(DECODER_READ); 252 SatisfyPendingCallback(DECODER_READ); 253 } 254 255 void Reset() { 256 EnterPendingState(DECODER_RESET); 257 SatisfyPendingCallback(DECODER_RESET); 258 } 259 260 void Stop() { 261 EnterPendingState(DECODER_STOP); 262 SatisfyPendingCallback(DECODER_STOP); 263 } 264 265 base::MessageLoop message_loop_; 266 267 scoped_ptr<VideoFrameStream> video_frame_stream_; 268 scoped_ptr<FakeDemuxerStream> demuxer_stream_; 269 // Use NiceMock since we don't care about most of calls on the decryptor, 270 // e.g. RegisterNewKeyCB(). 271 scoped_ptr<NiceMock<MockDecryptor> > decryptor_; 272 FakeVideoDecoder* decoder_; // Owned by |video_frame_stream_|. 273 274 bool is_initialized_; 275 int num_decoded_frames_; 276 bool pending_read_; 277 bool pending_reset_; 278 bool pending_stop_; 279 int total_bytes_decoded_; 280 scoped_refptr<VideoFrame> frame_read_; 281 282 private: 283 DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest); 284 }; 285 286 INSTANTIATE_TEST_CASE_P(Clear, VideoFrameStreamTest, testing::Values(false)); 287 INSTANTIATE_TEST_CASE_P(Encrypted, VideoFrameStreamTest, testing::Values(true)); 288 289 TEST_P(VideoFrameStreamTest, Initialization) { 290 Initialize(); 291 } 292 293 TEST_P(VideoFrameStreamTest, ReadOneFrame) { 294 Initialize(); 295 Read(); 296 } 297 298 TEST_P(VideoFrameStreamTest, ReadAllFrames) { 299 Initialize(); 300 do { 301 Read(); 302 } while (frame_read_.get() && !frame_read_->IsEndOfStream()); 303 304 const int total_num_frames = kNumConfigs * kNumBuffersInOneConfig; 305 DCHECK_EQ(num_decoded_frames_, total_num_frames); 306 } 307 308 TEST_P(VideoFrameStreamTest, Read_AfterReset) { 309 Initialize(); 310 Reset(); 311 Read(); 312 Reset(); 313 Read(); 314 } 315 316 // No Reset() before initialization is successfully completed. 317 318 TEST_P(VideoFrameStreamTest, Reset_AfterInitialization) { 319 Initialize(); 320 Reset(); 321 Read(); 322 } 323 324 TEST_P(VideoFrameStreamTest, Reset_DuringReinitialization) { 325 Initialize(); 326 EnterPendingState(DECODER_REINIT); 327 // VideoDecoder::Reset() is not called when we reset during reinitialization. 328 pending_reset_ = true; 329 video_frame_stream_->Reset( 330 base::Bind(&VideoFrameStreamTest::OnReset, base::Unretained(this))); 331 SatisfyPendingCallback(DECODER_REINIT); 332 Read(); 333 } 334 335 TEST_P(VideoFrameStreamTest, Reset_AfterReinitialization) { 336 Initialize(); 337 EnterPendingState(DECODER_REINIT); 338 SatisfyPendingCallback(DECODER_REINIT); 339 Reset(); 340 Read(); 341 } 342 343 TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_Normal) { 344 Initialize(); 345 EnterPendingState(DEMUXER_READ_NORMAL); 346 EnterPendingState(DECODER_RESET); 347 SatisfyPendingCallback(DEMUXER_READ_NORMAL); 348 SatisfyPendingCallback(DECODER_RESET); 349 Read(); 350 } 351 352 TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_ConfigChange) { 353 Initialize(); 354 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 355 EnterPendingState(DECODER_RESET); 356 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 357 SatisfyPendingCallback(DECODER_RESET); 358 Read(); 359 } 360 361 TEST_P(VideoFrameStreamTest, Reset_DuringNormalDecoderRead) { 362 Initialize(); 363 EnterPendingState(DECODER_READ); 364 EnterPendingState(DECODER_RESET); 365 SatisfyPendingCallback(DECODER_READ); 366 SatisfyPendingCallback(DECODER_RESET); 367 Read(); 368 } 369 370 TEST_P(VideoFrameStreamTest, Reset_AfterNormalRead) { 371 Initialize(); 372 Read(); 373 Reset(); 374 Read(); 375 } 376 377 TEST_P(VideoFrameStreamTest, Reset_AfterDemuxerRead_ConfigChange) { 378 Initialize(); 379 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 380 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 381 Reset(); 382 Read(); 383 } 384 385 TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) { 386 pending_stop_ = true; 387 video_frame_stream_->Stop( 388 base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this))); 389 message_loop_.RunUntilIdle(); 390 } 391 392 TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) { 393 EnterPendingState(DECODER_INIT); 394 EnterPendingState(DECODER_STOP); 395 SatisfyPendingCallback(DECODER_INIT); 396 SatisfyPendingCallback(DECODER_STOP); 397 } 398 399 TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) { 400 Initialize(); 401 Stop(); 402 } 403 404 TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) { 405 Initialize(); 406 EnterPendingState(DECODER_REINIT); 407 EnterPendingState(DECODER_STOP); 408 SatisfyPendingCallback(DECODER_REINIT); 409 SatisfyPendingCallback(DECODER_STOP); 410 } 411 412 TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) { 413 Initialize(); 414 EnterPendingState(DECODER_REINIT); 415 SatisfyPendingCallback(DECODER_REINIT); 416 Stop(); 417 } 418 419 TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) { 420 Initialize(); 421 EnterPendingState(DEMUXER_READ_NORMAL); 422 EnterPendingState(DECODER_STOP); 423 SatisfyPendingCallback(DEMUXER_READ_NORMAL); 424 SatisfyPendingCallback(DECODER_STOP); 425 } 426 427 TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) { 428 Initialize(); 429 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 430 EnterPendingState(DECODER_STOP); 431 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 432 SatisfyPendingCallback(DECODER_STOP); 433 } 434 435 TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderRead) { 436 Initialize(); 437 EnterPendingState(DECODER_READ); 438 EnterPendingState(DECODER_STOP); 439 SatisfyPendingCallback(DECODER_READ); 440 SatisfyPendingCallback(DECODER_STOP); 441 } 442 443 TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) { 444 Initialize(); 445 Read(); 446 Stop(); 447 } 448 449 TEST_P(VideoFrameStreamTest, Stop_AfterConfigChangeRead) { 450 Initialize(); 451 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 452 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 453 Stop(); 454 } 455 456 TEST_P(VideoFrameStreamTest, Stop_DuringReset) { 457 Initialize(); 458 EnterPendingState(DECODER_RESET); 459 EnterPendingState(DECODER_STOP); 460 SatisfyPendingCallback(DECODER_RESET); 461 SatisfyPendingCallback(DECODER_STOP); 462 } 463 464 TEST_P(VideoFrameStreamTest, Stop_AfterReset) { 465 Initialize(); 466 Reset(); 467 Stop(); 468 } 469 470 TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) { 471 Initialize(); 472 EnterPendingState(DECODER_READ); 473 EnterPendingState(DECODER_RESET); 474 EnterPendingState(DECODER_STOP); 475 SatisfyPendingCallback(DECODER_READ); 476 SatisfyPendingCallback(DECODER_RESET); 477 SatisfyPendingCallback(DECODER_STOP); 478 } 479 480 TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) { 481 Initialize(); 482 EnterPendingState(DECODER_READ); 483 EnterPendingState(DECODER_RESET); 484 SatisfyPendingCallback(DECODER_READ); 485 EnterPendingState(DECODER_STOP); 486 SatisfyPendingCallback(DECODER_RESET); 487 SatisfyPendingCallback(DECODER_STOP); 488 } 489 490 TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) { 491 Initialize(); 492 Read(); 493 Reset(); 494 Stop(); 495 } 496 497 } // namespace media 498