1 // Copyright 2013 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/basictypes.h" 6 #include "base/bind.h" 7 #include "base/message_loop/message_loop.h" 8 #include "media/base/decoder_buffer.h" 9 #include "media/base/mock_filters.h" 10 #include "media/base/test_helpers.h" 11 #include "media/base/video_frame.h" 12 #include "media/filters/fake_video_decoder.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace media { 16 17 static const int kDecodingDelay = 9; 18 static const int kTotalBuffers = 12; 19 static const int kDurationMs = 30; 20 21 class FakeVideoDecoderTest : public testing::Test { 22 public: 23 FakeVideoDecoderTest() 24 : decoder_(new FakeVideoDecoder(kDecodingDelay)), 25 num_input_buffers_(0), 26 num_decoded_frames_(0), 27 decode_status_(VideoDecoder::kNotEnoughData), 28 is_decode_pending_(false), 29 is_reset_pending_(false), 30 is_stop_pending_(false) {} 31 32 virtual ~FakeVideoDecoderTest() { 33 StopAndExpect(OK); 34 } 35 36 void InitializeWithConfig(const VideoDecoderConfig& config) { 37 decoder_->Initialize(config, NewExpectedStatusCB(PIPELINE_OK)); 38 message_loop_.RunUntilIdle(); 39 current_config_ = config; 40 } 41 42 void Initialize() { 43 InitializeWithConfig(TestVideoConfig::Normal()); 44 } 45 46 void EnterPendingInitState() { 47 decoder_->HoldNextInit(); 48 Initialize(); 49 } 50 51 void SatisfyInit() { 52 decoder_->SatisfyInit(); 53 message_loop_.RunUntilIdle(); 54 } 55 56 // Callback for VideoDecoder::Read(). 57 void FrameReady(VideoDecoder::Status status, 58 const scoped_refptr<VideoFrame>& frame) { 59 DCHECK(is_decode_pending_); 60 ASSERT_TRUE(status == VideoDecoder::kOk || 61 status == VideoDecoder::kNotEnoughData); 62 is_decode_pending_ = false; 63 decode_status_ = status; 64 frame_decoded_ = frame; 65 66 if (frame && !frame->IsEndOfStream()) 67 num_decoded_frames_++; 68 } 69 70 enum CallbackResult { 71 PENDING, 72 OK, 73 NOT_ENOUGH_DATA, 74 ABROTED, 75 EOS 76 }; 77 78 void ExpectReadResult(CallbackResult result) { 79 switch (result) { 80 case PENDING: 81 EXPECT_TRUE(is_decode_pending_); 82 ASSERT_FALSE(frame_decoded_); 83 break; 84 case OK: 85 EXPECT_FALSE(is_decode_pending_); 86 ASSERT_EQ(VideoDecoder::kOk, decode_status_); 87 ASSERT_TRUE(frame_decoded_); 88 EXPECT_FALSE(frame_decoded_->IsEndOfStream()); 89 break; 90 case NOT_ENOUGH_DATA: 91 EXPECT_FALSE(is_decode_pending_); 92 ASSERT_EQ(VideoDecoder::kNotEnoughData, decode_status_); 93 ASSERT_FALSE(frame_decoded_); 94 break; 95 case ABROTED: 96 EXPECT_FALSE(is_decode_pending_); 97 ASSERT_EQ(VideoDecoder::kOk, decode_status_); 98 EXPECT_FALSE(frame_decoded_); 99 break; 100 case EOS: 101 EXPECT_FALSE(is_decode_pending_); 102 ASSERT_EQ(VideoDecoder::kOk, decode_status_); 103 ASSERT_TRUE(frame_decoded_); 104 EXPECT_TRUE(frame_decoded_->IsEndOfStream()); 105 break; 106 } 107 } 108 109 void Decode() { 110 scoped_refptr<DecoderBuffer> buffer; 111 112 if (num_input_buffers_ < kTotalBuffers) { 113 buffer = CreateFakeVideoBufferForTest( 114 current_config_, 115 base::TimeDelta::FromMilliseconds(kDurationMs * num_input_buffers_), 116 base::TimeDelta::FromMilliseconds(kDurationMs)); 117 num_input_buffers_++; 118 } else { 119 buffer = DecoderBuffer::CreateEOSBuffer(); 120 } 121 122 decode_status_ = VideoDecoder::kDecodeError; 123 frame_decoded_ = NULL; 124 is_decode_pending_ = true; 125 126 decoder_->Decode( 127 buffer, 128 base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this))); 129 message_loop_.RunUntilIdle(); 130 } 131 132 void ReadOneFrame() { 133 do { 134 Decode(); 135 } while (decode_status_ == VideoDecoder::kNotEnoughData && 136 !is_decode_pending_); 137 } 138 139 void ReadUntilEOS() { 140 do { 141 ReadOneFrame(); 142 } while (frame_decoded_ && !frame_decoded_->IsEndOfStream()); 143 } 144 145 void EnterPendingReadState() { 146 // Pass the initial NOT_ENOUGH_DATA stage. 147 ReadOneFrame(); 148 decoder_->HoldNextRead(); 149 ReadOneFrame(); 150 ExpectReadResult(PENDING); 151 } 152 153 void SatisfyReadAndExpect(CallbackResult result) { 154 decoder_->SatisfyRead(); 155 message_loop_.RunUntilIdle(); 156 ExpectReadResult(result); 157 } 158 159 void SatisfyRead() { 160 SatisfyReadAndExpect(OK); 161 } 162 163 // Callback for VideoDecoder::Reset(). 164 void OnDecoderReset() { 165 DCHECK(is_reset_pending_); 166 is_reset_pending_ = false; 167 } 168 169 void ExpectResetResult(CallbackResult result) { 170 switch (result) { 171 case PENDING: 172 EXPECT_TRUE(is_reset_pending_); 173 break; 174 case OK: 175 EXPECT_FALSE(is_reset_pending_); 176 break; 177 default: 178 NOTREACHED(); 179 } 180 } 181 182 void ResetAndExpect(CallbackResult result) { 183 is_reset_pending_ = true; 184 decoder_->Reset(base::Bind(&FakeVideoDecoderTest::OnDecoderReset, 185 base::Unretained(this))); 186 message_loop_.RunUntilIdle(); 187 ExpectResetResult(result); 188 } 189 190 void EnterPendingResetState() { 191 decoder_->HoldNextReset(); 192 ResetAndExpect(PENDING); 193 } 194 195 void SatisfyReset() { 196 decoder_->SatisfyReset(); 197 message_loop_.RunUntilIdle(); 198 ExpectResetResult(OK); 199 } 200 201 // Callback for VideoDecoder::Stop(). 202 void OnDecoderStopped() { 203 DCHECK(is_stop_pending_); 204 is_stop_pending_ = false; 205 } 206 207 void ExpectStopResult(CallbackResult result) { 208 switch (result) { 209 case PENDING: 210 EXPECT_TRUE(is_stop_pending_); 211 break; 212 case OK: 213 EXPECT_FALSE(is_stop_pending_); 214 break; 215 default: 216 NOTREACHED(); 217 } 218 } 219 220 void StopAndExpect(CallbackResult result) { 221 is_stop_pending_ = true; 222 decoder_->Stop(base::Bind(&FakeVideoDecoderTest::OnDecoderStopped, 223 base::Unretained(this))); 224 message_loop_.RunUntilIdle(); 225 ExpectStopResult(result); 226 } 227 228 void EnterPendingStopState() { 229 decoder_->HoldNextStop(); 230 StopAndExpect(PENDING); 231 } 232 233 void SatisfyStop() { 234 decoder_->SatisfyStop(); 235 message_loop_.RunUntilIdle(); 236 ExpectStopResult(OK); 237 } 238 239 base::MessageLoop message_loop_; 240 VideoDecoderConfig current_config_; 241 242 scoped_ptr<FakeVideoDecoder> decoder_; 243 244 int num_input_buffers_; 245 int num_decoded_frames_; 246 247 // Callback result/status. 248 VideoDecoder::Status decode_status_; 249 scoped_refptr<VideoFrame> frame_decoded_; 250 bool is_decode_pending_; 251 bool is_reset_pending_; 252 bool is_stop_pending_; 253 254 private: 255 DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest); 256 }; 257 258 TEST_F(FakeVideoDecoderTest, Initialize) { 259 Initialize(); 260 } 261 262 TEST_F(FakeVideoDecoderTest, Read_AllFrames) { 263 Initialize(); 264 ReadUntilEOS(); 265 EXPECT_EQ(kTotalBuffers, num_decoded_frames_); 266 } 267 268 TEST_F(FakeVideoDecoderTest, Read_DecodingDelay) { 269 Initialize(); 270 271 while (num_input_buffers_ < kTotalBuffers) { 272 ReadOneFrame(); 273 EXPECT_EQ(num_input_buffers_, num_decoded_frames_ + kDecodingDelay); 274 } 275 } 276 277 TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) { 278 decoder_.reset(new FakeVideoDecoder(0)); 279 Initialize(); 280 281 while (num_input_buffers_ < kTotalBuffers) { 282 ReadOneFrame(); 283 EXPECT_EQ(num_input_buffers_, num_decoded_frames_); 284 } 285 } 286 287 TEST_F(FakeVideoDecoderTest, Read_Pending_NotEnoughData) { 288 Initialize(); 289 decoder_->HoldNextRead(); 290 ReadOneFrame(); 291 ExpectReadResult(PENDING); 292 SatisfyReadAndExpect(NOT_ENOUGH_DATA); 293 } 294 295 TEST_F(FakeVideoDecoderTest, Read_Pending_OK) { 296 Initialize(); 297 ReadOneFrame(); 298 EnterPendingReadState(); 299 SatisfyReadAndExpect(OK); 300 } 301 302 TEST_F(FakeVideoDecoderTest, Reinitialize) { 303 Initialize(); 304 ReadOneFrame(); 305 InitializeWithConfig(TestVideoConfig::Large()); 306 ReadOneFrame(); 307 } 308 309 // Reinitializing the decoder during the middle of the decoding process can 310 // cause dropped frames. 311 TEST_F(FakeVideoDecoderTest, Reinitialize_FrameDropped) { 312 Initialize(); 313 ReadOneFrame(); 314 Initialize(); 315 ReadUntilEOS(); 316 EXPECT_LT(num_decoded_frames_, kTotalBuffers); 317 } 318 319 TEST_F(FakeVideoDecoderTest, Reset) { 320 Initialize(); 321 ReadOneFrame(); 322 ResetAndExpect(OK); 323 } 324 325 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingRead) { 326 Initialize(); 327 EnterPendingReadState(); 328 ResetAndExpect(PENDING); 329 SatisfyRead(); 330 } 331 332 TEST_F(FakeVideoDecoderTest, Reset_Pending) { 333 Initialize(); 334 EnterPendingResetState(); 335 SatisfyReset(); 336 } 337 338 TEST_F(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) { 339 Initialize(); 340 EnterPendingReadState(); 341 EnterPendingResetState(); 342 SatisfyRead(); 343 SatisfyReset(); 344 } 345 346 TEST_F(FakeVideoDecoderTest, Stop) { 347 Initialize(); 348 ReadOneFrame(); 349 ExpectReadResult(OK); 350 StopAndExpect(OK); 351 } 352 353 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingInitialization) { 354 EnterPendingInitState(); 355 EnterPendingStopState(); 356 SatisfyInit(); 357 SatisfyStop(); 358 } 359 360 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) { 361 Initialize(); 362 EnterPendingReadState(); 363 StopAndExpect(PENDING); 364 SatisfyRead(); 365 ExpectStopResult(OK); 366 } 367 368 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) { 369 Initialize(); 370 EnterPendingResetState(); 371 StopAndExpect(PENDING); 372 SatisfyReset(); 373 ExpectStopResult(OK); 374 } 375 376 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) { 377 Initialize(); 378 EnterPendingReadState(); 379 EnterPendingResetState(); 380 StopAndExpect(PENDING); 381 SatisfyRead(); 382 SatisfyReset(); 383 ExpectStopResult(OK); 384 } 385 386 TEST_F(FakeVideoDecoderTest, Stop_Pending) { 387 Initialize(); 388 decoder_->HoldNextStop(); 389 StopAndExpect(PENDING); 390 decoder_->SatisfyStop(); 391 message_loop_.RunUntilIdle(); 392 ExpectStopResult(OK); 393 } 394 395 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingRead) { 396 Initialize(); 397 EnterPendingReadState(); 398 EnterPendingStopState(); 399 SatisfyRead(); 400 SatisfyStop(); 401 } 402 403 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReset) { 404 Initialize(); 405 EnterPendingResetState(); 406 EnterPendingStopState(); 407 SatisfyReset(); 408 SatisfyStop(); 409 } 410 411 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReadAndPendingReset) { 412 Initialize(); 413 EnterPendingReadState(); 414 EnterPendingResetState(); 415 EnterPendingStopState(); 416 SatisfyRead(); 417 SatisfyReset(); 418 SatisfyStop(); 419 } 420 421 } // namespace media 422