OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 <memory> | |
6 #include <utility> | |
7 | |
8 #include "base/bind.h" | |
9 #include "base/logging.h" | |
10 #include "base/macros.h" | |
11 #include "base/memory/ptr_util.h" | |
12 #include "base/threading/thread_task_runner_handle.h" | |
13 #include "base/timer/timer.h" | |
14 #include "media/base/android/audio_media_codec_decoder.h" | |
15 #include "media/base/android/media_codec_util.h" | |
16 #include "media/base/android/media_statistics.h" | |
17 #include "media/base/android/sdk_media_codec_bridge.h" | |
18 #include "media/base/android/test_data_factory.h" | |
19 #include "media/base/android/test_statistics.h" | |
20 #include "media/base/android/video_media_codec_decoder.h" | |
21 #include "media/base/timestamp_constants.h" | |
22 #include "testing/gtest/include/gtest/gtest.h" | |
23 #include "ui/gl/android/surface_texture.h" | |
24 | |
25 namespace media { | |
26 | |
27 namespace { | |
28 | |
29 const base::TimeDelta kDefaultTimeout = base::TimeDelta::FromMilliseconds(200); | |
30 const base::TimeDelta kAudioFramePeriod = | |
31 base::TimeDelta::FromSecondsD(1024.0 / 44100); // 1024 samples @ 44100 Hz | |
32 const base::TimeDelta kVideoFramePeriod = base::TimeDelta::FromMilliseconds(20); | |
33 | |
34 // A helper function to calculate the expected number of frames. | |
35 int GetFrameCount(base::TimeDelta duration, base::TimeDelta frame_period) { | |
36 // A chunk has 4 access units. The last unit timestamp must exceed the | |
37 // duration. Last chunk has 3 regular access units and one stand-alone EOS | |
38 // unit that we do not count. | |
39 | |
40 // Number of time intervals to exceed duration. | |
41 int num_intervals = duration / frame_period + 1.0; | |
42 | |
43 // To cover these intervals we need one extra unit at the beginning. | |
44 int num_units = num_intervals + 1; | |
45 | |
46 // Number of 4-unit chunks that hold these units: | |
47 int num_chunks = (num_units + 3) / 4; | |
48 | |
49 // Altogether these chunks hold 4*num_chunks units, but we do not count | |
50 // the last EOS as a frame. | |
51 return 4 * num_chunks - 1; | |
52 } | |
53 | |
54 class AudioFactory : public TestDataFactory { | |
55 public: | |
56 AudioFactory(base::TimeDelta duration); | |
57 DemuxerConfigs GetConfigs() const override; | |
58 | |
59 protected: | |
60 void ModifyChunk(DemuxerData* chunk) override; | |
61 }; | |
62 | |
63 class VideoFactory : public TestDataFactory { | |
64 public: | |
65 VideoFactory(base::TimeDelta duration); | |
66 DemuxerConfigs GetConfigs() const override; | |
67 | |
68 protected: | |
69 void ModifyChunk(DemuxerData* chunk) override; | |
70 }; | |
71 | |
72 AudioFactory::AudioFactory(base::TimeDelta duration) | |
73 : TestDataFactory("aac-44100-packet-%d", duration, kAudioFramePeriod) { | |
74 } | |
75 | |
76 DemuxerConfigs AudioFactory::GetConfigs() const { | |
77 return TestDataFactory::CreateAudioConfigs(kCodecAAC, duration_); | |
78 } | |
79 | |
80 void AudioFactory::ModifyChunk(DemuxerData* chunk) { | |
81 DCHECK(chunk); | |
82 for (AccessUnit& unit : chunk->access_units) { | |
83 if (!unit.data.empty()) | |
84 unit.is_key_frame = true; | |
85 } | |
86 } | |
87 | |
88 VideoFactory::VideoFactory(base::TimeDelta duration) | |
89 : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod) { | |
90 } | |
91 | |
92 DemuxerConfigs VideoFactory::GetConfigs() const { | |
93 return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_, | |
94 gfx::Size(320, 180)); | |
95 } | |
96 | |
97 void VideoFactory::ModifyChunk(DemuxerData* chunk) { | |
98 // The frames are taken from High profile and some are B-frames. | |
99 // The first 4 frames appear in the file in the following order: | |
100 // | |
101 // Frames: I P B P | |
102 // Decoding order: 0 1 2 3 | |
103 // Presentation order: 0 2 1 4(3) | |
104 // | |
105 // I keep the last PTS to be 3 for simplicity. | |
106 | |
107 // If the chunk contains EOS, it should not break the presentation order. | |
108 // For instance, the following chunk is ok: | |
109 // | |
110 // Frames: I P B EOS | |
111 // Decoding order: 0 1 2 - | |
112 // Presentation order: 0 2 1 - | |
113 // | |
114 // while this one might cause decoder to block: | |
115 // | |
116 // Frames: I P EOS | |
117 // Decoding order: 0 1 - | |
118 // Presentation order: 0 2 - <------- might wait for the B frame forever | |
119 // | |
120 // With current base class implementation that always has EOS at the 4th | |
121 // place we are covered (http://crbug.com/526755) | |
122 | |
123 DCHECK(chunk); | |
124 DCHECK(chunk->access_units.size() == 4); | |
125 | |
126 // Swap pts for second and third frames. Make first frame a key frame. | |
127 base::TimeDelta tmp = chunk->access_units[1].timestamp; | |
128 chunk->access_units[1].timestamp = chunk->access_units[2].timestamp; | |
129 chunk->access_units[2].timestamp = tmp; | |
130 | |
131 chunk->access_units[0].is_key_frame = true; | |
132 } | |
133 | |
134 } // namespace (anonymous) | |
135 | |
136 // The test fixture for MediaCodecDecoder | |
137 | |
138 class MediaCodecDecoderTest : public testing::Test { | |
139 public: | |
140 MediaCodecDecoderTest(); | |
141 ~MediaCodecDecoderTest() override; | |
142 | |
143 // Conditions we wait for. | |
144 bool is_prefetched() const { return is_prefetched_; } | |
145 bool is_stopped() const { return is_stopped_; } | |
146 bool is_starved() const { return is_starved_; } | |
147 | |
148 void SetPrefetched(bool value) { is_prefetched_ = value; } | |
149 void SetStopped(bool value) { is_stopped_ = value; } | |
150 void SetStarved(bool value) { is_starved_ = value; } | |
151 | |
152 protected: | |
153 typedef base::Callback<bool()> Predicate; | |
154 | |
155 typedef base::Callback<void(const DemuxerData&)> DataAvailableCallback; | |
156 | |
157 // Waits for condition to become true or for timeout to expire. | |
158 // Returns true if the condition becomes true. | |
159 bool WaitForCondition(const Predicate& condition, | |
160 const base::TimeDelta& timeout = kDefaultTimeout); | |
161 | |
162 void SetDataFactory(std::unique_ptr<TestDataFactory> factory) { | |
163 data_factory_ = std::move(factory); | |
164 } | |
165 | |
166 DemuxerConfigs GetConfigs() const { | |
167 // ASSERT_NE does not compile here because it expects void return value. | |
168 EXPECT_NE(nullptr, data_factory_.get()); | |
169 return data_factory_->GetConfigs(); | |
170 } | |
171 | |
172 void CreateAudioDecoder(); | |
173 void CreateVideoDecoder(); | |
174 void SetVideoSurface(); | |
175 void SetStopRequestAtTime(const base::TimeDelta& time) { | |
176 stop_request_time_ = time; | |
177 } | |
178 | |
179 // Decoder callbacks. | |
180 void OnDataRequested(); | |
181 void OnStarvation() { is_starved_ = true; } | |
182 void OnDecoderDrained() {} | |
183 void OnStopDone() { is_stopped_ = true; } | |
184 void OnKeyRequired() {} | |
185 void OnError() { DVLOG(0) << "MediaCodecDecoderTest::" << __FUNCTION__; } | |
186 void OnUpdateCurrentTime(base::TimeDelta now_playing, | |
187 base::TimeDelta last_buffered, | |
188 bool postpone) { | |
189 // Add the |last_buffered| value for PTS. For video it is the same as | |
190 // |now_playing| and is equal to PTS, for audio |last_buffered| should | |
191 // exceed PTS. | |
192 if (postpone) | |
193 return; | |
194 | |
195 pts_stat_.AddValue(last_buffered); | |
196 | |
197 if (stop_request_time_ != kNoTimestamp && | |
198 now_playing >= stop_request_time_) { | |
199 stop_request_time_ = kNoTimestamp; | |
200 decoder_->RequestToStop(); | |
201 } | |
202 } | |
203 | |
204 void OnVideoSizeChanged(const gfx::Size& video_size) { | |
205 video_size_ = video_size; | |
206 } | |
207 | |
208 void OnVideoCodecCreated() {} | |
209 | |
210 std::unique_ptr<MediaCodecDecoder> decoder_; | |
211 std::unique_ptr<TestDataFactory> data_factory_; | |
212 Minimax<base::TimeDelta> pts_stat_; | |
213 gfx::Size video_size_; | |
214 | |
215 private: | |
216 bool is_timeout_expired() const { return is_timeout_expired_; } | |
217 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; } | |
218 | |
219 base::MessageLoop message_loop_; | |
220 bool is_timeout_expired_; | |
221 | |
222 bool is_prefetched_; | |
223 bool is_stopped_; | |
224 bool is_starved_; | |
225 base::TimeDelta stop_request_time_; | |
226 | |
227 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
228 FrameStatistics frame_statistics_; | |
229 DataAvailableCallback data_available_cb_; | |
230 scoped_refptr<gl::SurfaceTexture> surface_texture_; | |
231 | |
232 DISALLOW_COPY_AND_ASSIGN(MediaCodecDecoderTest); | |
233 }; | |
234 | |
235 MediaCodecDecoderTest::MediaCodecDecoderTest() | |
236 : is_timeout_expired_(false), | |
237 is_prefetched_(false), | |
238 is_stopped_(false), | |
239 is_starved_(false), | |
240 stop_request_time_(kNoTimestamp), | |
241 task_runner_(base::ThreadTaskRunnerHandle::Get()) {} | |
242 | |
243 MediaCodecDecoderTest::~MediaCodecDecoderTest() {} | |
244 | |
245 bool MediaCodecDecoderTest::WaitForCondition(const Predicate& condition, | |
246 const base::TimeDelta& timeout) { | |
247 // Let the message_loop_ process events. | |
248 // We start the timer and RunUntilIdle() until it signals. | |
249 | |
250 SetTimeoutExpired(false); | |
251 | |
252 base::Timer timer(false, false); | |
253 timer.Start(FROM_HERE, timeout, | |
254 base::Bind(&MediaCodecDecoderTest::SetTimeoutExpired, | |
255 base::Unretained(this), true)); | |
256 | |
257 do { | |
258 if (condition.Run()) { | |
259 timer.Stop(); | |
260 return true; | |
261 } | |
262 message_loop_.RunUntilIdle(); | |
263 } while (!is_timeout_expired()); | |
264 | |
265 DCHECK(!timer.IsRunning()); | |
266 return false; | |
267 } | |
268 | |
269 void MediaCodecDecoderTest::CreateAudioDecoder() { | |
270 decoder_ = base::MakeUnique<AudioMediaCodecDecoder>( | |
271 task_runner_, &frame_statistics_, | |
272 base::Bind(&MediaCodecDecoderTest::OnDataRequested, | |
273 base::Unretained(this)), | |
274 base::Bind(&MediaCodecDecoderTest::OnStarvation, base::Unretained(this)), | |
275 base::Bind(&MediaCodecDecoderTest::OnDecoderDrained, | |
276 base::Unretained(this)), | |
277 base::Bind(&MediaCodecDecoderTest::OnStopDone, base::Unretained(this)), | |
278 base::Bind(&MediaCodecDecoderTest::OnKeyRequired, base::Unretained(this)), | |
279 base::Bind(&MediaCodecDecoderTest::OnError, base::Unretained(this)), | |
280 base::Bind(&MediaCodecDecoderTest::OnUpdateCurrentTime, | |
281 base::Unretained(this))); | |
282 | |
283 data_available_cb_ = base::Bind(&MediaCodecDecoder::OnDemuxerDataAvailable, | |
284 base::Unretained(decoder_.get())); | |
285 } | |
286 | |
287 void MediaCodecDecoderTest::CreateVideoDecoder() { | |
288 decoder_ = base::MakeUnique<VideoMediaCodecDecoder>( | |
289 task_runner_, &frame_statistics_, | |
290 base::Bind(&MediaCodecDecoderTest::OnDataRequested, | |
291 base::Unretained(this)), | |
292 base::Bind(&MediaCodecDecoderTest::OnStarvation, base::Unretained(this)), | |
293 base::Bind(&MediaCodecDecoderTest::OnDecoderDrained, | |
294 base::Unretained(this)), | |
295 base::Bind(&MediaCodecDecoderTest::OnStopDone, base::Unretained(this)), | |
296 base::Bind(&MediaCodecDecoderTest::OnKeyRequired, base::Unretained(this)), | |
297 base::Bind(&MediaCodecDecoderTest::OnError, base::Unretained(this)), | |
298 base::Bind(&MediaCodecDecoderTest::OnUpdateCurrentTime, | |
299 base::Unretained(this)), | |
300 base::Bind(&MediaCodecDecoderTest::OnVideoSizeChanged, | |
301 base::Unretained(this))); | |
302 | |
303 data_available_cb_ = base::Bind(&MediaCodecDecoder::OnDemuxerDataAvailable, | |
304 base::Unretained(decoder_.get())); | |
305 } | |
306 | |
307 void MediaCodecDecoderTest::OnDataRequested() { | |
308 if (!data_factory_) | |
309 return; | |
310 | |
311 DemuxerData data; | |
312 base::TimeDelta delay; | |
313 if (!data_factory_->CreateChunk(&data, &delay)) | |
314 return; | |
315 | |
316 task_runner_->PostDelayedTask(FROM_HERE, base::Bind(data_available_cb_, data), | |
317 delay); | |
318 } | |
319 | |
320 void MediaCodecDecoderTest::SetVideoSurface() { | |
321 surface_texture_ = gl::SurfaceTexture::Create(0); | |
322 gl::ScopedJavaSurface surface(surface_texture_.get()); | |
323 ASSERT_NE(nullptr, decoder_.get()); | |
324 VideoMediaCodecDecoder* video_decoder = | |
325 static_cast<VideoMediaCodecDecoder*>(decoder_.get()); | |
326 video_decoder->SetVideoSurface(std::move(surface)); | |
327 } | |
328 | |
329 TEST_F(MediaCodecDecoderTest, AudioPrefetch) { | |
330 CreateAudioDecoder(); | |
331 | |
332 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
333 SetDataFactory(base::MakeUnique<AudioFactory>(duration)); | |
334 | |
335 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
336 base::Unretained(this), true)); | |
337 | |
338 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
339 base::Unretained(this)))); | |
340 } | |
341 | |
342 TEST_F(MediaCodecDecoderTest, VideoPrefetch) { | |
343 CreateVideoDecoder(); | |
344 | |
345 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
346 SetDataFactory(base::MakeUnique<VideoFactory>(duration)); | |
347 | |
348 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
349 base::Unretained(this), true)); | |
350 | |
351 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
352 base::Unretained(this)))); | |
353 } | |
354 | |
355 TEST_F(MediaCodecDecoderTest, AudioConfigureNoParams) { | |
356 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
357 | |
358 CreateAudioDecoder(); | |
359 | |
360 // Cannot configure without config parameters. | |
361 EXPECT_EQ(MediaCodecDecoder::kConfigFailure, decoder_->Configure(nullptr)); | |
362 } | |
363 | |
364 TEST_F(MediaCodecDecoderTest, AudioConfigureValidParams) { | |
365 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
366 | |
367 CreateAudioDecoder(); | |
368 | |
369 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
370 std::unique_ptr<AudioFactory> factory(new AudioFactory(duration)); | |
371 decoder_->SetDemuxerConfigs(factory->GetConfigs()); | |
372 | |
373 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure(nullptr)); | |
374 } | |
375 | |
376 TEST_F(MediaCodecDecoderTest, VideoConfigureNoParams) { | |
377 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
378 | |
379 CreateVideoDecoder(); | |
380 | |
381 // decoder_->Configure() searches back for the key frame. | |
382 // We have to prefetch decoder. | |
383 | |
384 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
385 SetDataFactory(base::MakeUnique<VideoFactory>(duration)); | |
386 | |
387 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
388 base::Unretained(this), true)); | |
389 | |
390 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
391 base::Unretained(this)))); | |
392 | |
393 SetVideoSurface(); | |
394 | |
395 // Cannot configure without config parameters. | |
396 EXPECT_EQ(MediaCodecDecoder::kConfigFailure, decoder_->Configure(nullptr)); | |
397 } | |
398 | |
399 TEST_F(MediaCodecDecoderTest, VideoConfigureNoSurface) { | |
400 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
401 | |
402 CreateVideoDecoder(); | |
403 | |
404 // decoder_->Configure() searches back for the key frame. | |
405 // We have to prefetch decoder. | |
406 | |
407 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
408 SetDataFactory(base::MakeUnique<VideoFactory>(duration)); | |
409 | |
410 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
411 base::Unretained(this), true)); | |
412 | |
413 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
414 base::Unretained(this)))); | |
415 | |
416 decoder_->SetDemuxerConfigs(GetConfigs()); | |
417 | |
418 // Surface is not set, Configure() should fail. | |
419 | |
420 EXPECT_EQ(MediaCodecDecoder::kConfigFailure, decoder_->Configure(nullptr)); | |
421 } | |
422 | |
423 TEST_F(MediaCodecDecoderTest, VideoConfigureInvalidSurface) { | |
424 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
425 | |
426 CreateVideoDecoder(); | |
427 | |
428 // decoder_->Configure() searches back for the key frame. | |
429 // We have to prefetch decoder. | |
430 | |
431 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
432 SetDataFactory(base::MakeUnique<VideoFactory>(duration)); | |
433 | |
434 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
435 base::Unretained(this), true)); | |
436 | |
437 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
438 base::Unretained(this)))); | |
439 | |
440 decoder_->SetDemuxerConfigs(GetConfigs()); | |
441 | |
442 // Prepare the surface. | |
443 scoped_refptr<gl::SurfaceTexture> surface_texture( | |
444 gl::SurfaceTexture::Create(0)); | |
445 gl::ScopedJavaSurface surface(surface_texture.get()); | |
446 | |
447 // Release the surface texture. | |
448 surface_texture = NULL; | |
449 | |
450 VideoMediaCodecDecoder* video_decoder = | |
451 static_cast<VideoMediaCodecDecoder*>(decoder_.get()); | |
452 video_decoder->SetVideoSurface(std::move(surface)); | |
453 | |
454 EXPECT_EQ(MediaCodecDecoder::kConfigFailure, decoder_->Configure(nullptr)); | |
455 } | |
456 | |
457 TEST_F(MediaCodecDecoderTest, VideoConfigureValidParams) { | |
458 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
459 | |
460 CreateVideoDecoder(); | |
461 | |
462 // decoder_->Configure() searches back for the key frame. | |
463 // We have to prefetch decoder. | |
464 | |
465 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
466 SetDataFactory(base::MakeUnique<VideoFactory>(duration)); | |
467 | |
468 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
469 base::Unretained(this), true)); | |
470 | |
471 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
472 base::Unretained(this)))); | |
473 | |
474 decoder_->SetDemuxerConfigs(GetConfigs()); | |
475 | |
476 SetVideoSurface(); | |
477 | |
478 // Now we can expect Configure() to succeed. | |
479 | |
480 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure(nullptr)); | |
481 } | |
482 | |
483 TEST_F(MediaCodecDecoderTest, AudioStartWithoutConfigure) { | |
484 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
485 | |
486 CreateAudioDecoder(); | |
487 | |
488 // Decoder has to be prefetched and configured before the start. | |
489 | |
490 // Wrong state: not prefetched | |
491 EXPECT_FALSE(decoder_->Start(base::TimeDelta::FromMilliseconds(0))); | |
492 | |
493 // Do the prefetch. | |
494 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
495 SetDataFactory(base::MakeUnique<AudioFactory>(duration)); | |
496 | |
497 // Prefetch to avoid starvation at the beginning of playback. | |
498 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
499 base::Unretained(this), true)); | |
500 | |
501 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
502 base::Unretained(this)))); | |
503 | |
504 // Still, decoder is not configured. | |
505 EXPECT_FALSE(decoder_->Start(base::TimeDelta::FromMilliseconds(0))); | |
506 } | |
507 | |
508 // http://crbug.com/518900 | |
509 TEST_F(MediaCodecDecoderTest, DISABLED_AudioPlayTillCompletion) { | |
510 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
511 | |
512 DVLOG(0) << "AudioPlayTillCompletion started"; | |
513 | |
514 CreateAudioDecoder(); | |
515 | |
516 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
517 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500); | |
518 | |
519 SetDataFactory(base::WrapUnique(new AudioFactory(duration))); | |
520 | |
521 // Prefetch to avoid starvation at the beginning of playback. | |
522 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
523 base::Unretained(this), true)); | |
524 | |
525 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
526 base::Unretained(this)))); | |
527 | |
528 decoder_->SetDemuxerConfigs(GetConfigs()); | |
529 | |
530 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure(nullptr)); | |
531 | |
532 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0))); | |
533 | |
534 EXPECT_TRUE(WaitForCondition( | |
535 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)), | |
536 timeout)); | |
537 | |
538 EXPECT_TRUE(decoder_->IsStopped()); | |
539 EXPECT_TRUE(decoder_->IsCompleted()); | |
540 | |
541 // Last buffered timestamp should be no less than PTS. | |
542 // The number of hits in pts_stat_ depends on the preroll implementation. | |
543 // We might not report the time for the first buffer after preroll that | |
544 // is written to the audio track. pts_stat_.num_values() is either 21 or 22. | |
545 EXPECT_LE(21, pts_stat_.num_values()); | |
546 EXPECT_LE(data_factory_->last_pts(), pts_stat_.max()); | |
547 | |
548 DVLOG(0) << "AudioPlayTillCompletion stopping"; | |
549 } | |
550 | |
551 // crbug.com/618274 | |
552 #if defined(OS_ANDROID) | |
553 #define MAYBE_VideoPlayTillCompletion DISABLED_VideoPlayTillCompletion | |
554 #else | |
555 #define MAYBE_VideoPlayTillCompletion VideoPlayTillCompletion | |
556 #endif | |
557 TEST_F(MediaCodecDecoderTest, MAYBE_VideoPlayTillCompletion) { | |
558 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
559 | |
560 CreateVideoDecoder(); | |
561 | |
562 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
563 // The first output frame might come out with significant delay. Apparently | |
564 // the codec does initial configuration at this time. We increase the timeout | |
565 // to leave a room of 1 second for this initial configuration. | |
566 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500); | |
567 SetDataFactory(base::MakeUnique<VideoFactory>(duration)); | |
568 | |
569 // Prefetch | |
570 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
571 base::Unretained(this), true)); | |
572 | |
573 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
574 base::Unretained(this)))); | |
575 | |
576 decoder_->SetDemuxerConfigs(GetConfigs()); | |
577 | |
578 SetVideoSurface(); | |
579 | |
580 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure(nullptr)); | |
581 | |
582 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0))); | |
583 | |
584 EXPECT_TRUE(WaitForCondition( | |
585 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)), | |
586 timeout)); | |
587 | |
588 EXPECT_TRUE(decoder_->IsStopped()); | |
589 EXPECT_TRUE(decoder_->IsCompleted()); | |
590 | |
591 int expected_video_frames = GetFrameCount(duration, kVideoFramePeriod); | |
592 EXPECT_EQ(expected_video_frames, pts_stat_.num_values()); | |
593 EXPECT_EQ(data_factory_->last_pts(), pts_stat_.max()); | |
594 } | |
595 | |
596 // Disabled per http://crbug.com/611489. | |
597 TEST_F(MediaCodecDecoderTest, DISABLED_VideoStopAndResume) { | |
598 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
599 | |
600 CreateVideoDecoder(); | |
601 | |
602 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500); | |
603 base::TimeDelta stop_request_time = base::TimeDelta::FromMilliseconds(200); | |
604 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1000); | |
605 | |
606 SetDataFactory(base::WrapUnique(new VideoFactory(duration))); | |
607 | |
608 // Prefetch | |
609 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
610 base::Unretained(this), true)); | |
611 | |
612 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
613 base::Unretained(this)))); | |
614 | |
615 decoder_->SetDemuxerConfigs(GetConfigs()); | |
616 | |
617 SetVideoSurface(); | |
618 | |
619 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure(nullptr)); | |
620 | |
621 SetStopRequestAtTime(stop_request_time); | |
622 | |
623 // Start from the beginning. | |
624 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0))); | |
625 | |
626 EXPECT_TRUE(WaitForCondition( | |
627 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)), | |
628 timeout)); | |
629 | |
630 EXPECT_TRUE(decoder_->IsStopped()); | |
631 EXPECT_FALSE(decoder_->IsCompleted()); | |
632 | |
633 base::TimeDelta last_pts = pts_stat_.max(); | |
634 | |
635 EXPECT_GE(last_pts, stop_request_time); | |
636 | |
637 // Resume playback from last_pts: | |
638 | |
639 SetPrefetched(false); | |
640 SetStopped(false); | |
641 | |
642 // Prefetch again. | |
643 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
644 base::Unretained(this), true)); | |
645 | |
646 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
647 base::Unretained(this)))); | |
648 | |
649 // Then start. | |
650 EXPECT_TRUE(decoder_->Start(last_pts)); | |
651 | |
652 // Wait till completion. | |
653 EXPECT_TRUE(WaitForCondition( | |
654 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)), | |
655 timeout)); | |
656 | |
657 EXPECT_TRUE(decoder_->IsStopped()); | |
658 EXPECT_TRUE(decoder_->IsCompleted()); | |
659 | |
660 // We should not skip frames in this process. | |
661 int expected_video_frames = GetFrameCount(duration, kVideoFramePeriod); | |
662 EXPECT_EQ(expected_video_frames, pts_stat_.num_values()); | |
663 EXPECT_EQ(data_factory_->last_pts(), pts_stat_.max()); | |
664 } | |
665 | |
666 // http://crbug.com/518900 | |
667 TEST_F(MediaCodecDecoderTest, DISABLED_AudioStarvationAndStop) { | |
668 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
669 | |
670 CreateAudioDecoder(); | |
671 | |
672 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(200); | |
673 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(400); | |
674 | |
675 AudioFactory* factory = new AudioFactory(duration); | |
676 factory->SetStarvationMode(true); | |
677 SetDataFactory(base::WrapUnique(factory)); | |
678 | |
679 // Prefetch. | |
680 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
681 base::Unretained(this), true)); | |
682 | |
683 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
684 base::Unretained(this)))); | |
685 | |
686 // Configure. | |
687 decoder_->SetDemuxerConfigs(GetConfigs()); | |
688 | |
689 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure(nullptr)); | |
690 | |
691 // Start. | |
692 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0))); | |
693 | |
694 // Wait for starvation. | |
695 EXPECT_TRUE(WaitForCondition( | |
696 base::Bind(&MediaCodecDecoderTest::is_starved, base::Unretained(this)), | |
697 timeout)); | |
698 | |
699 EXPECT_FALSE(decoder_->IsStopped()); | |
700 EXPECT_FALSE(decoder_->IsCompleted()); | |
701 | |
702 EXPECT_GT(pts_stat_.num_values(), 0); | |
703 | |
704 // After starvation we should be able to stop decoder. | |
705 decoder_->RequestToStop(); | |
706 | |
707 EXPECT_TRUE(WaitForCondition( | |
708 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)))); | |
709 | |
710 EXPECT_TRUE(decoder_->IsStopped()); | |
711 EXPECT_FALSE(decoder_->IsCompleted()); | |
712 } | |
713 | |
714 // Disabled per http://crbug.com/611489. | |
715 TEST_F(MediaCodecDecoderTest, DISABLED_VideoFirstUnitIsReconfig) { | |
716 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
717 | |
718 // Test that the kConfigChanged unit that comes before the first data unit | |
719 // gets processed, i.e. is not lost. | |
720 | |
721 CreateVideoDecoder(); | |
722 | |
723 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(200); | |
724 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1000); | |
725 SetDataFactory(base::WrapUnique(new VideoFactory(duration))); | |
726 | |
727 // Ask factory to produce initial configuration unit. The configuraton will | |
728 // be factory.GetConfigs(). | |
729 data_factory_->RequestInitialConfigs(); | |
730 | |
731 // Create am alternative configuration (we just alter video size). | |
732 DemuxerConfigs alt_configs = data_factory_->GetConfigs(); | |
733 alt_configs.video_size = gfx::Size(100, 100); | |
734 | |
735 // Pass the alternative configuration to decoder. | |
736 decoder_->SetDemuxerConfigs(alt_configs); | |
737 | |
738 // Prefetch. | |
739 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched, | |
740 base::Unretained(this), true)); | |
741 | |
742 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched, | |
743 base::Unretained(this)))); | |
744 | |
745 // Current implementation reports the new video size after | |
746 // SetDemuxerConfigs(), verify that it is alt size. | |
747 EXPECT_EQ(alt_configs.video_size, video_size_); | |
748 | |
749 SetVideoSurface(); | |
750 | |
751 // Configure. | |
752 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure(nullptr)); | |
753 | |
754 // Start. | |
755 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0))); | |
756 | |
757 // Wait for completion. | |
758 EXPECT_TRUE(WaitForCondition( | |
759 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)), | |
760 timeout)); | |
761 | |
762 EXPECT_TRUE(decoder_->IsStopped()); | |
763 EXPECT_TRUE(decoder_->IsCompleted()); | |
764 EXPECT_EQ(data_factory_->last_pts(), pts_stat_.max()); | |
765 | |
766 // Check that the reported video size is the one from the in-stream configs. | |
767 EXPECT_EQ(data_factory_->GetConfigs().video_size, video_size_); | |
768 } | |
769 | |
770 } // namespace media | |
OLD | NEW |