Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1363)

Side by Side Diff: media/base/android/media_codec_decoder_unittest.cc

Issue 2276343005: Delete MediaCodecPlayer, it's time! (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/android/media_codec_decoder.cc ('k') | media/base/android/media_codec_player.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « media/base/android/media_codec_decoder.cc ('k') | media/base/android/media_codec_player.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698