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.
8 #include "base/logging.h"
9 #include "base/timer/timer.h"
10 #include "media/base/android/demuxer_android.h"
11 #include "media/base/android/media_codec_bridge.h"
12 #include "media/base/android/media_codec_player.h"
13 #include "media/base/android/media_player_manager.h"
14 #include "media/base/android/test_data_factory.h"
15 #include "media/base/android/test_statistics.h"
16 #include "media/base/timestamp_constants.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/gl/android/surface_texture.h"
22 // Helper macro to skip the test if MediaCodecBridge isn't available.
23 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
25 if (!MediaCodecBridge::IsAvailable()) { \
26 VLOG(0) << "Could not run test - not supported on device."; \
31 #define RUN_ON_MEDIA_THREAD(CLASS, METHOD, ...) \
33 if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \
34 GetMediaTaskRunner()->PostTask( \
36 base::Bind(&CLASS::METHOD, base::Unretained(this), ##__VA_ARGS__)); \
43 const base::TimeDelta kDefaultTimeout
= base::TimeDelta::FromMilliseconds(200);
44 const base::TimeDelta kAudioFramePeriod
=
45 base::TimeDelta::FromSecondsD(1024.0 / 44100); // 1024 samples @ 44100 Hz
46 const base::TimeDelta kVideoFramePeriod
= base::TimeDelta::FromMilliseconds(20);
49 kAlwaysReconfigAudio
= 0x1,
50 kAlwaysReconfigVideo
= 0x2,
53 // The predicate that always returns false, used for WaitForDelay implementation
58 // The method used to compare two time values of type T in expectations.
59 // Type T requires that a difference of type base::TimeDelta is defined.
61 bool AlmostEqual(T a
, T b
, double tolerance_ms
) {
62 return (a
- b
).magnitude().InMilliseconds() <= tolerance_ms
;
65 // A helper function to calculate the expected number of frames.
66 int GetFrameCount(base::TimeDelta duration
,
67 base::TimeDelta frame_period
,
69 // A chunk has 4 access units. The last unit timestamp must exceed the
70 // duration. Last chunk has 3 regular access units and one stand-alone EOS
71 // unit that we do not count.
73 // Number of time intervals to exceed duration.
74 int num_intervals
= duration
/ frame_period
+ 1.0;
76 // To cover these intervals we need one extra unit at the beginning and a one
77 // for each reconfiguration.
78 int num_units
= num_intervals
+ 1 + num_reconfigs
;
80 // Number of 4-unit chunks that hold these units:
81 int num_chunks
= (num_units
+ 3) / 4;
83 // Altogether these chunks hold 4*num_chunks units, but we do not count
84 // reconfiguration units and last EOS as frames.
85 return 4 * num_chunks
- 1 - num_reconfigs
;
88 // Mock of MediaPlayerManager for testing purpose.
90 class MockMediaPlayerManager
: public MediaPlayerManager
{
92 MockMediaPlayerManager()
93 : playback_allowed_(true),
94 playback_completed_(false),
95 num_seeks_completed_(0),
96 num_audio_codecs_created_(0),
97 num_video_codecs_created_(0),
98 weak_ptr_factory_(this) {}
99 ~MockMediaPlayerManager() override
{}
101 MediaResourceGetter
* GetMediaResourceGetter() override
{ return nullptr; }
102 MediaUrlInterceptor
* GetMediaUrlInterceptor() override
{ return nullptr; }
104 // Regular time update callback, reports current playback time to
105 // MediaPlayerManager.
106 void OnTimeUpdate(int player_id
,
107 base::TimeDelta current_timestamp
,
108 base::TimeTicks current_time_ticks
) override
{
109 pts_stat_
.AddValue(current_timestamp
);
112 void OnMediaMetadataChanged(int player_id
,
113 base::TimeDelta duration
,
116 bool success
) override
{
117 media_metadata_
.duration
= duration
;
118 media_metadata_
.width
= width
;
119 media_metadata_
.height
= height
;
120 media_metadata_
.modified
= true;
123 void OnPlaybackComplete(int player_id
) override
{
124 playback_completed_
= true;
127 void OnMediaInterrupted(int player_id
) override
{}
128 void OnBufferingUpdate(int player_id
, int percentage
) override
{}
129 void OnSeekComplete(int player_id
,
130 const base::TimeDelta
& current_time
) override
{
131 ++num_seeks_completed_
;
133 void OnError(int player_id
, int error
) override
{}
134 void OnVideoSizeChanged(int player_id
, int width
, int height
) override
{}
135 void OnWaitingForDecryptionKey(int player_id
) override
{}
136 MediaPlayerAndroid
* GetFullscreenPlayer() override
{ return nullptr; }
137 MediaPlayerAndroid
* GetPlayer(int player_id
) override
{ return nullptr; }
138 bool RequestPlay(int player_id
, base::TimeDelta duration
) override
{
139 return playback_allowed_
;
142 void OnMediaResourcesRequested(int player_id
) {}
144 // Time update callback that reports the internal progress of the stream.
145 // Implementation dependent, used for testing only.
146 void OnDecodersTimeUpdate(DemuxerStream::Type stream_type
,
147 base::TimeDelta now_playing
,
148 base::TimeDelta last_buffered
) {
149 render_stat_
[stream_type
].AddValue(
150 PTSTime(now_playing
, base::TimeTicks::Now()));
153 // Notification called on MediaCodec creation.
154 // Implementation dependent, used for testing only.
155 void OnMediaCodecCreated(DemuxerStream::Type stream_type
) {
156 if (stream_type
== DemuxerStream::AUDIO
)
157 ++num_audio_codecs_created_
;
158 else if (stream_type
== DemuxerStream::VIDEO
)
159 ++num_video_codecs_created_
;
162 // First frame information
163 base::TimeDelta
FirstFramePTS(DemuxerStream::Type stream_type
) const {
164 return render_stat_
[stream_type
].min().pts
;
166 base::TimeTicks
FirstFrameTime(DemuxerStream::Type stream_type
) const {
167 return render_stat_
[stream_type
].min().time
;
170 base::WeakPtr
<MockMediaPlayerManager
> GetWeakPtr() {
171 return weak_ptr_factory_
.GetWeakPtr();
174 void SetPlaybackAllowed(bool value
) { playback_allowed_
= value
; }
176 // Conditions to wait for.
177 bool IsMetadataChanged() const { return media_metadata_
.modified
; }
178 bool IsPlaybackCompleted() const { return playback_completed_
; }
179 bool IsPlaybackStarted() const { return pts_stat_
.num_values() > 0; }
180 bool IsPlaybackBeyondPosition(const base::TimeDelta
& pts
) const {
181 return pts_stat_
.max() > pts
;
183 bool IsSeekCompleted() const { return num_seeks_completed_
> 0; }
184 bool HasFirstFrame(DemuxerStream::Type stream_type
) const {
185 return render_stat_
[stream_type
].num_values() != 0;
188 int num_audio_codecs_created() const { return num_audio_codecs_created_
; }
189 int num_video_codecs_created() const { return num_video_codecs_created_
; }
191 struct MediaMetadata
{
192 base::TimeDelta duration
;
196 MediaMetadata() : width(0), height(0), modified(false) {}
198 MediaMetadata media_metadata_
;
202 base::TimeTicks time
;
204 PTSTime() : pts(), time() {}
205 PTSTime(base::TimeDelta p
, base::TimeTicks t
) : pts(p
), time(t
) {}
206 bool is_null() const { return time
.is_null(); }
207 bool operator<(const PTSTime
& rhs
) const { return time
< rhs
.time
; }
209 Minimax
<PTSTime
> render_stat_
[DemuxerStream::NUM_TYPES
];
211 Minimax
<base::TimeDelta
> pts_stat_
;
214 bool playback_allowed_
;
215 bool playback_completed_
;
216 int num_seeks_completed_
;
217 int num_audio_codecs_created_
;
218 int num_video_codecs_created_
;
220 base::WeakPtrFactory
<MockMediaPlayerManager
> weak_ptr_factory_
;
222 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager
);
225 // Helper method that creates demuxer configuration.
227 DemuxerConfigs
CreateAudioVideoConfigs(const base::TimeDelta
& duration
,
228 const gfx::Size
& video_size
) {
229 DemuxerConfigs configs
=
230 TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration
);
231 configs
.video_codec
= kCodecVP8
;
232 configs
.video_size
= video_size
;
233 configs
.is_video_encrypted
= false;
237 DemuxerConfigs
CreateAudioVideoConfigs(const TestDataFactory
* audio
,
238 const TestDataFactory
* video
) {
239 DemuxerConfigs result
= audio
->GetConfigs();
240 DemuxerConfigs vconf
= video
->GetConfigs();
242 result
.video_codec
= vconf
.video_codec
;
243 result
.video_size
= vconf
.video_size
;
244 result
.is_video_encrypted
= vconf
.is_video_encrypted
;
245 result
.duration
= std::max(result
.duration
, vconf
.duration
);
249 // AudioFactory creates data chunks that simulate audio stream from demuxer.
251 class AudioFactory
: public TestDataFactory
{
253 AudioFactory(base::TimeDelta duration
)
254 : TestDataFactory("aac-44100-packet-%d", duration
, kAudioFramePeriod
) {}
256 DemuxerConfigs
GetConfigs() const override
{
257 return TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration_
);
261 void ModifyChunk(DemuxerData
* chunk
) override
{
263 for (AccessUnit
& unit
: chunk
->access_units
) {
264 if (!unit
.data
.empty())
265 unit
.is_key_frame
= true;
270 // VideoFactory creates a video stream from demuxer.
272 class VideoFactory
: public TestDataFactory
{
274 VideoFactory(base::TimeDelta duration
)
275 : TestDataFactory("h264-320x180-frame-%d", duration
, kVideoFramePeriod
),
276 key_frame_requested_(true) {}
278 DemuxerConfigs
GetConfigs() const override
{
279 return TestDataFactory::CreateVideoConfigs(kCodecH264
, duration_
,
280 gfx::Size(320, 180));
283 void RequestKeyFrame() { key_frame_requested_
= true; }
286 void ModifyChunk(DemuxerData
* chunk
) override
{
287 // The frames are taken from High profile and some are B-frames.
288 // The first 4 frames appear in the file in the following order:
291 // Decoding order: 0 1 2 3
292 // Presentation order: 0 2 1 4(3)
294 // I keep the last PTS to be 3 for simplicity.
296 // If the chunk contains EOS, it should not break the presentation order.
297 // For instance, the following chunk is ok:
300 // Decoding order: 0 1 2 -
301 // Presentation order: 0 2 1 -
303 // while this might cause decoder to block:
306 // Decoding order: 0 1 -
307 // Presentation order: 0 2 - <------- might wait for the B frame forever
309 // With current base class implementation that always has EOS at the 4th
310 // place we are covered (http://crbug.com/526755)
313 DCHECK(chunk
->access_units
.size() == 4);
315 // Swap pts for second and third frames.
316 base::TimeDelta tmp
= chunk
->access_units
[1].timestamp
;
317 chunk
->access_units
[1].timestamp
= chunk
->access_units
[2].timestamp
;
318 chunk
->access_units
[2].timestamp
= tmp
;
320 // Make first frame a key frame.
321 if (key_frame_requested_
) {
322 chunk
->access_units
[0].is_key_frame
= true;
323 key_frame_requested_
= false;
328 bool key_frame_requested_
;
331 // Mock of DemuxerAndroid for testing purpose.
333 class MockDemuxerAndroid
: public DemuxerAndroid
{
335 MockDemuxerAndroid(base::MessageLoop
* ui_message_loop
);
336 ~MockDemuxerAndroid() override
;
338 // DemuxerAndroid implementation
339 void Initialize(DemuxerAndroidClient
* client
) override
;
340 void RequestDemuxerData(DemuxerStream::Type type
) override
;
341 void RequestDemuxerSeek(const base::TimeDelta
& seek_request
,
342 bool is_browser_seek
) override
;
344 // Helper methods that enable using a weak pointer when posting to the player.
345 void OnDemuxerDataAvailable(const DemuxerData
& chunk
);
346 void OnDemuxerSeekDone(base::TimeDelta reported_seek_time
);
348 // Sets the callback that is fired when demuxer is deleted (deletion
349 // happens on the Media thread).
350 void SetDemuxerDeletedCallback(base::Closure cb
) { demuxer_deleted_cb_
= cb
; }
352 // Sets the audio data factory.
353 void SetAudioFactory(scoped_ptr
<AudioFactory
> factory
) {
354 audio_factory_
= factory
.Pass();
357 // Sets the video data factory.
358 void SetVideoFactory(scoped_ptr
<VideoFactory
> factory
) {
359 video_factory_
= factory
.Pass();
362 // Accessors for data factories.
363 AudioFactory
* audio_factory() const { return audio_factory_
.get(); }
364 VideoFactory
* video_factory() const { return video_factory_
.get(); }
366 // Set the preroll interval after seek for audio stream.
367 void SetAudioPrerollInterval(base::TimeDelta value
) {
368 audio_preroll_interval_
= value
;
371 // Set the preroll interval after seek for video stream.
372 void SetVideoPrerollInterval(base::TimeDelta value
) {
373 video_preroll_interval_
= value
;
376 // Sets the delay in OnDemuxerSeekDone response.
377 void SetSeekDoneDelay(base::TimeDelta delay
) { seek_done_delay_
= delay
; }
379 // Post DemuxerConfigs to the client (i.e. the player) on correct thread.
380 void PostConfigs(const DemuxerConfigs
& configs
);
382 // Post DemuxerConfigs derived from data factories that has been set.
383 void PostInternalConfigs();
385 // Conditions to wait for.
386 bool IsInitialized() const { return client_
; }
387 bool HasPendingConfigs() const { return pending_configs_
; }
388 bool ReceivedSeekRequest() const { return num_seeks_
> 0; }
389 bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_
> 0; }
392 base::MessageLoop
* ui_message_loop_
;
393 DemuxerAndroidClient
* client_
;
395 scoped_ptr
<DemuxerConfigs
> pending_configs_
;
396 scoped_ptr
<AudioFactory
> audio_factory_
;
397 scoped_ptr
<VideoFactory
> video_factory_
;
399 base::TimeDelta audio_preroll_interval_
;
400 base::TimeDelta video_preroll_interval_
;
401 base::TimeDelta seek_done_delay_
;
404 int num_browser_seeks_
;
406 base::Closure demuxer_deleted_cb_
;
408 // NOTE: WeakPtrFactory must be the last data member to be destroyed first.
409 base::WeakPtrFactory
<MockDemuxerAndroid
> weak_factory_
;
411 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid
);
414 MockDemuxerAndroid::MockDemuxerAndroid(base::MessageLoop
* ui_message_loop
)
415 : ui_message_loop_(ui_message_loop
),
418 num_browser_seeks_(0),
419 weak_factory_(this) {}
421 MockDemuxerAndroid::~MockDemuxerAndroid() {
422 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__
;
423 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
425 if (!demuxer_deleted_cb_
.is_null())
426 ui_message_loop_
->PostTask(FROM_HERE
, demuxer_deleted_cb_
);
429 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient
* client
) {
430 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__
;
431 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
434 if (pending_configs_
)
435 client_
->OnDemuxerConfigsAvailable(*pending_configs_
);
438 void MockDemuxerAndroid::RequestDemuxerData(DemuxerStream::Type type
) {
439 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
442 base::TimeDelta delay
;
444 bool created
= false;
445 if (type
== DemuxerStream::AUDIO
&& audio_factory_
)
446 created
= audio_factory_
->CreateChunk(&chunk
, &delay
);
447 else if (type
== DemuxerStream::VIDEO
&& video_factory_
)
448 created
= video_factory_
->CreateChunk(&chunk
, &delay
);
453 // Request key frame after |kConfigChanged|
454 if (type
== DemuxerStream::VIDEO
&& !chunk
.demuxer_configs
.empty())
455 video_factory_
->RequestKeyFrame();
459 // Post to the Media thread. Use the weak pointer to prevent the data arrival
460 // after the player has been deleted.
461 GetMediaTaskRunner()->PostDelayedTask(
462 FROM_HERE
, base::Bind(&MockDemuxerAndroid::OnDemuxerDataAvailable
,
463 weak_factory_
.GetWeakPtr(), chunk
),
467 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta
& seek_request
,
468 bool is_browser_seek
) {
469 // Tell data factories to start next chunk with the new timestamp.
470 if (audio_factory_
) {
471 base::TimeDelta time_to_seek
=
472 std::max(base::TimeDelta(), seek_request
- audio_preroll_interval_
);
473 audio_factory_
->SeekTo(time_to_seek
);
475 if (video_factory_
) {
476 base::TimeDelta time_to_seek
=
477 std::max(base::TimeDelta(), seek_request
- video_preroll_interval_
);
478 video_factory_
->SeekTo(time_to_seek
);
479 video_factory_
->RequestKeyFrame();
484 ++num_browser_seeks_
;
486 // Post OnDemuxerSeekDone() to the player.
488 base::TimeDelta reported_seek_time
=
489 is_browser_seek
? seek_request
: kNoTimestamp();
490 GetMediaTaskRunner()->PostDelayedTask(
491 FROM_HERE
, base::Bind(&MockDemuxerAndroid::OnDemuxerSeekDone
,
492 weak_factory_
.GetWeakPtr(), reported_seek_time
),
496 void MockDemuxerAndroid::OnDemuxerDataAvailable(const DemuxerData
& chunk
) {
497 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
499 client_
->OnDemuxerDataAvailable(chunk
);
502 void MockDemuxerAndroid::OnDemuxerSeekDone(base::TimeDelta reported_seek_time
) {
503 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
505 client_
->OnDemuxerSeekDone(reported_seek_time
);
508 void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs
& configs
) {
509 RUN_ON_MEDIA_THREAD(MockDemuxerAndroid
, PostConfigs
, configs
);
511 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__
;
513 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
516 client_
->OnDemuxerConfigsAvailable(configs
);
518 pending_configs_
= scoped_ptr
<DemuxerConfigs
>(new DemuxerConfigs(configs
));
521 void MockDemuxerAndroid::PostInternalConfigs() {
522 ASSERT_TRUE(audio_factory_
|| video_factory_
);
524 if (audio_factory_
&& video_factory_
) {
526 CreateAudioVideoConfigs(audio_factory_
.get(), video_factory_
.get()));
527 } else if (audio_factory_
) {
528 PostConfigs(audio_factory_
->GetConfigs());
529 } else if (video_factory_
) {
530 PostConfigs(video_factory_
->GetConfigs());
534 } // namespace (anonymous)
536 // The test fixture for MediaCodecPlayer
538 class MediaCodecPlayerTest
: public testing::Test
{
540 MediaCodecPlayerTest();
542 // Conditions to wait for.
543 bool IsPaused() const { return !(player_
&& player_
->IsPlaying()); }
546 typedef base::Callback
<bool()> Predicate
;
548 void TearDown() override
;
551 void SetVideoSurface();
552 void SetVideoSurfaceB();
553 void RemoveVideoSurface();
555 // Waits for condition to become true or for timeout to expire.
556 // Returns true if the condition becomes true.
557 bool WaitForCondition(const Predicate
& condition
,
558 const base::TimeDelta
& timeout
= kDefaultTimeout
);
560 // Waits for timeout to expire.
561 void WaitForDelay(const base::TimeDelta
& timeout
);
563 // Waits till playback position as determined by maximal reported pts
564 // reaches the given value or for timeout to expire. Returns true if the
565 // playback has passed the given position.
566 bool WaitForPlaybackBeyondPosition(
567 const base::TimeDelta
& pts
,
568 const base::TimeDelta
& timeout
= kDefaultTimeout
);
570 // Helper method that starts video only stream. Waits till it actually
572 bool StartVideoPlayback(base::TimeDelta duration
, const char* test_name
);
574 // Helper method that starts audio and video streams.
575 bool StartAVPlayback(scoped_ptr
<AudioFactory
> audio_factory
,
576 scoped_ptr
<VideoFactory
> video_factory
,
578 const char* test_name
);
580 // Helper method that starts audio and video streams with preroll.
581 // The preroll is achieved by setting significant video preroll interval
582 // so video will have to catch up with audio. To make room for this interval
583 // the Start() command is preceded by SeekTo().
584 bool StartAVSeekAndPreroll(scoped_ptr
<AudioFactory
> audio_factory
,
585 scoped_ptr
<VideoFactory
> video_factory
,
586 base::TimeDelta seek_position
,
588 const char* test_name
);
590 // Callback sent when demuxer is being deleted.
591 void OnDemuxerDeleted() { demuxer_
= nullptr; }
593 bool IsDemuxerDeleted() const { return !demuxer_
; }
595 base::MessageLoop message_loop_
;
596 MockMediaPlayerManager manager_
;
597 MockDemuxerAndroid
* demuxer_
; // owned by player_
598 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_a_
;
599 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_b_
;
600 MediaCodecPlayer
* player_
; // raw pointer due to DeleteOnCorrectThread()
603 bool is_timeout_expired() const { return is_timeout_expired_
; }
604 void SetTimeoutExpired(bool value
) { is_timeout_expired_
= value
; }
606 bool is_timeout_expired_
;
608 DISALLOW_COPY_AND_ASSIGN(MediaCodecPlayerTest
);
611 MediaCodecPlayerTest::MediaCodecPlayerTest()
612 : demuxer_(new MockDemuxerAndroid(&message_loop_
)),
614 is_timeout_expired_(false) {}
616 void MediaCodecPlayerTest::TearDown() {
617 DVLOG(1) << __FUNCTION__
;
619 // Wait till the player is destroyed on the Media thread.
622 // The player deletes the demuxer on the Media thread. The demuxer's
623 // destructor sends a notification to the UI thread. When this notification
624 // arrives we can conclude that player started destroying its member
625 // variables. By that time the media codecs should have been released.
628 demuxer_
->SetDemuxerDeletedCallback(base::Bind(
629 &MediaCodecPlayerTest::OnDemuxerDeleted
, base::Unretained(this)));
631 player_
->DeleteOnCorrectThread();
634 WaitForCondition(base::Bind(&MediaCodecPlayerTest::IsDemuxerDeleted
,
635 base::Unretained(this)),
636 base::TimeDelta::FromMilliseconds(500)));
642 void MediaCodecPlayerTest::CreatePlayer() {
644 player_
= new MediaCodecPlayer(
646 manager_
.GetWeakPtr(),
647 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested
,
648 base::Unretained(&manager_
)),
649 scoped_ptr
<MockDemuxerAndroid
>(demuxer_
), GURL());
654 void MediaCodecPlayerTest::SetVideoSurface() {
655 surface_texture_a_
= gfx::SurfaceTexture::Create(0);
656 gfx::ScopedJavaSurface
surface(surface_texture_a_
.get());
658 ASSERT_NE(nullptr, player_
);
659 player_
->SetVideoSurface(surface
.Pass());
662 void MediaCodecPlayerTest::SetVideoSurfaceB() {
663 surface_texture_b_
= gfx::SurfaceTexture::Create(1);
664 gfx::ScopedJavaSurface
surface(surface_texture_b_
.get());
666 ASSERT_NE(nullptr, player_
);
667 player_
->SetVideoSurface(surface
.Pass());
670 void MediaCodecPlayerTest::RemoveVideoSurface() {
671 player_
->SetVideoSurface(gfx::ScopedJavaSurface());
672 surface_texture_a_
= NULL
;
675 bool MediaCodecPlayerTest::WaitForCondition(const Predicate
& condition
,
676 const base::TimeDelta
& timeout
) {
677 // Let the message_loop_ process events.
678 // We start the timer and RunUntilIdle() until it signals.
680 SetTimeoutExpired(false);
682 base::Timer
timer(false, false);
683 timer
.Start(FROM_HERE
, timeout
,
684 base::Bind(&MediaCodecPlayerTest::SetTimeoutExpired
,
685 base::Unretained(this), true));
688 if (condition
.Run()) {
692 message_loop_
.RunUntilIdle();
693 } while (!is_timeout_expired());
695 DCHECK(!timer
.IsRunning());
699 void MediaCodecPlayerTest::WaitForDelay(const base::TimeDelta
& timeout
) {
700 WaitForCondition(base::Bind(&AlwaysFalse
), timeout
);
703 bool MediaCodecPlayerTest::WaitForPlaybackBeyondPosition(
704 const base::TimeDelta
& pts
,
705 const base::TimeDelta
& timeout
) {
706 return WaitForCondition(
707 base::Bind(&MockMediaPlayerManager::IsPlaybackBeyondPosition
,
708 base::Unretained(&manager_
), pts
),
712 bool MediaCodecPlayerTest::StartVideoPlayback(base::TimeDelta duration
,
713 const char* test_name
) {
714 const base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
716 demuxer_
->SetVideoFactory(
717 scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
721 // Wait till the player is initialized on media thread.
722 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
723 base::Unretained(demuxer_
))));
725 if (!demuxer_
->IsInitialized()) {
726 DVLOG(0) << test_name
<< ": demuxer is not initialized";
732 // Post configuration after the player has been initialized.
733 demuxer_
->PostInternalConfigs();
736 EXPECT_FALSE(manager_
.IsPlaybackStarted());
739 // Wait for playback to start.
741 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
742 base::Unretained(&manager_
)),
745 if (!manager_
.IsPlaybackStarted()) {
746 DVLOG(0) << test_name
<< ": playback did not start";
753 bool MediaCodecPlayerTest::StartAVPlayback(
754 scoped_ptr
<AudioFactory
> audio_factory
,
755 scoped_ptr
<VideoFactory
> video_factory
,
757 const char* test_name
) {
758 demuxer_
->SetAudioFactory(audio_factory
.Pass());
759 demuxer_
->SetVideoFactory(video_factory
.Pass());
764 // Wait till the player is initialized on media thread.
765 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
766 base::Unretained(demuxer_
))));
768 if (!demuxer_
->IsInitialized()) {
769 DVLOG(0) << test_name
<< ": demuxer is not initialized";
773 // Ask decoders to always reconfigure after the player has been initialized.
774 if (flags
& kAlwaysReconfigAudio
)
775 player_
->SetAlwaysReconfigureForTests(DemuxerStream::AUDIO
);
776 if (flags
& kAlwaysReconfigVideo
)
777 player_
->SetAlwaysReconfigureForTests(DemuxerStream::VIDEO
);
779 // Set a testing callback to receive PTS from decoders.
780 player_
->SetDecodersTimeCallbackForTests(
781 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
782 base::Unretained(&manager_
)));
784 // Set a testing callback to receive MediaCodec creation events from decoders.
785 player_
->SetCodecCreatedCallbackForTests(
786 base::Bind(&MockMediaPlayerManager::OnMediaCodecCreated
,
787 base::Unretained(&manager_
)));
789 // Post configuration after the player has been initialized.
790 demuxer_
->PostInternalConfigs();
792 // Start and wait for playback.
795 // Wait till we start to play.
796 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(2000);
799 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
800 base::Unretained(&manager_
)),
803 if (!manager_
.IsPlaybackStarted()) {
804 DVLOG(0) << test_name
<< ": playback did not start";
811 bool MediaCodecPlayerTest::StartAVSeekAndPreroll(
812 scoped_ptr
<AudioFactory
> audio_factory
,
813 scoped_ptr
<VideoFactory
> video_factory
,
814 base::TimeDelta seek_position
,
816 const char* test_name
) {
817 // Initialize A/V playback
819 demuxer_
->SetAudioFactory(audio_factory
.Pass());
820 demuxer_
->SetVideoFactory(video_factory
.Pass());
825 // Wait till the player is initialized on media thread.
826 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
827 base::Unretained(demuxer_
))));
829 if (!demuxer_
->IsInitialized()) {
830 DVLOG(0) << test_name
<< ": demuxer is not initialized";
834 // Ask decoders to always reconfigure after the player has been initialized.
835 if (flags
& kAlwaysReconfigAudio
)
836 player_
->SetAlwaysReconfigureForTests(DemuxerStream::AUDIO
);
837 if (flags
& kAlwaysReconfigVideo
)
838 player_
->SetAlwaysReconfigureForTests(DemuxerStream::VIDEO
);
840 // Set a testing callback to receive PTS from decoders.
841 player_
->SetDecodersTimeCallbackForTests(
842 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
843 base::Unretained(&manager_
)));
845 // Set a testing callback to receive MediaCodec creation events from decoders.
846 player_
->SetCodecCreatedCallbackForTests(
847 base::Bind(&MockMediaPlayerManager::OnMediaCodecCreated
,
848 base::Unretained(&manager_
)));
850 // Post configuration after the player has been initialized.
851 demuxer_
->PostInternalConfigs();
854 player_
->SeekTo(seek_position
);
856 // Start the playback.
859 // Wait till preroll starts.
860 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(2000);
861 EXPECT_TRUE(WaitForCondition(
862 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
863 base::Unretained(player_
), DemuxerStream::VIDEO
),
866 if (!player_
->IsPrerollingForTests(DemuxerStream::VIDEO
)) {
867 DVLOG(0) << test_name
<< ": preroll did not happen for video";
874 TEST_F(MediaCodecPlayerTest
, SetAudioConfigsBeforePlayerCreation
) {
875 // Post configuration when there is no player yet.
876 EXPECT_EQ(nullptr, player_
);
878 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
880 demuxer_
->PostConfigs(
881 TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration
));
883 // Wait until the configuration gets to the media thread.
884 EXPECT_TRUE(WaitForCondition(base::Bind(
885 &MockDemuxerAndroid::HasPendingConfigs
, base::Unretained(demuxer_
))));
887 // Then create the player.
890 // Configuration should propagate through the player and to the manager.
892 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged
,
893 base::Unretained(&manager_
))));
895 EXPECT_EQ(duration
, manager_
.media_metadata_
.duration
);
896 EXPECT_EQ(0, manager_
.media_metadata_
.width
);
897 EXPECT_EQ(0, manager_
.media_metadata_
.height
);
900 TEST_F(MediaCodecPlayerTest
, SetAudioConfigsAfterPlayerCreation
) {
903 // Wait till the player is initialized on media thread.
904 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
905 base::Unretained(demuxer_
))));
907 // Post configuration after the player has been initialized.
908 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
909 demuxer_
->PostConfigs(
910 TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration
));
912 // Configuration should propagate through the player and to the manager.
914 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged
,
915 base::Unretained(&manager_
))));
917 EXPECT_EQ(duration
, manager_
.media_metadata_
.duration
);
918 EXPECT_EQ(0, manager_
.media_metadata_
.width
);
919 EXPECT_EQ(0, manager_
.media_metadata_
.height
);
922 TEST_F(MediaCodecPlayerTest
, SetAudioVideoConfigsAfterPlayerCreation
) {
925 // Wait till the player is initialized on media thread.
926 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
927 base::Unretained(demuxer_
))));
929 // Post configuration after the player has been initialized.
930 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
931 demuxer_
->PostConfigs(CreateAudioVideoConfigs(duration
, gfx::Size(320, 240)));
933 // Configuration should propagate through the player and to the manager.
935 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged
,
936 base::Unretained(&manager_
))));
938 EXPECT_EQ(duration
, manager_
.media_metadata_
.duration
);
939 EXPECT_EQ(320, manager_
.media_metadata_
.width
);
940 EXPECT_EQ(240, manager_
.media_metadata_
.height
);
943 TEST_F(MediaCodecPlayerTest
, AudioPlayTillCompletion
) {
944 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
946 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
947 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(2000);
949 demuxer_
->SetAudioFactory(
950 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
954 // Wait till the player is initialized on media thread.
955 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
956 base::Unretained(demuxer_
))));
958 // Post configuration after the player has been initialized.
959 demuxer_
->PostInternalConfigs();
961 EXPECT_FALSE(manager_
.IsPlaybackCompleted());
966 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
967 base::Unretained(&manager_
)),
970 // Current timestamp reflects "now playing" time. It might come with delay
971 // relative to the frame's PTS. Allow for 100 ms delay here.
972 base::TimeDelta audio_pts_delay
= base::TimeDelta::FromMilliseconds(100);
973 EXPECT_LT(duration
- audio_pts_delay
, manager_
.pts_stat_
.max());
976 TEST_F(MediaCodecPlayerTest
, AudioNoPermission
) {
977 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
979 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
980 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
982 manager_
.SetPlaybackAllowed(false);
984 demuxer_
->SetAudioFactory(
985 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
989 // Wait till the player is initialized on media thread.
990 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
991 base::Unretained(demuxer_
))));
993 // Post configuration after the player has been initialized.
994 demuxer_
->PostInternalConfigs();
996 EXPECT_FALSE(manager_
.IsPlaybackCompleted());
1000 // Playback should not start.
1002 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1003 base::Unretained(&manager_
)),
1007 TEST_F(MediaCodecPlayerTest
, VideoPlayTillCompletion
) {
1008 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1010 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
1011 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(2000);
1013 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoPlayTillCompletion"));
1015 // Wait till completion.
1017 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1018 base::Unretained(&manager_
)),
1021 EXPECT_LE(duration
, manager_
.pts_stat_
.max());
1024 TEST_F(MediaCodecPlayerTest
, VideoNoPermission
) {
1025 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1027 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
1028 const base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1030 manager_
.SetPlaybackAllowed(false);
1032 demuxer_
->SetVideoFactory(
1033 scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
1037 // Wait till the player is initialized on media thread.
1038 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
1039 base::Unretained(demuxer_
))));
1043 // Post configuration after the player has been initialized.
1044 demuxer_
->PostInternalConfigs();
1046 // Start the player.
1047 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1050 // Playback should not start.
1052 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1053 base::Unretained(&manager_
)),
1057 // http://crbug.com/518900
1058 TEST_F(MediaCodecPlayerTest
, AudioSeekAfterStop
) {
1059 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1061 // Play for 300 ms, then Pause, then Seek to beginning. The playback should
1062 // start from the beginning.
1064 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1066 demuxer_
->SetAudioFactory(
1067 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1071 // Post configuration.
1072 demuxer_
->PostInternalConfigs();
1074 // Start the player.
1077 // Wait for playback to start.
1079 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1080 base::Unretained(&manager_
))));
1082 // Wait for 300 ms and stop. The 300 ms interval takes into account potential
1083 // audio delay: audio takes time reconfiguring after the first several packets
1084 // get written to the audio track.
1085 WaitForDelay(base::TimeDelta::FromMilliseconds(300));
1087 player_
->Pause(true);
1089 // Make sure we played at least 100 ms.
1090 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1092 // Wait till the Pause is completed.
1093 EXPECT_TRUE(WaitForCondition(
1094 base::Bind(&MediaCodecPlayerTest::IsPaused
, base::Unretained(this))));
1096 // Clear statistics.
1097 manager_
.pts_stat_
.Clear();
1099 // Now we can seek to the beginning and start the playback.
1100 player_
->SeekTo(base::TimeDelta());
1104 // Wait for playback to start.
1106 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1107 base::Unretained(&manager_
))));
1109 // Make sure we started from the beginninig
1110 EXPECT_GT(base::TimeDelta::FromMilliseconds(40), manager_
.pts_stat_
.min());
1112 // The player should have reported the seek completion to the manager.
1113 EXPECT_TRUE(WaitForCondition(base::Bind(
1114 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1117 TEST_F(MediaCodecPlayerTest
, AudioSeekThenPlay
) {
1118 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1120 // Issue Seek command immediately followed by Start. The playback should
1121 // start at the seek position.
1123 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1124 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(500);
1126 demuxer_
->SetAudioFactory(
1127 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1131 // Post configuration.
1132 demuxer_
->PostInternalConfigs();
1134 // Seek and immediately start.
1135 player_
->SeekTo(seek_position
);
1138 // Wait for playback to start.
1140 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1141 base::Unretained(&manager_
))));
1143 // The playback should start at |seek_position|
1144 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1146 // The player should have reported the seek completion to the manager.
1147 EXPECT_TRUE(WaitForCondition(base::Bind(
1148 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1151 TEST_F(MediaCodecPlayerTest
, AudioSeekThenPlayThenConfig
) {
1152 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1154 // Issue Seek command immediately followed by Start but without prior demuxer
1155 // configuration. Start should wait for configuration. After it has been
1156 // posted the playback should start at the seek position.
1158 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1159 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(500);
1161 demuxer_
->SetAudioFactory(
1162 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1166 // Seek and immediately start.
1167 player_
->SeekTo(seek_position
);
1170 // Make sure the player is waiting.
1171 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1172 EXPECT_FALSE(player_
->IsPlaying());
1174 // Post configuration.
1175 demuxer_
->PostInternalConfigs();
1177 // Wait for playback to start.
1179 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1180 base::Unretained(&manager_
))));
1182 // The playback should start at |seek_position|
1183 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1185 // The player should have reported the seek completion to the manager.
1186 EXPECT_TRUE(WaitForCondition(base::Bind(
1187 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1190 // http://crbug.com/518900
1191 TEST_F(MediaCodecPlayerTest
, AudioSeekWhilePlaying
) {
1192 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1194 // Play for 300 ms, then issue several Seek commands in the row.
1195 // The playback should continue at the last seek position.
1197 // To test this condition without analyzing the reported time details
1198 // and without introducing dependency on implementation I make a long (10s)
1199 // duration and test that the playback resumes after big time jump (5s) in a
1200 // short period of time (200 ms).
1201 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
1203 demuxer_
->SetAudioFactory(
1204 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1208 // Post configuration.
1209 demuxer_
->PostInternalConfigs();
1211 // Start the player.
1214 // Wait for playback to start.
1216 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1217 base::Unretained(&manager_
))));
1220 WaitForDelay(base::TimeDelta::FromMilliseconds(300));
1222 // Make sure we played at least 100 ms.
1223 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1225 // Seek forward several times.
1226 player_
->SeekTo(base::TimeDelta::FromSeconds(3));
1227 player_
->SeekTo(base::TimeDelta::FromSeconds(4));
1228 player_
->SeekTo(base::TimeDelta::FromSeconds(5));
1230 // Make sure that we reached the last timestamp within default timeout,
1232 EXPECT_TRUE(WaitForPlaybackBeyondPosition(base::TimeDelta::FromSeconds(5)));
1233 EXPECT_TRUE(player_
->IsPlaying());
1235 // The player should have reported the seek completion to the manager.
1236 EXPECT_TRUE(WaitForCondition(base::Bind(
1237 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1240 TEST_F(MediaCodecPlayerTest
, VideoReplaceSurface
) {
1241 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1243 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
1244 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(1500);
1246 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoReplaceSurface"));
1248 // Wait for some time and check statistics.
1249 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1251 // Make sure we played at least 100 ms.
1252 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1254 // Set new video surface without removing the old one.
1257 // We should receive a browser seek request.
1258 EXPECT_TRUE(WaitForCondition(
1259 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest
,
1260 base::Unretained(demuxer_
))));
1262 // Playback should continue with a new surface. Wait till completion.
1264 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1265 base::Unretained(&manager_
)),
1267 EXPECT_LE(duration
, manager_
.pts_stat_
.max());
1270 TEST_F(MediaCodecPlayerTest
, VideoRemoveAndSetSurface
) {
1271 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1273 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
1275 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoRemoveAndSetSurface"));
1277 // Wait for some time and check statistics.
1278 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1280 // Make sure we played at least 100 ms.
1281 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1283 // Remove video surface.
1284 RemoveVideoSurface();
1286 // We should be stuck waiting for the new surface.
1287 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1288 EXPECT_FALSE(player_
->IsPlaying());
1290 // Save last PTS and clear statistics.
1291 base::TimeDelta max_pts_before_removal
= manager_
.pts_stat_
.max();
1292 manager_
.pts_stat_
.Clear();
1294 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1295 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1297 // Extra RemoveVideoSurface() should not change anything.
1298 RemoveVideoSurface();
1300 // Set another video surface.
1303 // We should receive a browser seek request.
1304 EXPECT_TRUE(WaitForCondition(
1305 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest
,
1306 base::Unretained(demuxer_
))));
1308 // Playback should continue with a new surface. Wait till it starts again.
1309 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(800);
1311 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1312 base::Unretained(&manager_
)),
1313 reconfigure_timeout
));
1315 // Timestamps should not go back.
1316 EXPECT_LE(max_pts_before_removal
, manager_
.pts_stat_
.max());
1319 // http://crbug.com/518900
1320 TEST_F(MediaCodecPlayerTest
, VideoReleaseAndStart
) {
1321 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1323 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
1325 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoReleaseAndStart"));
1327 // Wait for some time and check statistics.
1328 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1330 // Make sure we played at least 100 ms.
1331 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1333 // When the user presses Tasks button Chrome calls Pause() and Release().
1334 player_
->Pause(true);
1337 // Make sure we are not playing any more.
1338 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1339 EXPECT_FALSE(player_
->IsPlaying());
1341 // Save last PTS and clear statistics.
1342 base::TimeDelta max_pts_before_backgrounding
= manager_
.pts_stat_
.max();
1343 manager_
.pts_stat_
.Clear();
1345 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1346 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1352 // We should receive a browser seek request.
1353 EXPECT_TRUE(WaitForCondition(
1354 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest
,
1355 base::Unretained(demuxer_
))));
1357 // Wait for playback to start again.
1358 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(800);
1360 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1361 base::Unretained(&manager_
)),
1362 reconfigure_timeout
));
1364 // Timestamps should not go back.
1365 EXPECT_LE(max_pts_before_backgrounding
, manager_
.pts_stat_
.max());
1368 TEST_F(MediaCodecPlayerTest
, VideoSeekAndRelease
) {
1369 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1371 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1372 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1374 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoSeekAndRelease"));
1376 // Wait for some time and check statistics.
1377 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1379 // Make sure we played at least 100 ms.
1380 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1382 // Issue SeekTo() immediately followed by Release().
1383 player_
->SeekTo(seek_position
);
1386 // Make sure we are not playing any more.
1387 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1388 EXPECT_FALSE(player_
->IsPlaying());
1390 // The Release() should not cancel the SeekTo() and we should have received
1391 // the seek request by this time.
1392 EXPECT_TRUE(demuxer_
->ReceivedSeekRequest());
1394 // The player should have reported the seek completion to the manager.
1395 EXPECT_TRUE(WaitForCondition(base::Bind(
1396 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1398 // Clear statistics.
1399 manager_
.pts_stat_
.Clear();
1401 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1402 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1408 // Wait for playback to start again.
1409 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(800);
1411 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1412 base::Unretained(&manager_
)),
1413 reconfigure_timeout
));
1415 // Timestamps should start at the new seek position
1416 EXPECT_LE(seek_position
, manager_
.pts_stat_
.min());
1419 TEST_F(MediaCodecPlayerTest
, VideoReleaseWhileWaitingForSeek
) {
1420 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1422 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1423 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1425 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoReleaseWhileWaitingForSeek"));
1427 // Wait for some time and check statistics.
1428 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1430 // Make sure we played at least 100 ms.
1431 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1433 // Set artificial delay in the OnDemuxerSeekDone response so we can
1434 // issue commands while the player is in the STATE_WAITING_FOR_SEEK.
1435 demuxer_
->SetSeekDoneDelay(base::TimeDelta::FromMilliseconds(100));
1438 player_
->SeekTo(seek_position
);
1440 // Wait for the seek request to demuxer.
1441 EXPECT_TRUE(WaitForCondition(base::Bind(
1442 &MockDemuxerAndroid::ReceivedSeekRequest
, base::Unretained(demuxer_
))));
1444 // The player is supposed to be in STATE_WAITING_FOR_SEEK. Issue Release().
1447 // Make sure we are not playing any more.
1448 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1449 EXPECT_FALSE(player_
->IsPlaying());
1451 // Clear statistics.
1452 manager_
.pts_stat_
.Clear();
1454 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1455 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1461 // Wait for playback to start again.
1462 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(1000);
1464 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1465 base::Unretained(&manager_
)),
1466 reconfigure_timeout
));
1468 // Timestamps should start at the new seek position
1469 EXPECT_LE(seek_position
, manager_
.pts_stat_
.min());
1471 // The player should have reported the seek completion to the manager.
1472 EXPECT_TRUE(WaitForCondition(base::Bind(
1473 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1476 TEST_F(MediaCodecPlayerTest
, VideoPrerollAfterSeek
) {
1477 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1479 // A simple test for preroll for video stream only. After the seek is done
1480 // the data factory generates the frames with pts before the seek time, and
1481 // they should not be rendered. We deduce which frame is rendered by looking
1482 // at the reported time progress.
1484 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(600);
1485 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(500);
1486 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1488 // Tell demuxer to make the first frame 100ms earlier than the seek request.
1489 demuxer_
->SetVideoPrerollInterval(base::TimeDelta::FromMilliseconds(100));
1491 demuxer_
->SetVideoFactory(
1492 scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
1497 // Wait till the player is initialized on media thread.
1498 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
1499 base::Unretained(demuxer_
))));
1500 if (!demuxer_
->IsInitialized()) {
1501 DVLOG(0) << "VideoPrerollAfterSeek: demuxer is not initialized";
1505 // Post configuration after the player has been initialized.
1506 demuxer_
->PostInternalConfigs();
1509 player_
->SeekTo(seek_position
);
1511 // Start the playback and make sure it is started.
1515 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1516 base::Unretained(&manager_
)),
1519 // Wait for completion.
1521 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1522 base::Unretained(&manager_
))));
1524 // The first pts should be equal than seek position even if video frames
1525 // started 100 ms eralier than the seek request.
1526 EXPECT_EQ(seek_position
, manager_
.pts_stat_
.min());
1528 EXPECT_EQ(6, manager_
.pts_stat_
.num_values());
1531 TEST_F(MediaCodecPlayerTest
, AVPrerollAudioWaitsForVideo
) {
1532 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1534 // Test that during prerolling neither audio nor video plays and that both
1535 // resume simultaneously after preroll is finished. In other words, test
1536 // that preroll works.
1537 // We put the video into the long preroll and intercept the time when first
1538 // rendering happens in each stream. The moment of rendering is approximated
1539 // with a decoder PTS that is delivered by a test-only callback.
1541 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1543 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1544 // per frame it would take 250 ms to preroll.
1545 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1546 base::TimeDelta preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
1547 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(1000);
1549 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1550 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1552 demuxer_
->SetVideoPrerollInterval(preroll_intvl
);
1554 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
1556 "AVPrerollAudioWaitsForVideo"));
1558 // Wait till preroll finishes and the real playback starts.
1560 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1561 base::Unretained(&manager_
)),
1564 // Ensure that the first audio and video pts are close to each other and are
1565 // reported at the close moments in time.
1567 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1568 EXPECT_TRUE(WaitForCondition(
1569 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
1570 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
1572 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
1573 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
1575 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
1576 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
1578 // The playback should start at |seek_position|
1579 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1582 TEST_F(MediaCodecPlayerTest
, AVPrerollReleaseAndRestart
) {
1583 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1585 // Test that player will resume prerolling if prerolling is interrupted by
1586 // Release() and Start().
1588 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1590 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1591 // per frame it would take 250 ms to preroll.
1592 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1593 base::TimeDelta preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
1595 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1596 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(1000);
1598 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1599 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1601 demuxer_
->SetVideoPrerollInterval(preroll_intvl
);
1603 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
1605 "AVPrerollReleaseAndRestart"));
1610 // Make sure we have not been playing.
1611 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1613 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1614 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1616 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::AUDIO
));
1617 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::VIDEO
));
1618 EXPECT_EQ(0, manager_
.pts_stat_
.num_values());
1620 // Restart. Release() removed the video surface, we need to set it again.
1624 // The playback should pass through prerolling phase.
1625 EXPECT_TRUE(WaitForCondition(
1626 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
1627 base::Unretained(player_
), DemuxerStream::VIDEO
),
1630 // Wait till preroll finishes and the real playback starts.
1632 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1633 base::Unretained(&manager_
)),
1636 // Ensure that the first audio and video pts are close to each other and are
1637 // reported at the close moments in time.
1639 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1640 EXPECT_TRUE(WaitForCondition(
1641 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
1642 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
1644 // Release() might disacrd first audio frame.
1645 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
1646 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 50));
1648 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
1649 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
1651 // The playback should start at |seek_position|, but Release() might discard
1652 // the first audio frame.
1653 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 50));
1656 TEST_F(MediaCodecPlayerTest
, AVPrerollStopAndRestart
) {
1657 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1659 // Test that if Pause() happens during the preroll phase,
1660 // we continue to do preroll after restart.
1662 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1664 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1665 // per frame it would take 250 ms to preroll.
1666 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1667 base::TimeDelta preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
1669 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1670 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(1000);
1672 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1673 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1675 demuxer_
->SetVideoPrerollInterval(preroll_intvl
);
1677 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
1679 "AVPrerollStopAndRestart"));
1681 // Video stream should be prerolling. Request to stop.
1682 EXPECT_FALSE(IsPaused());
1683 player_
->Pause(true);
1685 EXPECT_TRUE(WaitForCondition(
1686 base::Bind(&MediaCodecPlayerTest::IsPaused
, base::Unretained(this))));
1688 // Test that we have not been playing.
1689 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1690 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1692 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::AUDIO
));
1693 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::VIDEO
));
1694 EXPECT_EQ(0, manager_
.pts_stat_
.num_values());
1699 // There should be preroll after the start.
1700 EXPECT_TRUE(WaitForCondition(
1701 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
1702 base::Unretained(player_
), DemuxerStream::VIDEO
),
1705 // Wait for a short period of time, so that preroll is still ongoing,
1707 WaitForDelay(base::TimeDelta::FromMilliseconds(100));
1709 EXPECT_FALSE(IsPaused());
1710 player_
->Pause(true);
1712 EXPECT_TRUE(WaitForCondition(
1713 base::Bind(&MediaCodecPlayerTest::IsPaused
, base::Unretained(this))));
1715 // Check that we still haven't started rendering.
1716 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1717 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1719 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::AUDIO
));
1720 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::VIDEO
));
1721 EXPECT_EQ(0, manager_
.pts_stat_
.num_values());
1726 // Wait till we start to play.
1728 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1729 base::Unretained(&manager_
)),
1732 // Check that we did prerolling, i.e. audio did wait for video.
1733 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1734 EXPECT_TRUE(WaitForCondition(
1735 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
1736 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
1738 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
1739 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
1741 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
1742 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
1744 // The playback should start at |seek_position|
1745 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1748 TEST_F(MediaCodecPlayerTest
, AVPrerollVideoEndsWhilePrerolling
) {
1749 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1751 // Test that when one stream ends in the preroll phase and another is not
1752 // the preroll finishes and playback continues after it.
1754 // http://crbug.com/526755
1755 // TODO(timav): remove these logs after verifying that the bug is fixed.
1756 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: begin";
1758 base::TimeDelta audio_duration
= base::TimeDelta::FromMilliseconds(1100);
1759 base::TimeDelta video_duration
= base::TimeDelta::FromMilliseconds(900);
1760 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1761 base::TimeDelta video_preroll_intvl
= base::TimeDelta::FromMilliseconds(200);
1763 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1764 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(400);
1766 demuxer_
->SetVideoPrerollInterval(video_preroll_intvl
);
1768 demuxer_
->SetAudioFactory(
1769 scoped_ptr
<AudioFactory
>(new AudioFactory(audio_duration
)));
1770 demuxer_
->SetVideoFactory(
1771 scoped_ptr
<VideoFactory
>(new VideoFactory(video_duration
)));
1776 // Set special testing callback to receive PTS from decoders.
1777 player_
->SetDecodersTimeCallbackForTests(
1778 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
1779 base::Unretained(&manager_
)));
1781 // Wait till the player is initialized on media thread.
1782 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
1783 base::Unretained(demuxer_
))));
1785 if (!demuxer_
->IsInitialized()) {
1786 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: demuxer is not initialized";
1790 // Post configuration after the player has been initialized.
1791 demuxer_
->PostInternalConfigs();
1794 player_
->SeekTo(seek_position
);
1796 // Start the playback.
1799 // The video decoder should start prerolling.
1800 // Wait till preroll starts.
1801 EXPECT_TRUE(WaitForCondition(
1802 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
1803 base::Unretained(player_
), DemuxerStream::VIDEO
),
1806 // Wait for playback to start.
1807 bool playback_started
=
1808 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1809 base::Unretained(&manager_
)),
1812 // http://crbug.com/526755
1813 if (!playback_started
) {
1814 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: playback did not start for "
1817 ASSERT_TRUE(playback_started
);
1819 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1821 // Play till completion.
1823 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1824 base::Unretained(&manager_
))));
1826 // There should not be any video frames.
1827 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1829 // http://crbug.com/526755
1830 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: end";
1833 TEST_F(MediaCodecPlayerTest
, VideoConfigChangeWhilePlaying
) {
1834 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1836 // Test that video only playback continues after video config change.
1838 // Initialize video playback
1839 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1840 base::TimeDelta config_change_position
=
1841 base::TimeDelta::FromMilliseconds(1000);
1843 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(2000);
1844 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1846 demuxer_
->SetVideoFactory(
1847 scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
1849 demuxer_
->video_factory()->RequestConfigChange(config_change_position
);
1854 // Wait till the player is initialized on media thread.
1855 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
1856 base::Unretained(demuxer_
))));
1858 if (!demuxer_
->IsInitialized()) {
1859 DVLOG(0) << "VideoConfigChangeWhilePlaying: demuxer is not initialized";
1863 // Ask decoders to always reconfigure after the player has been initialized.
1864 player_
->SetAlwaysReconfigureForTests(DemuxerStream::VIDEO
);
1866 // Set a testing callback to receive PTS from decoders.
1867 player_
->SetDecodersTimeCallbackForTests(
1868 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
1869 base::Unretained(&manager_
)));
1871 // Set a testing callback to receive MediaCodec creation events from decoders.
1872 player_
->SetCodecCreatedCallbackForTests(
1873 base::Bind(&MockMediaPlayerManager::OnMediaCodecCreated
,
1874 base::Unretained(&manager_
)));
1876 // Post configuration after the player has been initialized.
1877 demuxer_
->PostInternalConfigs();
1879 // Start and wait for playback.
1882 // Wait till we start to play.
1884 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1885 base::Unretained(&manager_
)),
1888 // Wait till completion
1890 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1891 base::Unretained(&manager_
)),
1892 completion_timeout
));
1894 // The video codec should be recreated upon config changes.
1895 EXPECT_EQ(2, manager_
.num_video_codecs_created());
1897 // Check that we did not miss video frames
1898 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
1899 EXPECT_EQ(expected_video_frames
,
1900 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
1903 TEST_F(MediaCodecPlayerTest
, AVVideoConfigChangeWhilePlaying
) {
1904 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1906 // Test that A/V playback continues after video config change.
1908 // Initialize A/V playback
1909 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1910 base::TimeDelta config_change_position
=
1911 base::TimeDelta::FromMilliseconds(1000);
1913 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1915 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1916 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1918 video_factory
->RequestConfigChange(config_change_position
);
1920 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
1921 kAlwaysReconfigVideo
,
1922 "AVVideoConfigChangeWhilePlaying"));
1924 // Wait till completion
1926 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1927 base::Unretained(&manager_
)),
1928 completion_timeout
));
1930 // The audio codec should be kept.
1931 EXPECT_EQ(1, manager_
.num_audio_codecs_created());
1933 // The video codec should be recreated upon config changes.
1934 EXPECT_EQ(2, manager_
.num_video_codecs_created());
1936 // Check that we did not miss video frames
1937 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
1938 EXPECT_EQ(expected_video_frames
,
1939 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
1941 // Check that we did not miss audio frames. We expect one postponed frames
1942 // that are not reported.
1943 // For Nexus 4 KitKat the AAC decoder seems to swallow the first frame
1944 // but reports the last pts twice, maybe it just shifts the reported PTS.
1945 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 0) - 1;
1946 EXPECT_EQ(expected_audio_frames
,
1947 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
1950 TEST_F(MediaCodecPlayerTest
, AVAudioConfigChangeWhilePlaying
) {
1951 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1953 // Test that A/V playback continues after audio config change.
1955 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1956 base::TimeDelta config_change_position
=
1957 base::TimeDelta::FromMilliseconds(1000);
1959 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1961 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1962 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1964 audio_factory
->RequestConfigChange(config_change_position
);
1966 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
1967 kAlwaysReconfigAudio
,
1968 "AVAudioConfigChangeWhilePlaying"));
1970 // Wait till completion
1972 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1973 base::Unretained(&manager_
)),
1974 completion_timeout
));
1976 // The audio codec should be recreated upon config changes.
1977 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
1979 // The video codec should be kept.
1980 EXPECT_EQ(1, manager_
.num_video_codecs_created());
1982 // Check that we did not miss video frames.
1983 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 0);
1984 EXPECT_EQ(expected_video_frames
,
1985 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
1987 // Check that we did not miss audio frames. We expect two postponed frames
1988 // that are not reported.
1989 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 1) - 2;
1990 EXPECT_EQ(expected_audio_frames
,
1991 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
1994 TEST_F(MediaCodecPlayerTest
, AVSimultaneousConfigChange_1
) {
1995 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1997 // Test that the playback continues if audio and video config changes happen
1998 // at the same time.
2000 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
2001 base::TimeDelta config_change_audio
= base::TimeDelta::FromMilliseconds(1000);
2002 base::TimeDelta config_change_video
= base::TimeDelta::FromMilliseconds(1000);
2004 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
2006 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
2007 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
2009 audio_factory
->RequestConfigChange(config_change_audio
);
2010 video_factory
->RequestConfigChange(config_change_video
);
2012 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
2013 kAlwaysReconfigAudio
| kAlwaysReconfigVideo
,
2014 "AVSimultaneousConfigChange_1"));
2016 // Wait till completion
2018 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
2019 base::Unretained(&manager_
)),
2020 completion_timeout
));
2022 // The audio codec should be recreated upon config changes.
2023 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
2025 // The video codec should be recreated upon config changes.
2026 EXPECT_EQ(2, manager_
.num_video_codecs_created());
2028 // Check that we did not miss video frames.
2029 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
2030 EXPECT_EQ(expected_video_frames
,
2031 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
2033 // Check that we did not miss audio frames. We expect two postponed frames
2034 // that are not reported.
2035 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 1) - 2;
2036 EXPECT_EQ(expected_audio_frames
,
2037 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
2040 TEST_F(MediaCodecPlayerTest
, AVSimultaneousConfigChange_2
) {
2041 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2043 // Test that the playback continues if audio and video config changes happen
2044 // at the same time. Move audio change moment slightly to make it drained
2047 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
2048 base::TimeDelta config_change_audio
= base::TimeDelta::FromMilliseconds(1020);
2049 base::TimeDelta config_change_video
= base::TimeDelta::FromMilliseconds(1000);
2051 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
2053 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
2054 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
2056 audio_factory
->RequestConfigChange(config_change_audio
);
2057 video_factory
->RequestConfigChange(config_change_video
);
2059 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
2060 kAlwaysReconfigAudio
| kAlwaysReconfigVideo
,
2061 "AVSimultaneousConfigChange_2"));
2063 // Wait till completion
2065 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
2066 base::Unretained(&manager_
)),
2067 completion_timeout
));
2069 // The audio codec should be recreated upon config changes.
2070 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
2072 // The video codec should be recreated upon config changes.
2073 EXPECT_EQ(2, manager_
.num_video_codecs_created());
2075 // Check that we did not miss video frames.
2076 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
2077 EXPECT_EQ(expected_video_frames
,
2078 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
2080 // Check that we did not miss audio frames. We expect two postponed frames
2081 // that are not reported.
2082 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 1) - 2;
2083 EXPECT_EQ(expected_audio_frames
,
2084 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
2087 TEST_F(MediaCodecPlayerTest
, AVAudioEndsAcrossVideoConfigChange
) {
2088 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2090 // Test that audio can end while video config change processing.
2092 base::TimeDelta audio_duration
= base::TimeDelta::FromMilliseconds(1000);
2093 base::TimeDelta video_duration
= base::TimeDelta::FromMilliseconds(1200);
2094 base::TimeDelta config_change_video
= base::TimeDelta::FromMilliseconds(1000);
2096 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
2098 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(audio_duration
));
2099 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(video_duration
));
2101 video_factory
->RequestConfigChange(config_change_video
);
2103 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
2104 kAlwaysReconfigVideo
,
2105 "AVAudioEndsAcrossVideoConfigChange"));
2107 // Wait till completion
2109 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
2110 base::Unretained(&manager_
)),
2111 completion_timeout
));
2113 // The audio codec should not be recreated.
2114 EXPECT_EQ(1, manager_
.num_audio_codecs_created());
2116 // The video codec should be recreated upon config changes.
2117 EXPECT_EQ(2, manager_
.num_video_codecs_created());
2119 // Check that we did not miss video frames.
2120 int expected_video_frames
=
2121 GetFrameCount(video_duration
, kVideoFramePeriod
, 1);
2122 EXPECT_EQ(expected_video_frames
,
2123 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
2125 // Check the last video frame timestamp. The maximum render pts may differ
2126 // from |video_duration| because of the testing artefact: if the last video
2127 // chunk is incomplete if will have different last pts due to B-frames
2129 EXPECT_LE(video_duration
,
2130 manager_
.render_stat_
[DemuxerStream::VIDEO
].max().pts
);
2132 // Check that the playback time reported by the player goes past
2133 // the audio time and corresponds to video after the audio ended.
2134 EXPECT_EQ(video_duration
, manager_
.pts_stat_
.max());
2137 TEST_F(MediaCodecPlayerTest
, AVVideoEndsAcrossAudioConfigChange
) {
2138 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2140 // Test that video can end while audio config change processing.
2141 base::TimeDelta audio_duration
= base::TimeDelta::FromMilliseconds(1200);
2142 base::TimeDelta video_duration
= base::TimeDelta::FromMilliseconds(1000);
2143 base::TimeDelta config_change_audio
= base::TimeDelta::FromMilliseconds(1000);
2145 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
2147 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(audio_duration
));
2148 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(video_duration
));
2150 audio_factory
->RequestConfigChange(config_change_audio
);
2152 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
2153 kAlwaysReconfigAudio
,
2154 "AVVideoEndsAcrossAudioConfigChange"));
2156 // Wait till completion
2158 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
2159 base::Unretained(&manager_
)),
2160 completion_timeout
));
2162 // The audio codec should be recreated upon config changes.
2163 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
2165 // The video codec should not be recreated.
2166 EXPECT_EQ(1, manager_
.num_video_codecs_created());
2168 // Check that we did not miss audio frames. We expect two postponed frames
2169 // that are not reported.
2170 int expected_audio_frames
=
2171 GetFrameCount(audio_duration
, kAudioFramePeriod
, 1) - 2;
2172 EXPECT_EQ(expected_audio_frames
,
2173 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
2176 TEST_F(MediaCodecPlayerTest
, AVPrerollAcrossVideoConfigChange
) {
2177 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2179 // Test that preroll continues if interrupted by video config change.
2181 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
2182 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
2183 base::TimeDelta config_change_position
=
2184 base::TimeDelta::FromMilliseconds(800);
2185 base::TimeDelta video_preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
2186 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(3000);
2188 demuxer_
->SetVideoPrerollInterval(video_preroll_intvl
);
2190 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
2192 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
2193 video_factory
->RequestConfigChange(config_change_position
);
2195 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
2196 seek_position
, kAlwaysReconfigVideo
,
2197 "AVPrerollAcrossVideoConfigChange"));
2199 // Wait till preroll finishes and the real playback starts.
2201 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
2202 base::Unretained(&manager_
)),
2205 // The presense of config change should not affect preroll behavior:
2207 // Ensure that the first audio and video pts are close to each other and are
2208 // reported at the close moments in time.
2210 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
2211 EXPECT_TRUE(WaitForCondition(
2212 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
2213 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
2215 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
2216 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
2218 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
2219 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
2221 // The playback should start at |seek_position|
2222 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
2225 TEST_F(MediaCodecPlayerTest
, AVPrerollAcrossAudioConfigChange
) {
2226 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2228 // Test that preroll continues if interrupted by video config change.
2230 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
2231 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
2232 base::TimeDelta config_change_position
=
2233 base::TimeDelta::FromMilliseconds(800);
2234 base::TimeDelta audio_preroll_intvl
= base::TimeDelta::FromMilliseconds(400);
2235 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(3000);
2237 demuxer_
->SetAudioPrerollInterval(audio_preroll_intvl
);
2239 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
2240 audio_factory
->RequestConfigChange(config_change_position
);
2242 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
2244 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
2245 seek_position
, kAlwaysReconfigAudio
,
2246 "AVPrerollAcrossAudioConfigChange"));
2248 // Wait till preroll finishes and the real playback starts.
2250 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
2251 base::Unretained(&manager_
)),
2254 // The presense of config change should not affect preroll behavior:
2256 // Ensure that the first audio and video pts are close to each other and are
2257 // reported at the close moments in time.
2259 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
2260 EXPECT_TRUE(WaitForCondition(
2261 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
2262 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
2264 // Wait for some more video
2265 WaitForDelay(base::TimeDelta::FromMilliseconds(100));
2267 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
2268 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
2270 // Because for video preroll the first frame after preroll renders during the
2271 // preroll stage (and not after the preroll is done) we cannot guarantee the
2272 // proper video timimg in this test.
2273 // TODO(timav): maybe we should not call the testing callback for
2274 // kRenderAfterPreroll for video (for audio we already do not call).
2275 // EXPECT_TRUE(AlmostEqual(manager_.FirstFrameTime(DemuxerStream::AUDIO),
2276 // manager_.FirstFrameTime(DemuxerStream::VIDEO), 50));
2278 // The playback should start at |seek_position|
2279 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
2282 } // namespace media