video_frame_stream_unittest.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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 16using ::testing::_; 17using ::testing::Assign; 18using ::testing::Invoke; 19using ::testing::NiceMock; 20using ::testing::Return; 21using ::testing::SaveArg; 22 23static const int kNumConfigs = 3; 24static const int kNumBuffersInOneConfig = 5; 25static const int kDecodingDelay = 7; 26 27namespace media { 28 29class 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(VideoDecoder::Status status, 99 const scoped_refptr<VideoFrame>& frame) { 100 DCHECK(pending_read_); 101 ASSERT_EQ(VideoDecoder::kOk, status); 102 frame_read_ = frame; 103 if (frame.get() && !frame->IsEndOfStream()) 104 num_decoded_frames_++; 105 pending_read_ = false; 106 } 107 108 void OnReset() { 109 DCHECK(!pending_read_); 110 DCHECK(pending_reset_); 111 pending_reset_ = false; 112 } 113 114 void OnStopped() { 115 DCHECK(!pending_read_); 116 DCHECK(!pending_reset_); 117 DCHECK(pending_stop_); 118 pending_stop_ = false; 119 is_initialized_ = false; 120 } 121 122 void ReadUntilPending() { 123 do { 124 frame_read_ = NULL; 125 pending_read_ = true; 126 video_frame_stream_->Read(base::Bind( 127 &VideoFrameStreamTest::FrameReady, base::Unretained(this))); 128 message_loop_.RunUntilIdle(); 129 } while (!pending_read_); 130 } 131 132 enum PendingState { 133 NOT_PENDING, 134 DEMUXER_READ_NORMAL, 135 DEMUXER_READ_CONFIG_CHANGE, 136 DECODER_INIT, 137 DECODER_REINIT, 138 DECODER_READ, 139 DECODER_RESET, 140 DECODER_STOP 141 }; 142 143 void EnterPendingState(PendingState state) { 144 DCHECK_NE(state, NOT_PENDING); 145 switch (state) { 146 case DEMUXER_READ_NORMAL: 147 demuxer_stream_->HoldNextRead(); 148 ReadUntilPending(); 149 break; 150 151 case DEMUXER_READ_CONFIG_CHANGE: 152 demuxer_stream_->HoldNextConfigChangeRead(); 153 ReadUntilPending(); 154 break; 155 156 case DECODER_INIT: 157 decoder_->HoldNextInit(); 158 video_frame_stream_->Initialize( 159 demuxer_stream_.get(), 160 base::Bind(&VideoFrameStreamTest::OnStatistics, 161 base::Unretained(this)), 162 base::Bind(&VideoFrameStreamTest::OnInitialized, 163 base::Unretained(this))); 164 message_loop_.RunUntilIdle(); 165 break; 166 167 case DECODER_REINIT: 168 decoder_->HoldNextInit(); 169 ReadUntilPending(); 170 break; 171 172 case DECODER_READ: 173 decoder_->HoldNextRead(); 174 ReadUntilPending(); 175 break; 176 177 case DECODER_RESET: 178 decoder_->HoldNextReset(); 179 pending_reset_ = true; 180 video_frame_stream_->Reset(base::Bind(&VideoFrameStreamTest::OnReset, 181 base::Unretained(this))); 182 message_loop_.RunUntilIdle(); 183 break; 184 185 case DECODER_STOP: 186 decoder_->HoldNextStop(); 187 pending_stop_ = true; 188 video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped, 189 base::Unretained(this))); 190 message_loop_.RunUntilIdle(); 191 break; 192 193 case NOT_PENDING: 194 NOTREACHED(); 195 break; 196 } 197 } 198 199 void SatisfyPendingCallback(PendingState state) { 200 DCHECK_NE(state, NOT_PENDING); 201 switch (state) { 202 case DEMUXER_READ_NORMAL: 203 case DEMUXER_READ_CONFIG_CHANGE: 204 demuxer_stream_->SatisfyRead(); 205 break; 206 207 case DECODER_INIT: 208 EXPECT_CALL(*this, OnInitialized(true, false)) 209 .WillOnce(SaveArg<0>(&is_initialized_)); 210 decoder_->SatisfyInit(); 211 break; 212 213 case DECODER_REINIT: 214 decoder_->SatisfyInit(); 215 break; 216 217 case DECODER_READ: 218 DCHECK(pending_read_); 219 decoder_->SatisfyRead(); 220 break; 221 222 case DECODER_RESET: 223 DCHECK(pending_reset_); 224 decoder_->SatisfyReset(); 225 break; 226 227 case DECODER_STOP: 228 DCHECK(pending_stop_); 229 decoder_->SatisfyStop(); 230 break; 231 232 case NOT_PENDING: 233 NOTREACHED(); 234 break; 235 } 236 237 message_loop_.RunUntilIdle(); 238 if (!is_initialized_) 239 decoder_ = NULL; 240 } 241 242 void Initialize() { 243 EnterPendingState(DECODER_INIT); 244 SatisfyPendingCallback(DECODER_INIT); 245 } 246 247 void Read() { 248 EnterPendingState(DECODER_READ); 249 SatisfyPendingCallback(DECODER_READ); 250 } 251 252 void Reset() { 253 EnterPendingState(DECODER_RESET); 254 SatisfyPendingCallback(DECODER_RESET); 255 } 256 257 void Stop() { 258 EnterPendingState(DECODER_STOP); 259 SatisfyPendingCallback(DECODER_STOP); 260 } 261 262 base::MessageLoop message_loop_; 263 264 scoped_ptr<VideoFrameStream> video_frame_stream_; 265 scoped_ptr<FakeDemuxerStream> demuxer_stream_; 266 // Use NiceMock since we don't care about most of calls on the decryptor, 267 // e.g. RegisterNewKeyCB(). 268 scoped_ptr<NiceMock<MockDecryptor> > decryptor_; 269 FakeVideoDecoder* decoder_; // Owned by |video_frame_stream_|. 270 271 bool is_initialized_; 272 int num_decoded_frames_; 273 bool pending_read_; 274 bool pending_reset_; 275 bool pending_stop_; 276 int total_bytes_decoded_; 277 scoped_refptr<VideoFrame> frame_read_; 278 279 private: 280 DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest); 281}; 282 283INSTANTIATE_TEST_CASE_P(Clear, VideoFrameStreamTest, testing::Values(false)); 284INSTANTIATE_TEST_CASE_P(Encrypted, VideoFrameStreamTest, testing::Values(true)); 285 286TEST_P(VideoFrameStreamTest, Initialization) { 287 Initialize(); 288} 289 290TEST_P(VideoFrameStreamTest, ReadOneFrame) { 291 Initialize(); 292 Read(); 293} 294 295TEST_P(VideoFrameStreamTest, ReadAllFrames) { 296 Initialize(); 297 do { 298 Read(); 299 } while (frame_read_.get() && !frame_read_->IsEndOfStream()); 300 301 const int total_num_frames = kNumConfigs * kNumBuffersInOneConfig; 302 DCHECK_EQ(num_decoded_frames_, total_num_frames); 303} 304 305TEST_P(VideoFrameStreamTest, Read_AfterReset) { 306 Initialize(); 307 Reset(); 308 Read(); 309 Reset(); 310 Read(); 311} 312 313// No Reset() before initialization is successfully completed. 314 315TEST_P(VideoFrameStreamTest, Reset_AfterInitialization) { 316 Initialize(); 317 Reset(); 318 Read(); 319} 320 321TEST_P(VideoFrameStreamTest, Reset_DuringReinitialization) { 322 Initialize(); 323 EnterPendingState(DECODER_REINIT); 324 // VideoDecoder::Reset() is not called when we reset during reinitialization. 325 pending_reset_ = true; 326 video_frame_stream_->Reset( 327 base::Bind(&VideoFrameStreamTest::OnReset, base::Unretained(this))); 328 SatisfyPendingCallback(DECODER_REINIT); 329 Read(); 330} 331 332TEST_P(VideoFrameStreamTest, Reset_AfterReinitialization) { 333 Initialize(); 334 EnterPendingState(DECODER_REINIT); 335 SatisfyPendingCallback(DECODER_REINIT); 336 Reset(); 337 Read(); 338} 339 340TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_Normal) { 341 Initialize(); 342 EnterPendingState(DEMUXER_READ_NORMAL); 343 EnterPendingState(DECODER_RESET); 344 SatisfyPendingCallback(DEMUXER_READ_NORMAL); 345 SatisfyPendingCallback(DECODER_RESET); 346 Read(); 347} 348 349TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_ConfigChange) { 350 Initialize(); 351 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 352 EnterPendingState(DECODER_RESET); 353 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 354 SatisfyPendingCallback(DECODER_RESET); 355 Read(); 356} 357 358TEST_P(VideoFrameStreamTest, Reset_DuringNormalDecoderRead) { 359 Initialize(); 360 EnterPendingState(DECODER_READ); 361 EnterPendingState(DECODER_RESET); 362 SatisfyPendingCallback(DECODER_READ); 363 SatisfyPendingCallback(DECODER_RESET); 364 Read(); 365} 366 367TEST_P(VideoFrameStreamTest, Reset_AfterNormalRead) { 368 Initialize(); 369 Read(); 370 Reset(); 371 Read(); 372} 373 374TEST_P(VideoFrameStreamTest, Reset_AfterDemuxerRead_ConfigChange) { 375 Initialize(); 376 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 377 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 378 Reset(); 379 Read(); 380} 381 382TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) { 383 pending_stop_ = true; 384 video_frame_stream_->Stop( 385 base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this))); 386 message_loop_.RunUntilIdle(); 387} 388 389TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) { 390 EnterPendingState(DECODER_INIT); 391 EnterPendingState(DECODER_STOP); 392 SatisfyPendingCallback(DECODER_INIT); 393 SatisfyPendingCallback(DECODER_STOP); 394} 395 396TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) { 397 Initialize(); 398 Stop(); 399} 400 401TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) { 402 Initialize(); 403 EnterPendingState(DECODER_REINIT); 404 EnterPendingState(DECODER_STOP); 405 SatisfyPendingCallback(DECODER_REINIT); 406 SatisfyPendingCallback(DECODER_STOP); 407} 408 409TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) { 410 Initialize(); 411 EnterPendingState(DECODER_REINIT); 412 SatisfyPendingCallback(DECODER_REINIT); 413 Stop(); 414} 415 416TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) { 417 Initialize(); 418 EnterPendingState(DEMUXER_READ_NORMAL); 419 EnterPendingState(DECODER_STOP); 420 SatisfyPendingCallback(DEMUXER_READ_NORMAL); 421 SatisfyPendingCallback(DECODER_STOP); 422} 423 424TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) { 425 Initialize(); 426 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 427 EnterPendingState(DECODER_STOP); 428 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 429 SatisfyPendingCallback(DECODER_STOP); 430} 431 432TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderRead) { 433 Initialize(); 434 EnterPendingState(DECODER_READ); 435 EnterPendingState(DECODER_STOP); 436 SatisfyPendingCallback(DECODER_READ); 437 SatisfyPendingCallback(DECODER_STOP); 438} 439 440TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) { 441 Initialize(); 442 Read(); 443 Stop(); 444} 445 446TEST_P(VideoFrameStreamTest, Stop_AfterConfigChangeRead) { 447 Initialize(); 448 EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); 449 SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); 450 Stop(); 451} 452 453TEST_P(VideoFrameStreamTest, Stop_DuringReset) { 454 Initialize(); 455 EnterPendingState(DECODER_RESET); 456 EnterPendingState(DECODER_STOP); 457 SatisfyPendingCallback(DECODER_RESET); 458 SatisfyPendingCallback(DECODER_STOP); 459} 460 461TEST_P(VideoFrameStreamTest, Stop_AfterReset) { 462 Initialize(); 463 Reset(); 464 Stop(); 465} 466 467TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) { 468 Initialize(); 469 EnterPendingState(DECODER_READ); 470 EnterPendingState(DECODER_RESET); 471 EnterPendingState(DECODER_STOP); 472 SatisfyPendingCallback(DECODER_READ); 473 SatisfyPendingCallback(DECODER_RESET); 474 SatisfyPendingCallback(DECODER_STOP); 475} 476 477TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) { 478 Initialize(); 479 EnterPendingState(DECODER_READ); 480 EnterPendingState(DECODER_RESET); 481 SatisfyPendingCallback(DECODER_READ); 482 EnterPendingState(DECODER_STOP); 483 SatisfyPendingCallback(DECODER_RESET); 484 SatisfyPendingCallback(DECODER_STOP); 485} 486 487TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) { 488 Initialize(); 489 Read(); 490 Reset(); 491 Stop(); 492} 493 494} // namespace media 495