Roll src/third_party/WebKit d10c917:a1123a1 (svn 198729:198730)
[chromium-blink-merge.git] / media / base / android / media_codec_decoder_unittest.cc
blob7f8d81337dcc25befecdaf77c01955f0a16940f2
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 "testing/gtest/include/gtest/gtest.h"
14 #include "ui/gl/android/surface_texture.h"
16 namespace media {
18 // Helper macro to skip the test if MediaCodecBridge isn't available.
19 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
20 do { \
21 if (!MediaCodecBridge::IsAvailable()) { \
22 VLOG(0) << "Could not run test - not supported on device."; \
23 return; \
24 } \
25 } while (0)
27 namespace {
29 const base::TimeDelta kDefaultTimeout = base::TimeDelta::FromMilliseconds(200);
30 const base::TimeDelta kAudioFramePeriod = base::TimeDelta::FromMilliseconds(20);
31 const base::TimeDelta kVideoFramePeriod = base::TimeDelta::FromMilliseconds(20);
33 class AudioFactory : public TestDataFactory {
34 public:
35 AudioFactory(const base::TimeDelta& duration);
36 DemuxerConfigs GetConfigs() const override;
38 protected:
39 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override;
42 class VideoFactory : public TestDataFactory {
43 public:
44 VideoFactory(const base::TimeDelta& duration);
45 DemuxerConfigs GetConfigs() const override;
47 protected:
48 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override;
51 AudioFactory::AudioFactory(const base::TimeDelta& duration)
52 : TestDataFactory("vorbis-packet-%d", duration, kAudioFramePeriod) {
55 DemuxerConfigs AudioFactory::GetConfigs() const {
56 return TestDataFactory::CreateAudioConfigs(kCodecVorbis, duration_);
59 void AudioFactory::ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) {
60 // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
61 // NuMediaExtractor.cpp in Android source code.
62 uint8 padding[4] = {0xff, 0xff, 0xff, 0xff};
63 unit->data.insert(unit->data.end(), padding, padding + 4);
66 VideoFactory::VideoFactory(const base::TimeDelta& duration)
67 : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod) {
70 DemuxerConfigs VideoFactory::GetConfigs() const {
71 return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_,
72 gfx::Size(320, 180));
75 void VideoFactory::ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) {
76 // The frames are taken from High profile and some are B-frames.
77 // The first 4 frames appear in the file in the following order:
79 // Frames: I P B P
80 // Decoding order: 0 1 2 3
81 // Presentation order: 0 2 1 4(3)
83 // I keep the last PTS to be 3 for simplicity.
85 // Swap pts for second and third frames.
86 if (index_in_chunk == 1) // second frame
87 unit->timestamp += frame_period_;
88 if (index_in_chunk == 2) // third frame
89 unit->timestamp -= frame_period_;
91 if (index_in_chunk == 0)
92 unit->is_key_frame = true;
95 // Class that computes statistics: number of calls, minimum and maximum values.
96 // It is used for PTS statistics to verify that playback did actually happen.
98 template <typename T>
99 class Minimax {
100 public:
101 Minimax() : num_values_(0) {}
102 ~Minimax() {}
104 void AddValue(const T& value) {
105 ++num_values_;
106 if (value < min_)
107 min_ = value;
108 else if (max_ < value)
109 max_ = value;
112 const T& min() const { return min_; }
113 const T& max() const { return max_; }
114 int num_values() const { return num_values_; }
116 private:
117 T min_;
118 T max_;
119 int num_values_;
122 } // namespace (anonymous)
124 // The test fixture for MediaCodecDecoder
126 class MediaCodecDecoderTest : public testing::Test {
127 public:
128 MediaCodecDecoderTest();
129 ~MediaCodecDecoderTest() override;
131 // Conditions we wait for.
132 bool is_prefetched() const { return is_prefetched_; }
133 bool is_stopped() const { return is_stopped_; }
134 bool is_starved() const { return is_starved_; }
136 void SetPrefetched(bool value) { is_prefetched_ = value; }
137 void SetStopped(bool value) { is_stopped_ = value; }
138 void SetStarved(bool value) { is_starved_ = value; }
140 protected:
141 typedef base::Callback<bool()> Predicate;
143 typedef base::Callback<void(const DemuxerData&)> DataAvailableCallback;
145 // Waits for condition to become true or for timeout to expire.
146 // Returns true if the condition becomes true.
147 bool WaitForCondition(const Predicate& condition,
148 const base::TimeDelta& timeout = kDefaultTimeout);
150 void SetDataFactory(scoped_ptr<TestDataFactory> factory) {
151 data_factory_ = factory.Pass();
154 DemuxerConfigs GetConfigs() const {
155 // ASSERT_NE does not compile here because it expects void return value.
156 EXPECT_NE(nullptr, data_factory_.get());
157 return data_factory_->GetConfigs();
160 void CreateAudioDecoder();
161 void CreateVideoDecoder();
162 void SetVideoSurface();
163 void SetStopRequestAtTime(const base::TimeDelta& time) {
164 stop_request_time_ = time;
167 // Decoder callbacks.
168 void OnDataRequested();
169 void OnStarvation() { is_starved_ = true; }
170 void OnStopDone() { is_stopped_ = true; }
171 void OnError() {}
172 void OnUpdateCurrentTime(base::TimeDelta now_playing,
173 base::TimeDelta last_buffered) {
174 pts_stat_.AddValue(now_playing);
176 if (stop_request_time_ != kNoTimestamp() &&
177 now_playing >= stop_request_time_) {
178 stop_request_time_ = kNoTimestamp();
179 decoder_->RequestToStop();
183 void OnVideoSizeChanged(const gfx::Size& video_size) {}
184 void OnVideoCodecCreated() {}
186 scoped_ptr<MediaCodecDecoder> decoder_;
187 scoped_ptr<TestDataFactory> data_factory_;
188 Minimax<base::TimeDelta> pts_stat_;
190 private:
191 bool is_timeout_expired() const { return is_timeout_expired_; }
192 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; }
194 base::MessageLoop message_loop_;
195 bool is_timeout_expired_;
197 bool is_prefetched_;
198 bool is_stopped_;
199 bool is_starved_;
200 base::TimeDelta stop_request_time_;
202 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
203 DataAvailableCallback data_available_cb_;
204 scoped_refptr<gfx::SurfaceTexture> surface_texture_;
206 DISALLOW_COPY_AND_ASSIGN(MediaCodecDecoderTest);
209 MediaCodecDecoderTest::MediaCodecDecoderTest()
210 : is_timeout_expired_(false),
211 is_prefetched_(false),
212 is_stopped_(false),
213 is_starved_(false),
214 stop_request_time_(kNoTimestamp()),
215 task_runner_(base::ThreadTaskRunnerHandle::Get()) {
218 MediaCodecDecoderTest::~MediaCodecDecoderTest() {}
220 bool MediaCodecDecoderTest::WaitForCondition(const Predicate& condition,
221 const base::TimeDelta& timeout) {
222 // Let the message_loop_ process events.
223 // We start the timer and RunUntilIdle() until it signals.
225 SetTimeoutExpired(false);
227 base::Timer timer(false, false);
228 timer.Start(FROM_HERE, timeout,
229 base::Bind(&MediaCodecDecoderTest::SetTimeoutExpired,
230 base::Unretained(this), true));
232 do {
233 if (condition.Run()) {
234 timer.Stop();
235 return true;
237 message_loop_.RunUntilIdle();
238 } while (!is_timeout_expired());
240 DCHECK(!timer.IsRunning());
241 return false;
244 void MediaCodecDecoderTest::CreateAudioDecoder() {
245 decoder_ = scoped_ptr<MediaCodecDecoder>(new MediaCodecAudioDecoder(
246 task_runner_, base::Bind(&MediaCodecDecoderTest::OnDataRequested,
247 base::Unretained(this)),
248 base::Bind(&MediaCodecDecoderTest::OnStarvation, base::Unretained(this)),
249 base::Bind(&MediaCodecDecoderTest::OnStopDone, base::Unretained(this)),
250 base::Bind(&MediaCodecDecoderTest::OnError, base::Unretained(this)),
251 base::Bind(&MediaCodecDecoderTest::OnUpdateCurrentTime,
252 base::Unretained(this))));
254 data_available_cb_ = base::Bind(&MediaCodecDecoder::OnDemuxerDataAvailable,
255 base::Unretained(decoder_.get()));
258 void MediaCodecDecoderTest::CreateVideoDecoder() {
259 decoder_ = scoped_ptr<MediaCodecDecoder>(new MediaCodecVideoDecoder(
260 task_runner_, base::Bind(&MediaCodecDecoderTest::OnDataRequested,
261 base::Unretained(this)),
262 base::Bind(&MediaCodecDecoderTest::OnStarvation, base::Unretained(this)),
263 base::Bind(&MediaCodecDecoderTest::OnStopDone, base::Unretained(this)),
264 base::Bind(&MediaCodecDecoderTest::OnError, base::Unretained(this)),
265 base::Bind(&MediaCodecDecoderTest::OnUpdateCurrentTime,
266 base::Unretained(this)),
267 base::Bind(&MediaCodecDecoderTest::OnVideoSizeChanged,
268 base::Unretained(this)),
269 base::Bind(&MediaCodecDecoderTest::OnVideoCodecCreated,
270 base::Unretained(this))));
272 data_available_cb_ = base::Bind(&MediaCodecDecoder::OnDemuxerDataAvailable,
273 base::Unretained(decoder_.get()));
276 void MediaCodecDecoderTest::OnDataRequested() {
277 if (!data_factory_)
278 return;
280 DemuxerData data;
281 base::TimeDelta delay;
282 if (!data_factory_->CreateChunk(&data, &delay))
283 return;
285 task_runner_->PostDelayedTask(FROM_HERE, base::Bind(data_available_cb_, data),
286 delay);
289 void MediaCodecDecoderTest::SetVideoSurface() {
290 surface_texture_ = gfx::SurfaceTexture::Create(0);
291 gfx::ScopedJavaSurface surface(surface_texture_.get());
292 ASSERT_NE(nullptr, decoder_.get());
293 MediaCodecVideoDecoder* video_decoder =
294 static_cast<MediaCodecVideoDecoder*>(decoder_.get());
295 video_decoder->SetPendingSurface(surface.Pass());
298 TEST_F(MediaCodecDecoderTest, AudioPrefetch) {
299 CreateAudioDecoder();
301 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
302 SetDataFactory(scoped_ptr<TestDataFactory>(new AudioFactory(duration)));
304 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
305 base::Unretained(this), true));
307 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
308 base::Unretained(this))));
311 TEST_F(MediaCodecDecoderTest, VideoPrefetch) {
312 CreateVideoDecoder();
314 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
315 SetDataFactory(scoped_ptr<VideoFactory>(new VideoFactory(duration)));
317 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
318 base::Unretained(this), true));
320 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
321 base::Unretained(this))));
324 TEST_F(MediaCodecDecoderTest, AudioConfigureNoParams) {
325 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
327 CreateAudioDecoder();
329 // Cannot configure without config parameters.
330 EXPECT_EQ(MediaCodecDecoder::CONFIG_FAILURE, decoder_->Configure());
333 TEST_F(MediaCodecDecoderTest, AudioConfigureValidParams) {
334 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
336 CreateAudioDecoder();
338 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
339 scoped_ptr<AudioFactory> factory(new AudioFactory(duration));
340 decoder_->SetDemuxerConfigs(factory->GetConfigs());
342 EXPECT_EQ(MediaCodecDecoder::CONFIG_OK, decoder_->Configure());
345 TEST_F(MediaCodecDecoderTest, VideoConfigureNoParams) {
346 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
348 CreateVideoDecoder();
350 // Cannot configure without config parameters.
351 EXPECT_EQ(MediaCodecDecoder::CONFIG_FAILURE, decoder_->Configure());
354 TEST_F(MediaCodecDecoderTest, VideoConfigureNoSurface) {
355 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
357 CreateVideoDecoder();
359 // decoder_->Configure() searches back for the key frame.
360 // We have to prefetch decoder.
362 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
363 SetDataFactory(scoped_ptr<VideoFactory>(new VideoFactory(duration)));
365 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
366 base::Unretained(this), true));
368 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
369 base::Unretained(this))));
371 decoder_->SetDemuxerConfigs(GetConfigs());
373 // Surface is not set, Configure() should fail.
375 EXPECT_EQ(MediaCodecDecoder::CONFIG_FAILURE, decoder_->Configure());
378 TEST_F(MediaCodecDecoderTest, VideoConfigureInvalidSurface) {
379 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
381 CreateVideoDecoder();
383 // decoder_->Configure() searches back for the key frame.
384 // We have to prefetch decoder.
386 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
387 SetDataFactory(scoped_ptr<VideoFactory>(new VideoFactory(duration)));
389 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
390 base::Unretained(this), true));
392 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
393 base::Unretained(this))));
395 decoder_->SetDemuxerConfigs(GetConfigs());
397 // Prepare the surface.
398 scoped_refptr<gfx::SurfaceTexture> surface_texture(
399 gfx::SurfaceTexture::Create(0));
400 gfx::ScopedJavaSurface surface(surface_texture.get());
402 // Release the surface texture.
403 surface_texture = NULL;
405 MediaCodecVideoDecoder* video_decoder =
406 static_cast<MediaCodecVideoDecoder*>(decoder_.get());
407 video_decoder->SetPendingSurface(surface.Pass());
409 EXPECT_EQ(MediaCodecDecoder::CONFIG_FAILURE, decoder_->Configure());
412 TEST_F(MediaCodecDecoderTest, VideoConfigureValidParams) {
413 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
415 CreateVideoDecoder();
417 // decoder_->Configure() searches back for the key frame.
418 // We have to prefetch decoder.
420 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
421 SetDataFactory(scoped_ptr<VideoFactory>(new VideoFactory(duration)));
423 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
424 base::Unretained(this), true));
426 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
427 base::Unretained(this))));
429 decoder_->SetDemuxerConfigs(GetConfigs());
431 SetVideoSurface();
433 // Now we can expect Configure() to succeed.
435 EXPECT_EQ(MediaCodecDecoder::CONFIG_OK, decoder_->Configure());
438 TEST_F(MediaCodecDecoderTest, AudioStartWithoutConfigure) {
439 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
441 CreateAudioDecoder();
443 // Decoder has to be prefetched and configured before the start.
445 // Wrong state: not prefetched
446 EXPECT_FALSE(decoder_->Start(base::TimeDelta::FromMilliseconds(0)));
448 // Do the prefetch.
449 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
450 SetDataFactory(scoped_ptr<AudioFactory>(new AudioFactory(duration)));
452 // Prefetch to avoid starvation at the beginning of playback.
453 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
454 base::Unretained(this), true));
456 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
457 base::Unretained(this))));
459 // Still, decoder is not configured.
460 EXPECT_FALSE(decoder_->Start(base::TimeDelta::FromMilliseconds(0)));
463 TEST_F(MediaCodecDecoderTest, AudioPlayTillCompletion) {
464 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
466 CreateAudioDecoder();
468 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
469 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(600);
471 SetDataFactory(scoped_ptr<AudioFactory>(new AudioFactory(duration)));
473 // Prefetch to avoid starvation at the beginning of playback.
474 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
475 base::Unretained(this), true));
477 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
478 base::Unretained(this))));
480 decoder_->SetDemuxerConfigs(GetConfigs());
482 EXPECT_EQ(MediaCodecDecoder::CONFIG_OK, decoder_->Configure());
484 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0)));
486 EXPECT_TRUE(WaitForCondition(
487 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)),
488 timeout));
490 EXPECT_TRUE(decoder_->IsStopped());
491 EXPECT_TRUE(decoder_->IsCompleted());
493 // It is hard to properly estimate minimum and maximum values because
494 // reported times are different from PTS.
495 EXPECT_EQ(25, pts_stat_.num_values());
498 TEST_F(MediaCodecDecoderTest, VideoPlayTillCompletion) {
499 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
501 CreateVideoDecoder();
503 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
504 // The first output frame might come out with significant delay. Apparently
505 // the codec does initial configuration at this time. We increase the timeout
506 // to leave a room of 1 second for this initial configuration.
507 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
508 SetDataFactory(scoped_ptr<VideoFactory>(new VideoFactory(duration)));
510 // Prefetch
511 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
512 base::Unretained(this), true));
514 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
515 base::Unretained(this))));
517 decoder_->SetDemuxerConfigs(GetConfigs());
519 SetVideoSurface();
521 EXPECT_EQ(MediaCodecDecoder::CONFIG_OK, decoder_->Configure());
523 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0)));
525 EXPECT_TRUE(WaitForCondition(
526 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)),
527 timeout));
529 EXPECT_TRUE(decoder_->IsStopped());
530 EXPECT_TRUE(decoder_->IsCompleted());
532 EXPECT_EQ(26, pts_stat_.num_values());
533 EXPECT_EQ(data_factory_->last_pts(), pts_stat_.max());
536 TEST_F(MediaCodecDecoderTest, VideoStopAndResume) {
537 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
539 CreateVideoDecoder();
541 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
542 base::TimeDelta stop_request_time = base::TimeDelta::FromMilliseconds(200);
543 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1000);
545 SetDataFactory(scoped_ptr<VideoFactory>(new VideoFactory(duration)));
547 // Prefetch
548 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
549 base::Unretained(this), true));
551 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
552 base::Unretained(this))));
554 decoder_->SetDemuxerConfigs(GetConfigs());
556 SetVideoSurface();
558 EXPECT_EQ(MediaCodecDecoder::CONFIG_OK, decoder_->Configure());
560 SetStopRequestAtTime(stop_request_time);
562 // Start from the beginning.
563 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0)));
565 EXPECT_TRUE(WaitForCondition(
566 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)),
567 timeout));
569 EXPECT_TRUE(decoder_->IsStopped());
570 EXPECT_FALSE(decoder_->IsCompleted());
572 base::TimeDelta last_pts = pts_stat_.max();
574 EXPECT_GE(last_pts, stop_request_time);
576 // Resume playback from last_pts:
578 SetPrefetched(false);
579 SetStopped(false);
581 // Prefetch again.
582 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
583 base::Unretained(this), true));
585 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
586 base::Unretained(this))));
588 // Then start.
589 EXPECT_TRUE(decoder_->Start(last_pts));
591 // Wait till completion.
592 EXPECT_TRUE(WaitForCondition(
593 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this)),
594 timeout));
596 EXPECT_TRUE(decoder_->IsStopped());
597 EXPECT_TRUE(decoder_->IsCompleted());
599 // We should not skip frames in this process.
600 EXPECT_EQ(26, pts_stat_.num_values());
601 EXPECT_EQ(data_factory_->last_pts(), pts_stat_.max());
604 TEST_F(MediaCodecDecoderTest, AudioStarvationAndStop) {
605 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
607 CreateAudioDecoder();
609 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(200);
610 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(400);
612 AudioFactory* factory = new AudioFactory(duration);
613 factory->SetStarvationMode(true);
614 SetDataFactory(scoped_ptr<AudioFactory>(factory));
616 // Prefetch.
617 decoder_->Prefetch(base::Bind(&MediaCodecDecoderTest::SetPrefetched,
618 base::Unretained(this), true));
620 EXPECT_TRUE(WaitForCondition(base::Bind(&MediaCodecDecoderTest::is_prefetched,
621 base::Unretained(this))));
623 // Configure.
624 decoder_->SetDemuxerConfigs(GetConfigs());
626 EXPECT_EQ(MediaCodecDecoder::CONFIG_OK, decoder_->Configure());
628 // Start.
629 EXPECT_TRUE(decoder_->Start(base::TimeDelta::FromMilliseconds(0)));
631 // Wait for starvation.
632 EXPECT_TRUE(WaitForCondition(
633 base::Bind(&MediaCodecDecoderTest::is_starved, base::Unretained(this)),
634 timeout));
636 EXPECT_FALSE(decoder_->IsStopped());
637 EXPECT_FALSE(decoder_->IsCompleted());
639 EXPECT_GT(pts_stat_.num_values(), 0);
641 // After starvation we should be able to stop decoder.
642 decoder_->RequestToStop();
644 EXPECT_TRUE(WaitForCondition(
645 base::Bind(&MediaCodecDecoderTest::is_stopped, base::Unretained(this))));
647 EXPECT_TRUE(decoder_->IsStopped());
648 EXPECT_FALSE(decoder_->IsCompleted());
651 } // namespace media