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