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.
6 #include "base/logging.h"
7 #include "base/thread_task_runner_handle.h"
8 #include "base/timer/timer.h"
9 #include "media/base/android/media_codec_audio_decoder.h"
10 #include "media/base/android/media_codec_bridge.h"
11 #include "media/base/android/media_codec_video_decoder.h"
12 #include "media/base/android/test_data_factory.h"
13 #include "media/base/android/test_statistics.h"
14 #include "media/base/timestamp_constants.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gl/android/surface_texture.h"
20 // Helper macro to skip the test if MediaCodecBridge isn't available.
21 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
23 if (!MediaCodecBridge::IsAvailable()) { \
24 VLOG(0) << "Could not run test - not supported on device."; \
31 const base::TimeDelta kDefaultTimeout
= base::TimeDelta::FromMilliseconds(200);
32 const base::TimeDelta kAudioFramePeriod
=
33 base::TimeDelta::FromSecondsD(1024.0 / 44100); // 1024 samples @ 44100 Hz
34 const base::TimeDelta kVideoFramePeriod
= base::TimeDelta::FromMilliseconds(20);
36 // A helper function to calculate the expected number of frames.
37 int GetFrameCount(base::TimeDelta duration
, base::TimeDelta frame_period
) {
38 // A chunk has 4 access units. The last unit timestamp must exceed the
39 // duration. Last chunk has 3 regular access units and one stand-alone EOS
40 // unit that we do not count.
42 // Number of time intervals to exceed duration.
43 int num_intervals
= duration
/ frame_period
+ 1.0;
45 // To cover these intervals we need one extra unit at the beginning.
46 int num_units
= num_intervals
+ 1;
48 // Number of 4-unit chunks that hold these units:
49 int num_chunks
= (num_units
+ 3) / 4;
51 // Altogether these chunks hold 4*num_chunks units, but we do not count
52 // the last EOS as a frame.
53 return 4 * num_chunks
- 1;
56 class AudioFactory
: public TestDataFactory
{
58 AudioFactory(base::TimeDelta duration
);
59 DemuxerConfigs
GetConfigs() const override
;
62 void ModifyChunk(DemuxerData
* chunk
) override
;
65 class VideoFactory
: public TestDataFactory
{
67 VideoFactory(base::TimeDelta duration
);
68 DemuxerConfigs
GetConfigs() const override
;
71 void ModifyChunk(DemuxerData
* chunk
) override
;
74 AudioFactory::AudioFactory(base::TimeDelta duration
)
75 : TestDataFactory("aac-44100-packet-%d", duration
, kAudioFramePeriod
) {
78 DemuxerConfigs
AudioFactory::GetConfigs() const {
79 return TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration_
);
82 void AudioFactory::ModifyChunk(DemuxerData
* chunk
) {
84 for (AccessUnit
& unit
: chunk
->access_units
) {
85 if (!unit
.data
.empty())
86 unit
.is_key_frame
= true;
90 VideoFactory::VideoFactory(base::TimeDelta duration
)
91 : TestDataFactory("h264-320x180-frame-%d", duration
, kVideoFramePeriod
) {
94 DemuxerConfigs
VideoFactory::GetConfigs() const {
95 return TestDataFactory::CreateVideoConfigs(kCodecH264
, duration_
,
99 void VideoFactory::ModifyChunk(DemuxerData
* chunk
) {
100 // The frames are taken from High profile and some are B-frames.
101 // The first 4 frames appear in the file in the following order:
104 // Decoding order: 0 1 2 3
105 // Presentation order: 0 2 1 4(3)
107 // I keep the last PTS to be 3 for simplicity.
109 // If the chunk contains EOS, it should not break the presentation order.
110 // For instance, the following chunk is ok:
113 // Decoding order: 0 1 2 -
114 // Presentation order: 0 2 1 -
116 // while this one might cause decoder to block:
119 // Decoding order: 0 1 -
120 // Presentation order: 0 2 - <------- might wait for the B frame forever
122 // With current base class implementation that always has EOS at the 4th
123 // place we are covered (http://crbug.com/526755)
126 DCHECK(chunk
->access_units
.size() == 4);
128 // Swap pts for second and third frames. Make first frame a key frame.
129 base::TimeDelta tmp
= chunk
->access_units
[1].timestamp
;
130 chunk
->access_units
[1].timestamp
= chunk
->access_units
[2].timestamp
;
131 chunk
->access_units
[2].timestamp
= tmp
;
133 chunk
->access_units
[0].is_key_frame
= true;
136 } // namespace (anonymous)
138 // The test fixture for MediaCodecDecoder
140 class MediaCodecDecoderTest
: public testing::Test
{
142 MediaCodecDecoderTest();
143 ~MediaCodecDecoderTest() override
;
145 // Conditions we wait for.
146 bool is_prefetched() const { return is_prefetched_
; }
147 bool is_stopped() const { return is_stopped_
; }
148 bool is_starved() const { return is_starved_
; }
150 void SetPrefetched(bool value
) { is_prefetched_
= value
; }
151 void SetStopped(bool value
) { is_stopped_
= value
; }
152 void SetStarved(bool value
) { is_starved_
= value
; }
155 typedef base::Callback
<bool()> Predicate
;
157 typedef base::Callback
<void(const DemuxerData
&)> DataAvailableCallback
;
159 // Waits for condition to become true or for timeout to expire.
160 // Returns true if the condition becomes true.
161 bool WaitForCondition(const Predicate
& condition
,
162 const base::TimeDelta
& timeout
= kDefaultTimeout
);
164 void SetDataFactory(scoped_ptr
<TestDataFactory
> factory
) {
165 data_factory_
= factory
.Pass();
168 DemuxerConfigs
GetConfigs() const {
169 // ASSERT_NE does not compile here because it expects void return value.
170 EXPECT_NE(nullptr, data_factory_
.get());
171 return data_factory_
->GetConfigs();
174 void CreateAudioDecoder();
175 void CreateVideoDecoder();
176 void SetVideoSurface();
177 void SetStopRequestAtTime(const base::TimeDelta
& time
) {
178 stop_request_time_
= time
;
181 // Decoder callbacks.
182 void OnDataRequested();
183 void OnStarvation() { is_starved_
= true; }
184 void OnDecoderDrained() {}
185 void OnStopDone() { is_stopped_
= true; }
186 void OnError() { DVLOG(0) << "MediaCodecDecoderTest::" << __FUNCTION__
; }
187 void OnUpdateCurrentTime(base::TimeDelta now_playing
,
188 base::TimeDelta last_buffered
,
190 // Add the |last_buffered| value for PTS. For video it is the same as
191 // |now_playing| and is equal to PTS, for audio |last_buffered| should
196 pts_stat_
.AddValue(last_buffered
);
198 if (stop_request_time_
!= kNoTimestamp() &&
199 now_playing
>= stop_request_time_
) {
200 stop_request_time_
= kNoTimestamp();
201 decoder_
->RequestToStop();
205 void OnVideoSizeChanged(const gfx::Size
& video_size
) {
206 video_size_
= video_size
;
209 void OnVideoCodecCreated() {}
211 scoped_ptr
<MediaCodecDecoder
> decoder_
;
212 scoped_ptr
<TestDataFactory
> data_factory_
;
213 Minimax
<base::TimeDelta
> pts_stat_
;
214 gfx::Size video_size_
;
217 bool is_timeout_expired() const { return is_timeout_expired_
; }
218 void SetTimeoutExpired(bool value
) { is_timeout_expired_
= value
; }
220 base::MessageLoop message_loop_
;
221 bool is_timeout_expired_
;
226 base::TimeDelta stop_request_time_
;
228 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner_
;
229 DataAvailableCallback data_available_cb_
;
230 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_
;
232 DISALLOW_COPY_AND_ASSIGN(MediaCodecDecoderTest
);
235 MediaCodecDecoderTest::MediaCodecDecoderTest()
236 : is_timeout_expired_(false),
237 is_prefetched_(false),
240 stop_request_time_(kNoTimestamp()),
241 task_runner_(base::ThreadTaskRunnerHandle::Get()) {
244 MediaCodecDecoderTest::~MediaCodecDecoderTest() {}
246 bool MediaCodecDecoderTest::WaitForCondition(const Predicate
& condition
,
247 const base::TimeDelta
& timeout
) {
248 // Let the message_loop_ process events.
249 // We start the timer and RunUntilIdle() until it signals.
251 SetTimeoutExpired(false);
253 base::Timer
timer(false, false);
254 timer
.Start(FROM_HERE
, timeout
,
255 base::Bind(&MediaCodecDecoderTest::SetTimeoutExpired
,
256 base::Unretained(this), true));
259 if (condition
.Run()) {
263 message_loop_
.RunUntilIdle();
264 } while (!is_timeout_expired());
266 DCHECK(!timer
.IsRunning());
270 void MediaCodecDecoderTest::CreateAudioDecoder() {
271 decoder_
= scoped_ptr
<MediaCodecDecoder
>(new MediaCodecAudioDecoder(
272 task_runner_
, 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::OnError
, base::Unretained(this)),
279 base::Bind(&MediaCodecDecoderTest::OnUpdateCurrentTime
,
280 base::Unretained(this))));
282 data_available_cb_
= base::Bind(&MediaCodecDecoder::OnDemuxerDataAvailable
,
283 base::Unretained(decoder_
.get()));
286 void MediaCodecDecoderTest::CreateVideoDecoder() {
287 decoder_
= scoped_ptr
<MediaCodecDecoder
>(new MediaCodecVideoDecoder(
288 task_runner_
, base::Bind(&MediaCodecDecoderTest::OnDataRequested
,
289 base::Unretained(this)),
290 base::Bind(&MediaCodecDecoderTest::OnStarvation
, base::Unretained(this)),
291 base::Bind(&MediaCodecDecoderTest::OnDecoderDrained
,
292 base::Unretained(this)),
293 base::Bind(&MediaCodecDecoderTest::OnStopDone
, base::Unretained(this)),
294 base::Bind(&MediaCodecDecoderTest::OnError
, base::Unretained(this)),
295 base::Bind(&MediaCodecDecoderTest::OnUpdateCurrentTime
,
296 base::Unretained(this)),
297 base::Bind(&MediaCodecDecoderTest::OnVideoSizeChanged
,
298 base::Unretained(this)),
299 base::Bind(&MediaCodecDecoderTest::OnVideoCodecCreated
,
300 base::Unretained(this))));
302 data_available_cb_
= base::Bind(&MediaCodecDecoder::OnDemuxerDataAvailable
,
303 base::Unretained(decoder_
.get()));
306 void MediaCodecDecoderTest::OnDataRequested() {
311 base::TimeDelta delay
;
312 if (!data_factory_
->CreateChunk(&data
, &delay
))
315 task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(data_available_cb_
, data
),
319 void MediaCodecDecoderTest::SetVideoSurface() {
320 surface_texture_
= gfx::SurfaceTexture::Create(0);
321 gfx::ScopedJavaSurface
surface(surface_texture_
.get());
322 ASSERT_NE(nullptr, decoder_
.get());
323 MediaCodecVideoDecoder
* video_decoder
=
324 static_cast<MediaCodecVideoDecoder
*>(decoder_
.get());
325 video_decoder
->SetVideoSurface(surface
.Pass());
328 TEST_F(MediaCodecDecoderTest
, AudioPrefetch
) {
329 CreateAudioDecoder();
331 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
332 SetDataFactory(scoped_ptr
<TestDataFactory
>(new AudioFactory(duration
)));
334 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
335 base::Unretained(this), true));
337 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
338 base::Unretained(this))));
341 TEST_F(MediaCodecDecoderTest
, VideoPrefetch
) {
342 CreateVideoDecoder();
344 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
345 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
347 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
348 base::Unretained(this), true));
350 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
351 base::Unretained(this))));
354 TEST_F(MediaCodecDecoderTest
, AudioConfigureNoParams
) {
355 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
357 CreateAudioDecoder();
359 // Cannot configure without config parameters.
360 EXPECT_EQ(MediaCodecDecoder::kConfigFailure
, decoder_
->Configure());
363 TEST_F(MediaCodecDecoderTest
, AudioConfigureValidParams
) {
364 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
366 CreateAudioDecoder();
368 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
369 scoped_ptr
<AudioFactory
> factory(new AudioFactory(duration
));
370 decoder_
->SetDemuxerConfigs(factory
->GetConfigs());
372 EXPECT_EQ(MediaCodecDecoder::kConfigOk
, decoder_
->Configure());
375 TEST_F(MediaCodecDecoderTest
, VideoConfigureNoParams
) {
376 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
378 CreateVideoDecoder();
380 // decoder_->Configure() searches back for the key frame.
381 // We have to prefetch decoder.
383 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
384 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
386 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
387 base::Unretained(this), true));
389 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
390 base::Unretained(this))));
394 // Cannot configure without config parameters.
395 EXPECT_EQ(MediaCodecDecoder::kConfigFailure
, decoder_
->Configure());
398 TEST_F(MediaCodecDecoderTest
, VideoConfigureNoSurface
) {
399 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
401 CreateVideoDecoder();
403 // decoder_->Configure() searches back for the key frame.
404 // We have to prefetch decoder.
406 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
407 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
409 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
410 base::Unretained(this), true));
412 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
413 base::Unretained(this))));
415 decoder_
->SetDemuxerConfigs(GetConfigs());
417 // Surface is not set, Configure() should fail.
419 EXPECT_EQ(MediaCodecDecoder::kConfigFailure
, decoder_
->Configure());
422 TEST_F(MediaCodecDecoderTest
, VideoConfigureInvalidSurface
) {
423 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
425 CreateVideoDecoder();
427 // decoder_->Configure() searches back for the key frame.
428 // We have to prefetch decoder.
430 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
431 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
433 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
434 base::Unretained(this), true));
436 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
437 base::Unretained(this))));
439 decoder_
->SetDemuxerConfigs(GetConfigs());
441 // Prepare the surface.
442 scoped_refptr
<gfx::SurfaceTexture
> surface_texture(
443 gfx::SurfaceTexture::Create(0));
444 gfx::ScopedJavaSurface
surface(surface_texture
.get());
446 // Release the surface texture.
447 surface_texture
= NULL
;
449 MediaCodecVideoDecoder
* video_decoder
=
450 static_cast<MediaCodecVideoDecoder
*>(decoder_
.get());
451 video_decoder
->SetVideoSurface(surface
.Pass());
453 EXPECT_EQ(MediaCodecDecoder::kConfigFailure
, decoder_
->Configure());
456 TEST_F(MediaCodecDecoderTest
, VideoConfigureValidParams
) {
457 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
459 CreateVideoDecoder();
461 // decoder_->Configure() searches back for the key frame.
462 // We have to prefetch decoder.
464 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
465 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
467 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
468 base::Unretained(this), true));
470 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
471 base::Unretained(this))));
473 decoder_
->SetDemuxerConfigs(GetConfigs());
477 // Now we can expect Configure() to succeed.
479 EXPECT_EQ(MediaCodecDecoder::kConfigOk
, decoder_
->Configure());
482 TEST_F(MediaCodecDecoderTest
, AudioStartWithoutConfigure
) {
483 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
485 CreateAudioDecoder();
487 // Decoder has to be prefetched and configured before the start.
489 // Wrong state: not prefetched
490 EXPECT_FALSE(decoder_
->Start(base::TimeDelta::FromMilliseconds(0)));
493 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
494 SetDataFactory(scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
496 // Prefetch to avoid starvation at the beginning of playback.
497 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
498 base::Unretained(this), true));
500 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
501 base::Unretained(this))));
503 // Still, decoder is not configured.
504 EXPECT_FALSE(decoder_
->Start(base::TimeDelta::FromMilliseconds(0)));
507 // http://crbug.com/518900
508 TEST_F(MediaCodecDecoderTest
, AudioPlayTillCompletion
) {
509 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
511 DVLOG(0) << "AudioPlayTillCompletion started";
513 CreateAudioDecoder();
515 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
516 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(1500);
518 SetDataFactory(scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
520 // Prefetch to avoid starvation at the beginning of playback.
521 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
522 base::Unretained(this), true));
524 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
525 base::Unretained(this))));
527 decoder_
->SetDemuxerConfigs(GetConfigs());
529 EXPECT_EQ(MediaCodecDecoder::kConfigOk
, decoder_
->Configure());
531 EXPECT_TRUE(decoder_
->Start(base::TimeDelta::FromMilliseconds(0)));
533 EXPECT_TRUE(WaitForCondition(
534 base::Bind(&MediaCodecDecoderTest::is_stopped
, base::Unretained(this)),
537 EXPECT_TRUE(decoder_
->IsStopped());
538 EXPECT_TRUE(decoder_
->IsCompleted());
540 // Last buffered timestamp should be no less than PTS.
541 // The number of hits in pts_stat_ depends on the preroll implementation.
542 // We might not report the time for the first buffer after preroll that
543 // is written to the audio track. pts_stat_.num_values() is either 21 or 22.
544 EXPECT_LE(21, pts_stat_
.num_values());
545 EXPECT_LE(data_factory_
->last_pts(), pts_stat_
.max());
547 DVLOG(0) << "AudioPlayTillCompletion stopping";
550 TEST_F(MediaCodecDecoderTest
, VideoPlayTillCompletion
) {
551 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
553 CreateVideoDecoder();
555 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
556 // The first output frame might come out with significant delay. Apparently
557 // the codec does initial configuration at this time. We increase the timeout
558 // to leave a room of 1 second for this initial configuration.
559 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(1500);
560 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
563 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
564 base::Unretained(this), true));
566 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
567 base::Unretained(this))));
569 decoder_
->SetDemuxerConfigs(GetConfigs());
573 EXPECT_EQ(MediaCodecDecoder::kConfigOk
, decoder_
->Configure());
575 EXPECT_TRUE(decoder_
->Start(base::TimeDelta::FromMilliseconds(0)));
577 EXPECT_TRUE(WaitForCondition(
578 base::Bind(&MediaCodecDecoderTest::is_stopped
, base::Unretained(this)),
581 EXPECT_TRUE(decoder_
->IsStopped());
582 EXPECT_TRUE(decoder_
->IsCompleted());
584 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
);
585 EXPECT_EQ(expected_video_frames
, pts_stat_
.num_values());
586 EXPECT_EQ(data_factory_
->last_pts(), pts_stat_
.max());
589 TEST_F(MediaCodecDecoderTest
, VideoStopAndResume
) {
590 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
592 CreateVideoDecoder();
594 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
595 base::TimeDelta stop_request_time
= base::TimeDelta::FromMilliseconds(200);
596 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(1000);
598 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
601 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
602 base::Unretained(this), true));
604 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
605 base::Unretained(this))));
607 decoder_
->SetDemuxerConfigs(GetConfigs());
611 EXPECT_EQ(MediaCodecDecoder::kConfigOk
, decoder_
->Configure());
613 SetStopRequestAtTime(stop_request_time
);
615 // Start from the beginning.
616 EXPECT_TRUE(decoder_
->Start(base::TimeDelta::FromMilliseconds(0)));
618 EXPECT_TRUE(WaitForCondition(
619 base::Bind(&MediaCodecDecoderTest::is_stopped
, base::Unretained(this)),
622 EXPECT_TRUE(decoder_
->IsStopped());
623 EXPECT_FALSE(decoder_
->IsCompleted());
625 base::TimeDelta last_pts
= pts_stat_
.max();
627 EXPECT_GE(last_pts
, stop_request_time
);
629 // Resume playback from last_pts:
631 SetPrefetched(false);
635 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
636 base::Unretained(this), true));
638 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
639 base::Unretained(this))));
642 EXPECT_TRUE(decoder_
->Start(last_pts
));
644 // Wait till completion.
645 EXPECT_TRUE(WaitForCondition(
646 base::Bind(&MediaCodecDecoderTest::is_stopped
, base::Unretained(this)),
649 EXPECT_TRUE(decoder_
->IsStopped());
650 EXPECT_TRUE(decoder_
->IsCompleted());
652 // We should not skip frames in this process.
653 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
);
654 EXPECT_EQ(expected_video_frames
, pts_stat_
.num_values());
655 EXPECT_EQ(data_factory_
->last_pts(), pts_stat_
.max());
658 // http://crbug.com/518900
659 TEST_F(MediaCodecDecoderTest
, DISABLED_AudioStarvationAndStop
) {
660 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
662 CreateAudioDecoder();
664 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(200);
665 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(400);
667 AudioFactory
* factory
= new AudioFactory(duration
);
668 factory
->SetStarvationMode(true);
669 SetDataFactory(scoped_ptr
<AudioFactory
>(factory
));
672 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
673 base::Unretained(this), true));
675 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
676 base::Unretained(this))));
679 decoder_
->SetDemuxerConfigs(GetConfigs());
681 EXPECT_EQ(MediaCodecDecoder::kConfigOk
, decoder_
->Configure());
684 EXPECT_TRUE(decoder_
->Start(base::TimeDelta::FromMilliseconds(0)));
686 // Wait for starvation.
687 EXPECT_TRUE(WaitForCondition(
688 base::Bind(&MediaCodecDecoderTest::is_starved
, base::Unretained(this)),
691 EXPECT_FALSE(decoder_
->IsStopped());
692 EXPECT_FALSE(decoder_
->IsCompleted());
694 EXPECT_GT(pts_stat_
.num_values(), 0);
696 // After starvation we should be able to stop decoder.
697 decoder_
->RequestToStop();
699 EXPECT_TRUE(WaitForCondition(
700 base::Bind(&MediaCodecDecoderTest::is_stopped
, base::Unretained(this))));
702 EXPECT_TRUE(decoder_
->IsStopped());
703 EXPECT_FALSE(decoder_
->IsCompleted());
706 TEST_F(MediaCodecDecoderTest
, VideoFirstUnitIsReconfig
) {
707 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
709 // Test that the kConfigChanged unit that comes before the first data unit
710 // gets processed, i.e. is not lost.
712 CreateVideoDecoder();
714 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(200);
715 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(1000);
716 SetDataFactory(scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
718 // Ask factory to produce initial configuration unit. The configuraton will
719 // be factory.GetConfigs().
720 data_factory_
->RequestInitialConfigs();
722 // Create am alternative configuration (we just alter video size).
723 DemuxerConfigs alt_configs
= data_factory_
->GetConfigs();
724 alt_configs
.video_size
= gfx::Size(100, 100);
726 // Pass the alternative configuration to decoder.
727 decoder_
->SetDemuxerConfigs(alt_configs
);
730 decoder_
->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched
,
731 base::Unretained(this), true));
733 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched
,
734 base::Unretained(this))));
736 // Current implementation reports the new video size after
737 // SetDemuxerConfigs(), verify that it is alt size.
738 EXPECT_EQ(alt_configs
.video_size
, video_size_
);
743 EXPECT_EQ(MediaCodecDecoder::kConfigOk
, decoder_
->Configure());
746 EXPECT_TRUE(decoder_
->Start(base::TimeDelta::FromMilliseconds(0)));
748 // Wait for completion.
749 EXPECT_TRUE(WaitForCondition(
750 base::Bind(&MediaCodecDecoderTest::is_stopped
, base::Unretained(this)),
753 EXPECT_TRUE(decoder_
->IsStopped());
754 EXPECT_TRUE(decoder_
->IsCompleted());
755 EXPECT_EQ(data_factory_
->last_pts(), pts_stat_
.max());
757 // Check that the reported video size is the one from the in-stream configs.
758 EXPECT_EQ(data_factory_
->GetConfigs().video_size
, video_size_
);