Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / media / base / android / media_codec_player_unittest.cc
blobaf65f059f099cd5dced88c820734becf2595d5db
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/timer/timer.h"
8 #include "media/base/android/demuxer_android.h"
9 #include "media/base/android/media_codec_bridge.h"
10 #include "media/base/android/media_codec_player.h"
11 #include "media/base/android/media_player_manager.h"
12 #include "media/base/android/test_data_factory.h"
13 #include "media/base/android/test_statistics.h"
14 #include "media/base/buffers.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 #define RUN_ON_MEDIA_THREAD(CLASS, METHOD, ...) \
30 do { \
31 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \
32 GetMediaTaskRunner()->PostTask( \
33 FROM_HERE, \
34 base::Bind(&CLASS::METHOD, base::Unretained(this), ##__VA_ARGS__)); \
35 return; \
36 } \
37 } while (0)
39 namespace {
41 const base::TimeDelta kDefaultTimeout = base::TimeDelta::FromMilliseconds(200);
42 const base::TimeDelta kAudioFramePeriod =
43 base::TimeDelta::FromSecondsD(1024.0 / 44100); // 1024 samples @ 44100 Hz
44 const base::TimeDelta kVideoFramePeriod = base::TimeDelta::FromMilliseconds(20);
46 // The predicate that always returns false, used for WaitForDelay implementation
47 bool AlwaysFalse() {
48 return false;
51 // The method used to compare two TimeDelta values in expectations.
52 bool AlmostEqual(base::TimeDelta a, base::TimeDelta b, double tolerance_ms) {
53 return (a - b).magnitude().InMilliseconds() <= tolerance_ms;
56 // Mock of MediaPlayerManager for testing purpose.
58 class MockMediaPlayerManager : public MediaPlayerManager {
59 public:
60 MockMediaPlayerManager()
61 : playback_completed_(false),
62 num_seeks_completed_(0),
63 weak_ptr_factory_(this) {}
64 ~MockMediaPlayerManager() override {}
66 MediaResourceGetter* GetMediaResourceGetter() override { return nullptr; }
67 MediaUrlInterceptor* GetMediaUrlInterceptor() override { return nullptr; }
69 void OnTimeUpdate(int player_id,
70 base::TimeDelta current_timestamp,
71 base::TimeTicks current_time_ticks) override {
72 pts_stat_.AddValue(current_timestamp);
75 void OnMediaMetadataChanged(int player_id,
76 base::TimeDelta duration,
77 int width,
78 int height,
79 bool success) override {
80 media_metadata_.duration = duration;
81 media_metadata_.width = width;
82 media_metadata_.height = height;
83 media_metadata_.modified = true;
86 void OnPlaybackComplete(int player_id) override {
87 playback_completed_ = true;
90 void OnMediaInterrupted(int player_id) override {}
91 void OnBufferingUpdate(int player_id, int percentage) override {}
92 void OnSeekComplete(int player_id,
93 const base::TimeDelta& current_time) override {
94 ++num_seeks_completed_;
96 void OnError(int player_id, int error) override {}
97 void OnVideoSizeChanged(int player_id, int width, int height) override {}
98 void OnAudibleStateChanged(int player_id, bool is_audible_now) override {}
99 void OnWaitingForDecryptionKey(int player_id) override {}
100 MediaPlayerAndroid* GetFullscreenPlayer() override { return nullptr; }
101 MediaPlayerAndroid* GetPlayer(int player_id) override { return nullptr; }
102 bool RequestPlay(int player_id) override { return true; }
104 void OnMediaResourcesRequested(int player_id) {}
106 base::WeakPtr<MockMediaPlayerManager> GetWeakPtr() {
107 return weak_ptr_factory_.GetWeakPtr();
110 // Conditions to wait for.
111 bool IsMetadataChanged() const { return media_metadata_.modified; }
112 bool IsPlaybackCompleted() const { return playback_completed_; }
113 bool IsPlaybackStarted() const { return pts_stat_.num_values() > 0; }
114 bool IsPlaybackBeyondPosition(const base::TimeDelta& pts) const {
115 return pts_stat_.max() > pts;
117 bool IsSeekCompleted() const { return num_seeks_completed_ > 0; }
119 struct MediaMetadata {
120 base::TimeDelta duration;
121 int width;
122 int height;
123 bool modified;
124 MediaMetadata() : width(0), height(0), modified(false) {}
126 MediaMetadata media_metadata_;
128 Minimax<base::TimeDelta> pts_stat_;
130 private:
131 bool playback_completed_;
132 int num_seeks_completed_;
134 base::WeakPtrFactory<MockMediaPlayerManager> weak_ptr_factory_;
136 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager);
139 // Helper method that creates demuxer configuration.
141 DemuxerConfigs CreateAudioVideoConfigs(const base::TimeDelta& duration,
142 const gfx::Size& video_size) {
143 DemuxerConfigs configs =
144 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration);
145 configs.video_codec = kCodecVP8;
146 configs.video_size = video_size;
147 configs.is_video_encrypted = false;
148 return configs;
151 DemuxerConfigs CreateAudioVideoConfigs(const TestDataFactory* audio,
152 const TestDataFactory* video) {
153 DemuxerConfigs result = audio->GetConfigs();
154 DemuxerConfigs vconf = video->GetConfigs();
156 result.video_codec = vconf.video_codec;
157 result.video_size = vconf.video_size;
158 result.is_video_encrypted = vconf.is_video_encrypted;
159 return result;
162 // AudioFactory creates data chunks that simulate audio stream from demuxer.
164 class AudioFactory : public TestDataFactory {
165 public:
166 AudioFactory(base::TimeDelta duration)
167 : TestDataFactory("aac-44100-packet-%d", duration, kAudioFramePeriod) {}
169 DemuxerConfigs GetConfigs() const override {
170 return TestDataFactory::CreateAudioConfigs(kCodecAAC, duration_);
173 protected:
174 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override {
175 unit->is_key_frame = true;
179 // VideoFactory creates a video stream from demuxer.
181 class VideoFactory : public TestDataFactory {
182 public:
183 VideoFactory(base::TimeDelta duration)
184 : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod),
185 key_frame_requested_(true) {}
187 DemuxerConfigs GetConfigs() const override {
188 return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_,
189 gfx::Size(320, 180));
192 void RequestKeyFrame() { key_frame_requested_ = true; }
194 protected:
195 void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override {
196 // The frames are taken from High profile and some are B-frames.
197 // The first 4 frames appear in the file in the following order:
199 // Frames: I P B P
200 // Decoding order: 0 1 2 3
201 // Presentation order: 0 2 1 4(3)
203 // I keep the last PTS to be 3 for simplicity.
205 // Swap pts for second and third frames. Make first frame a key frame.
206 switch (index_in_chunk) {
207 case 0: // first frame
208 unit->is_key_frame = key_frame_requested_;
209 key_frame_requested_ = false;
210 break;
211 case 1: // second frame
212 unit->timestamp += frame_period_;
213 break;
214 case 2: // third frame
215 unit->timestamp -= frame_period_;
216 break;
217 case 3: // fourth frame, do not modify
218 break;
219 default:
220 NOTREACHED();
221 break;
225 private:
226 bool key_frame_requested_;
229 // Mock of DemuxerAndroid for testing purpose.
231 class MockDemuxerAndroid : public DemuxerAndroid {
232 public:
233 MockDemuxerAndroid()
234 : client_(nullptr), num_seeks_(0), num_browser_seeks_(0) {}
235 ~MockDemuxerAndroid() override {}
237 // DemuxerAndroid implementation
238 void Initialize(DemuxerAndroidClient* client) override;
239 void RequestDemuxerData(DemuxerStream::Type type) override;
240 void RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
241 bool is_browser_seek) override;
243 // Sets the audio data factory.
244 void SetAudioFactory(scoped_ptr<AudioFactory> factory) {
245 audio_factory_ = factory.Pass();
248 // Sets the video data factory.
249 void SetVideoFactory(scoped_ptr<VideoFactory> factory) {
250 video_factory_ = factory.Pass();
253 // Sets the delay in OnDemuxerSeekDone response.
254 void SetSeekDoneDelay(base::TimeDelta delay) { seek_done_delay_ = delay; }
256 // Post DemuxerConfigs to the client (i.e. the player) on correct thread.
257 void PostConfigs(const DemuxerConfigs& configs);
259 // Post DemuxerConfigs derived from data factories that has been set.
260 void PostInternalConfigs();
262 // Conditions to wait for.
263 bool IsInitialized() const { return client_; }
264 bool HasPendingConfigs() const { return pending_configs_; }
265 bool ReceivedSeekRequest() const { return num_seeks_ > 0; }
266 bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_ > 0; }
268 private:
269 DemuxerAndroidClient* client_;
270 scoped_ptr<DemuxerConfigs> pending_configs_;
271 scoped_ptr<AudioFactory> audio_factory_;
272 scoped_ptr<VideoFactory> video_factory_;
273 base::TimeDelta seek_done_delay_;
274 int num_seeks_;
275 int num_browser_seeks_;
277 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
280 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient* client) {
281 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__;
282 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
284 client_ = client;
285 if (pending_configs_)
286 client_->OnDemuxerConfigsAvailable(*pending_configs_);
289 void MockDemuxerAndroid::RequestDemuxerData(DemuxerStream::Type type) {
290 DemuxerData chunk;
291 base::TimeDelta delay;
293 bool created = false;
294 if (type == DemuxerStream::AUDIO && audio_factory_)
295 created = audio_factory_->CreateChunk(&chunk, &delay);
296 else if (type == DemuxerStream::VIDEO && video_factory_)
297 created = video_factory_->CreateChunk(&chunk, &delay);
299 if (!created)
300 return;
302 chunk.type = type;
304 // Post to Media thread.
305 DCHECK(client_);
306 GetMediaTaskRunner()->PostDelayedTask(
307 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerDataAvailable,
308 base::Unretained(client_), chunk),
309 delay);
312 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
313 bool is_browser_seek) {
314 // Tell data factories to start next chunk with the new timestamp.
315 if (audio_factory_)
316 audio_factory_->SeekTo(time_to_seek);
317 if (video_factory_) {
318 video_factory_->SeekTo(time_to_seek);
319 video_factory_->RequestKeyFrame();
322 ++num_seeks_;
323 if (is_browser_seek)
324 ++num_browser_seeks_;
326 // Post OnDemuxerSeekDone() to the player.
327 DCHECK(client_);
328 base::TimeDelta reported_seek_time =
329 is_browser_seek ? time_to_seek : kNoTimestamp();
330 GetMediaTaskRunner()->PostDelayedTask(
331 FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone,
332 base::Unretained(client_), reported_seek_time),
333 seek_done_delay_);
336 void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs& configs) {
337 RUN_ON_MEDIA_THREAD(MockDemuxerAndroid, PostConfigs, configs);
339 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__;
341 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
343 if (client_)
344 client_->OnDemuxerConfigsAvailable(configs);
345 else
346 pending_configs_ = scoped_ptr<DemuxerConfigs>(new DemuxerConfigs(configs));
349 void MockDemuxerAndroid::PostInternalConfigs() {
350 ASSERT_TRUE(audio_factory_ || video_factory_);
352 if (audio_factory_ && video_factory_) {
353 PostConfigs(
354 CreateAudioVideoConfigs(audio_factory_.get(), video_factory_.get()));
355 } else if (audio_factory_) {
356 PostConfigs(audio_factory_->GetConfigs());
357 } else if (video_factory_) {
358 PostConfigs(video_factory_->GetConfigs());
362 } // namespace (anonymous)
364 // The test fixture for MediaCodecPlayer
366 class MediaCodecPlayerTest : public testing::Test {
367 public:
368 MediaCodecPlayerTest();
369 ~MediaCodecPlayerTest() override;
371 // Conditions to wait for.
372 bool IsPaused() const { return !(player_ && player_->IsPlaying()); }
374 protected:
375 typedef base::Callback<bool()> Predicate;
377 void CreatePlayer();
378 void SetVideoSurface();
379 void SetVideoSurfaceB();
380 void RemoveVideoSurface();
382 // Waits for condition to become true or for timeout to expire.
383 // Returns true if the condition becomes true.
384 bool WaitForCondition(const Predicate& condition,
385 const base::TimeDelta& timeout = kDefaultTimeout);
387 // Waits for timeout to expire.
388 void WaitForDelay(const base::TimeDelta& timeout);
390 // Waits till playback position as determined by maximal reported pts
391 // reaches the given value or for timeout to expire. Returns true if the
392 // playback has passed the given position.
393 bool WaitForPlaybackBeyondPosition(
394 const base::TimeDelta& pts,
395 const base::TimeDelta& timeout = kDefaultTimeout);
397 // Helper method that starts video only stream. Waits till it actually
398 // started.
399 void StartVideoPlayback(base::TimeDelta duration);
401 base::MessageLoop message_loop_;
402 MockMediaPlayerManager manager_;
403 MockDemuxerAndroid* demuxer_; // owned by player_
404 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
405 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
406 MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread()
408 private:
409 bool is_timeout_expired() const { return is_timeout_expired_; }
410 void SetTimeoutExpired(bool value) { is_timeout_expired_ = value; }
412 bool is_timeout_expired_;
414 DISALLOW_COPY_AND_ASSIGN(MediaCodecPlayerTest);
417 MediaCodecPlayerTest::MediaCodecPlayerTest()
418 : demuxer_(new MockDemuxerAndroid()), player_(nullptr) {
421 MediaCodecPlayerTest::~MediaCodecPlayerTest() {
422 if (player_)
423 player_->DeleteOnCorrectThread();
426 void MediaCodecPlayerTest::CreatePlayer() {
427 DCHECK(demuxer_);
428 player_ = new MediaCodecPlayer(
429 0, // player_id
430 manager_.GetWeakPtr(),
431 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested,
432 base::Unretained(&manager_)),
433 scoped_ptr<MockDemuxerAndroid>(demuxer_), GURL());
435 DCHECK(player_);
438 void MediaCodecPlayerTest::SetVideoSurface() {
439 surface_texture_a_ = gfx::SurfaceTexture::Create(0);
440 gfx::ScopedJavaSurface surface(surface_texture_a_.get());
442 ASSERT_NE(nullptr, player_);
443 player_->SetVideoSurface(surface.Pass());
446 void MediaCodecPlayerTest::SetVideoSurfaceB() {
447 surface_texture_b_ = gfx::SurfaceTexture::Create(1);
448 gfx::ScopedJavaSurface surface(surface_texture_b_.get());
450 ASSERT_NE(nullptr, player_);
451 player_->SetVideoSurface(surface.Pass());
454 void MediaCodecPlayerTest::RemoveVideoSurface() {
455 player_->SetVideoSurface(gfx::ScopedJavaSurface());
456 surface_texture_a_ = NULL;
459 bool MediaCodecPlayerTest::WaitForCondition(const Predicate& condition,
460 const base::TimeDelta& timeout) {
461 // Let the message_loop_ process events.
462 // We start the timer and RunUntilIdle() until it signals.
464 SetTimeoutExpired(false);
466 base::Timer timer(false, false);
467 timer.Start(FROM_HERE, timeout,
468 base::Bind(&MediaCodecPlayerTest::SetTimeoutExpired,
469 base::Unretained(this), true));
471 do {
472 if (condition.Run()) {
473 timer.Stop();
474 return true;
476 message_loop_.RunUntilIdle();
477 } while (!is_timeout_expired());
479 DCHECK(!timer.IsRunning());
480 return false;
483 void MediaCodecPlayerTest::WaitForDelay(const base::TimeDelta& timeout) {
484 WaitForCondition(base::Bind(&AlwaysFalse), timeout);
487 bool MediaCodecPlayerTest::WaitForPlaybackBeyondPosition(
488 const base::TimeDelta& pts,
489 const base::TimeDelta& timeout) {
490 return WaitForCondition(
491 base::Bind(&MockMediaPlayerManager::IsPlaybackBeyondPosition,
492 base::Unretained(&manager_), pts),
493 timeout);
496 void MediaCodecPlayerTest::StartVideoPlayback(base::TimeDelta duration) {
497 const base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
499 demuxer_->SetVideoFactory(
500 scoped_ptr<VideoFactory>(new VideoFactory(duration)));
502 CreatePlayer();
503 SetVideoSurface();
505 // Wait till the player is initialized on media thread.
506 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
507 base::Unretained(demuxer_))));
509 // Post configuration after the player has been initialized.
510 demuxer_->PostInternalConfigs();
512 // Start the player.
513 EXPECT_FALSE(manager_.IsPlaybackStarted());
514 player_->Start();
516 // Wait for playback to start.
517 EXPECT_TRUE(
518 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
519 base::Unretained(&manager_)),
520 start_timeout));
523 TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) {
524 // Post configuration when there is no player yet.
525 EXPECT_EQ(nullptr, player_);
527 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
529 demuxer_->PostConfigs(
530 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration));
532 // Wait until the configuration gets to the media thread.
533 EXPECT_TRUE(WaitForCondition(base::Bind(
534 &MockDemuxerAndroid::HasPendingConfigs, base::Unretained(demuxer_))));
536 // Then create the player.
537 CreatePlayer();
539 // Configuration should propagate through the player and to the manager.
540 EXPECT_TRUE(
541 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged,
542 base::Unretained(&manager_))));
544 EXPECT_EQ(duration, manager_.media_metadata_.duration);
545 EXPECT_EQ(0, manager_.media_metadata_.width);
546 EXPECT_EQ(0, manager_.media_metadata_.height);
549 TEST_F(MediaCodecPlayerTest, SetAudioConfigsAfterPlayerCreation) {
550 CreatePlayer();
552 // Wait till the player is initialized on media thread.
553 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
554 base::Unretained(demuxer_))));
556 // Post configuration after the player has been initialized.
557 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
558 demuxer_->PostConfigs(
559 TestDataFactory::CreateAudioConfigs(kCodecAAC, duration));
561 // Configuration should propagate through the player and to the manager.
562 EXPECT_TRUE(
563 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged,
564 base::Unretained(&manager_))));
566 EXPECT_EQ(duration, manager_.media_metadata_.duration);
567 EXPECT_EQ(0, manager_.media_metadata_.width);
568 EXPECT_EQ(0, manager_.media_metadata_.height);
571 TEST_F(MediaCodecPlayerTest, SetAudioVideoConfigsAfterPlayerCreation) {
572 CreatePlayer();
574 // Wait till the player is initialized on media thread.
575 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
576 base::Unretained(demuxer_))));
578 // Post configuration after the player has been initialized.
579 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
580 demuxer_->PostConfigs(CreateAudioVideoConfigs(duration, gfx::Size(320, 240)));
582 // Configuration should propagate through the player and to the manager.
583 EXPECT_TRUE(
584 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged,
585 base::Unretained(&manager_))));
587 EXPECT_EQ(duration, manager_.media_metadata_.duration);
588 EXPECT_EQ(320, manager_.media_metadata_.width);
589 EXPECT_EQ(240, manager_.media_metadata_.height);
592 TEST_F(MediaCodecPlayerTest, AudioPlayTillCompletion) {
593 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
595 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
596 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(2000);
598 demuxer_->SetAudioFactory(
599 scoped_ptr<AudioFactory>(new AudioFactory(duration)));
601 CreatePlayer();
603 // Wait till the player is initialized on media thread.
604 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
605 base::Unretained(demuxer_))));
607 // Post configuration after the player has been initialized.
608 demuxer_->PostInternalConfigs();
610 EXPECT_FALSE(manager_.IsPlaybackCompleted());
612 player_->Start();
614 EXPECT_TRUE(
615 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
616 base::Unretained(&manager_)),
617 timeout));
619 // Current timestamp reflects "now playing" time. It might come with delay
620 // relative to the frame's PTS. Allow for 100 ms delay here.
621 base::TimeDelta audio_pts_delay = base::TimeDelta::FromMilliseconds(100);
622 EXPECT_LT(duration - audio_pts_delay, manager_.pts_stat_.max());
625 TEST_F(MediaCodecPlayerTest, VideoPlayTillCompletion) {
626 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
628 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
629 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
631 StartVideoPlayback(duration);
633 // Wait till completion.
634 EXPECT_TRUE(
635 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
636 base::Unretained(&manager_)),
637 timeout));
639 EXPECT_LE(duration, manager_.pts_stat_.max());
642 // http://crbug.com/518900
643 TEST_F(MediaCodecPlayerTest, DISABLED_AudioSeekAfterStop) {
644 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
646 // Play for 300 ms, then Pause, then Seek to beginning. The playback should
647 // start from the beginning.
649 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
651 demuxer_->SetAudioFactory(
652 scoped_ptr<AudioFactory>(new AudioFactory(duration)));
654 CreatePlayer();
656 // Post configuration.
657 demuxer_->PostInternalConfigs();
659 // Start the player.
660 player_->Start();
662 // Wait for playback to start.
663 EXPECT_TRUE(
664 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
665 base::Unretained(&manager_))));
667 // Wait for 300 ms and stop. The 300 ms interval takes into account potential
668 // audio delay: audio takes time reconfiguring after the first several packets
669 // get written to the audio track.
670 WaitForDelay(base::TimeDelta::FromMilliseconds(300));
672 player_->Pause(true);
674 // Make sure we played at least 100 ms.
675 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
677 // Wait till the Pause is completed.
678 EXPECT_TRUE(WaitForCondition(
679 base::Bind(&MediaCodecPlayerTest::IsPaused, base::Unretained(this))));
681 // Clear statistics.
682 manager_.pts_stat_.Clear();
684 // Now we can seek to the beginning and start the playback.
685 player_->SeekTo(base::TimeDelta());
687 player_->Start();
689 // Wait for playback to start.
690 EXPECT_TRUE(
691 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
692 base::Unretained(&manager_))));
694 // Make sure we started from the beginninig
695 EXPECT_GT(base::TimeDelta::FromMilliseconds(40), manager_.pts_stat_.min());
697 // The player should have reported the seek completion to the manager.
698 EXPECT_TRUE(WaitForCondition(base::Bind(
699 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
702 TEST_F(MediaCodecPlayerTest, AudioSeekThenPlay) {
703 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
705 // Issue Seek command immediately followed by Start. The playback should
706 // start at the seek position.
708 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
709 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(500);
711 demuxer_->SetAudioFactory(
712 scoped_ptr<AudioFactory>(new AudioFactory(duration)));
714 CreatePlayer();
716 // Post configuration.
717 demuxer_->PostInternalConfigs();
719 // Seek and immediately start.
720 player_->SeekTo(seek_position);
721 player_->Start();
723 // Wait for playback to start.
724 EXPECT_TRUE(
725 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
726 base::Unretained(&manager_))));
728 // The playback should start at |seek_position|
729 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
731 // The player should have reported the seek completion to the manager.
732 EXPECT_TRUE(WaitForCondition(base::Bind(
733 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
736 TEST_F(MediaCodecPlayerTest, AudioSeekThenPlayThenConfig) {
737 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
739 // Issue Seek command immediately followed by Start but without prior demuxer
740 // configuration. Start should wait for configuration. After it has been
741 // posted the playback should start at the seek position.
743 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
744 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(500);
746 demuxer_->SetAudioFactory(
747 scoped_ptr<AudioFactory>(new AudioFactory(duration)));
749 CreatePlayer();
751 // Seek and immediately start.
752 player_->SeekTo(seek_position);
753 player_->Start();
755 // Make sure the player is waiting.
756 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
757 EXPECT_FALSE(player_->IsPlaying());
759 // Post configuration.
760 demuxer_->PostInternalConfigs();
762 // Wait for playback to start.
763 EXPECT_TRUE(
764 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
765 base::Unretained(&manager_))));
767 // The playback should start at |seek_position|
768 EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
770 // The player should have reported the seek completion to the manager.
771 EXPECT_TRUE(WaitForCondition(base::Bind(
772 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
775 // http://crbug.com/518900
776 TEST_F(MediaCodecPlayerTest, DISABLED_AudioSeekWhilePlaying) {
777 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
779 // Play for 300 ms, then issue several Seek commands in the row.
780 // The playback should continue at the last seek position.
782 // To test this condition without analyzing the reported time details
783 // and without introducing dependency on implementation I make a long (10s)
784 // duration and test that the playback resumes after big time jump (5s) in a
785 // short period of time (200 ms).
786 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
788 demuxer_->SetAudioFactory(
789 scoped_ptr<AudioFactory>(new AudioFactory(duration)));
791 CreatePlayer();
793 // Post configuration.
794 demuxer_->PostInternalConfigs();
796 // Start the player.
797 player_->Start();
799 // Wait for playback to start.
800 EXPECT_TRUE(
801 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
802 base::Unretained(&manager_))));
804 // Wait for 300 ms.
805 WaitForDelay(base::TimeDelta::FromMilliseconds(300));
807 // Make sure we played at least 100 ms.
808 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
810 // Seek forward several times.
811 player_->SeekTo(base::TimeDelta::FromSeconds(3));
812 player_->SeekTo(base::TimeDelta::FromSeconds(4));
813 player_->SeekTo(base::TimeDelta::FromSeconds(5));
815 // Make sure that we reached the last timestamp within default timeout,
816 // i.e. 200 ms.
817 EXPECT_TRUE(WaitForPlaybackBeyondPosition(base::TimeDelta::FromSeconds(5)));
818 EXPECT_TRUE(player_->IsPlaying());
820 // The player should have reported the seek completion to the manager.
821 EXPECT_TRUE(WaitForCondition(base::Bind(
822 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
825 TEST_F(MediaCodecPlayerTest, VideoReplaceSurface) {
826 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
828 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
829 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
831 StartVideoPlayback(duration);
833 // Wait for some time and check statistics.
834 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
836 // Make sure we played at least 100 ms.
837 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
839 // Set new video surface without removing the old one.
840 SetVideoSurfaceB();
842 // We should receive a browser seek request.
843 EXPECT_TRUE(WaitForCondition(
844 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
845 base::Unretained(demuxer_))));
847 // Playback should continue with a new surface. Wait till completion.
848 EXPECT_TRUE(
849 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
850 base::Unretained(&manager_)),
851 timeout));
852 EXPECT_LE(duration, manager_.pts_stat_.max());
855 TEST_F(MediaCodecPlayerTest, VideoRemoveAndSetSurface) {
856 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
858 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
860 StartVideoPlayback(duration);
862 // Wait for some time and check statistics.
863 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
865 // Make sure we played at least 100 ms.
866 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
868 // Remove video surface.
869 RemoveVideoSurface();
871 // We should be stuck waiting for the new surface.
872 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
873 EXPECT_FALSE(player_->IsPlaying());
875 // Save last PTS and clear statistics.
876 base::TimeDelta max_pts_before_removal = manager_.pts_stat_.max();
877 manager_.pts_stat_.Clear();
879 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
880 EXPECT_FALSE(manager_.IsPlaybackStarted());
882 // Extra RemoveVideoSurface() should not change anything.
883 RemoveVideoSurface();
885 // Set another video surface.
886 SetVideoSurfaceB();
888 // We should receive a browser seek request.
889 EXPECT_TRUE(WaitForCondition(
890 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
891 base::Unretained(demuxer_))));
893 // Playback should continue with a new surface. Wait till it starts again.
894 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
895 EXPECT_TRUE(
896 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
897 base::Unretained(&manager_)),
898 reconfigure_timeout));
900 // Timestamps should not go back.
901 EXPECT_LE(max_pts_before_removal, manager_.pts_stat_.max());
904 // http://crbug.com/518900
905 TEST_F(MediaCodecPlayerTest, DISABLED_VideoReleaseAndStart) {
906 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
908 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
910 StartVideoPlayback(duration);
912 // Wait for some time and check statistics.
913 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
915 // Make sure we played at least 100 ms.
916 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
918 // When the user presses Tasks button Chrome calls Pause() and Release().
919 player_->Pause(true);
920 player_->Release();
922 // Make sure we are not playing any more.
923 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
924 EXPECT_FALSE(player_->IsPlaying());
926 // Save last PTS and clear statistics.
927 base::TimeDelta max_pts_before_backgrounding = manager_.pts_stat_.max();
928 manager_.pts_stat_.Clear();
930 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
931 EXPECT_FALSE(manager_.IsPlaybackStarted());
933 // Restart.
934 SetVideoSurface();
935 player_->Start();
937 // We should receive a browser seek request.
938 EXPECT_TRUE(WaitForCondition(
939 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
940 base::Unretained(demuxer_))));
942 // Wait for playback to start again.
943 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
944 EXPECT_TRUE(
945 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
946 base::Unretained(&manager_)),
947 reconfigure_timeout));
949 // Timestamps should not go back.
950 EXPECT_LE(max_pts_before_backgrounding, manager_.pts_stat_.max());
953 TEST_F(MediaCodecPlayerTest, VideoSeekAndRelease) {
954 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
956 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
957 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
959 StartVideoPlayback(duration);
961 // Wait for some time and check statistics.
962 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
964 // Make sure we played at least 100 ms.
965 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
967 // Issue SeekTo() immediately followed by Release().
968 player_->SeekTo(seek_position);
969 player_->Release();
971 // Make sure we are not playing any more.
972 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
973 EXPECT_FALSE(player_->IsPlaying());
975 // The Release() should not cancel the SeekTo() and we should have received
976 // the seek request by this time.
977 EXPECT_TRUE(demuxer_->ReceivedSeekRequest());
979 // The player should have reported the seek completion to the manager.
980 EXPECT_TRUE(WaitForCondition(base::Bind(
981 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
983 // Clear statistics.
984 manager_.pts_stat_.Clear();
986 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
987 EXPECT_FALSE(manager_.IsPlaybackStarted());
989 // Restart.
990 SetVideoSurface();
991 player_->Start();
993 // Wait for playback to start again.
994 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
995 EXPECT_TRUE(
996 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
997 base::Unretained(&manager_)),
998 reconfigure_timeout));
1000 // Timestamps should start at the new seek position
1001 EXPECT_LE(seek_position, manager_.pts_stat_.min());
1004 TEST_F(MediaCodecPlayerTest, VideoReleaseWhileWaitingForSeek) {
1005 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1007 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
1008 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
1010 StartVideoPlayback(duration);
1012 // Wait for some time and check statistics.
1013 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1015 // Make sure we played at least 100 ms.
1016 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
1018 // Set artificial delay in the OnDemuxerSeekDone response so we can
1019 // issue commands while the player is in the STATE_WAITING_FOR_SEEK.
1020 demuxer_->SetSeekDoneDelay(base::TimeDelta::FromMilliseconds(100));
1022 // Issue SeekTo().
1023 player_->SeekTo(seek_position);
1025 // Wait for the seek request to demuxer.
1026 EXPECT_TRUE(WaitForCondition(base::Bind(
1027 &MockDemuxerAndroid::ReceivedSeekRequest, base::Unretained(demuxer_))));
1029 // The player is supposed to be in STATE_WAITING_FOR_SEEK. Issue Release().
1030 player_->Release();
1032 // Make sure we are not playing any more.
1033 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1034 EXPECT_FALSE(player_->IsPlaying());
1036 // Clear statistics.
1037 manager_.pts_stat_.Clear();
1039 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1040 EXPECT_FALSE(manager_.IsPlaybackStarted());
1042 // Restart.
1043 SetVideoSurface();
1044 player_->Start();
1046 // Wait for playback to start again.
1047 base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(1000);
1048 EXPECT_TRUE(
1049 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
1050 base::Unretained(&manager_)),
1051 reconfigure_timeout));
1053 // Timestamps should start at the new seek position
1054 EXPECT_LE(seek_position, manager_.pts_stat_.min());
1056 // The player should have reported the seek completion to the manager.
1057 EXPECT_TRUE(WaitForCondition(base::Bind(
1058 &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
1061 } // namespace media