Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / base / android / media_codec_decoder_unittest.cc
blob9d1b7ab8ae38cdc2bef6e5f8a8eedd2228675365
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.
5 #include "base/bind.h"
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"
18 namespace media {
20 // Helper macro to skip the test if MediaCodecBridge isn't available.
21 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
22 do { \
23 if (!MediaCodecBridge::IsAvailable()) { \
24 VLOG(0) << "Could not run test - not supported on device."; \
25 return; \
26 } \
27 } while (0)
29 namespace {
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 {
57 public:
58 AudioFactory(base::TimeDelta duration);
59 DemuxerConfigs GetConfigs() const override;
61 protected:
62 void ModifyChunk(DemuxerData* chunk) override;
65 class VideoFactory : public TestDataFactory {
66 public:
67 VideoFactory(base::TimeDelta duration);
68 DemuxerConfigs GetConfigs() const override;
70 protected:
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) {
83 DCHECK(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_,
96 gfx::Size(320, 180));
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:
103 // Frames: I P B P
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:
112 // Frames: I P B EOS
113 // Decoding order: 0 1 2 -
114 // Presentation order: 0 2 1 -
116 // while this one might cause decoder to block:
118 // Frames: I P EOS
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)
125 DCHECK(chunk);
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 {
141 public:
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; }
154 protected:
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,
189 bool postpone) {
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
192 // exceed PTS.
193 if (postpone)
194 return;
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_;
216 private:
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_;
223 bool is_prefetched_;
224 bool is_stopped_;
225 bool is_starved_;
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),
238 is_stopped_(false),
239 is_starved_(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));
258 do {
259 if (condition.Run()) {
260 timer.Stop();
261 return true;
263 message_loop_.RunUntilIdle();
264 } while (!is_timeout_expired());
266 DCHECK(!timer.IsRunning());
267 return false;
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() {
307 if (!data_factory_)
308 return;
310 DemuxerData data;
311 base::TimeDelta delay;
312 if (!data_factory_->CreateChunk(&data, &delay))
313 return;
315 task_runner_->PostDelayedTask(FROM_HERE, base::Bind(data_available_cb_, data),
316 delay);
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))));
392 SetVideoSurface();
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());
475 SetVideoSurface();
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)));
492 // Do the prefetch.
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)),
535 timeout));
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)));
562 // Prefetch
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());
571 SetVideoSurface();
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)),
579 timeout));
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)));
600 // Prefetch
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());
609 SetVideoSurface();
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)),
620 timeout));
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);
632 SetStopped(false);
634 // Prefetch again.
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))));
641 // Then start.
642 EXPECT_TRUE(decoder_->Start(last_pts));
644 // Wait till completion.
645 EXPECT_TRUE(WaitForCondition(
646 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)),
647 timeout));
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));
671 // Prefetch.
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))));
678 // Configure.
679 decoder_->SetDemuxerConfigs(GetConfigs());
681 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure());
683 // Start.
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)),
689 timeout));
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);
729 // Prefetch.
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_);
740 SetVideoSurface();
742 // Configure.
743 EXPECT_EQ(MediaCodecDecoder::kConfigOk, decoder_->Configure());
745 // Start.
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)),
751 timeout));
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_);
761 } // namespace media