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_completed_(false),
94 num_seeks_completed_(0),
95 num_audio_codecs_created_(0),
96 num_video_codecs_created_(0),
97 weak_ptr_factory_(this) {}
98 ~MockMediaPlayerManager() override
{}
100 MediaResourceGetter
* GetMediaResourceGetter() override
{ return nullptr; }
101 MediaUrlInterceptor
* GetMediaUrlInterceptor() override
{ return nullptr; }
103 // Regular time update callback, reports current playback time to
104 // MediaPlayerManager.
105 void OnTimeUpdate(int player_id
,
106 base::TimeDelta current_timestamp
,
107 base::TimeTicks current_time_ticks
) override
{
108 pts_stat_
.AddValue(current_timestamp
);
111 void OnMediaMetadataChanged(int player_id
,
112 base::TimeDelta duration
,
115 bool success
) override
{
116 media_metadata_
.duration
= duration
;
117 media_metadata_
.width
= width
;
118 media_metadata_
.height
= height
;
119 media_metadata_
.modified
= true;
122 void OnPlaybackComplete(int player_id
) override
{
123 playback_completed_
= true;
126 void OnMediaInterrupted(int player_id
) override
{}
127 void OnBufferingUpdate(int player_id
, int percentage
) override
{}
128 void OnSeekComplete(int player_id
,
129 const base::TimeDelta
& current_time
) override
{
130 ++num_seeks_completed_
;
132 void OnError(int player_id
, int error
) override
{}
133 void OnVideoSizeChanged(int player_id
, int width
, int height
) override
{}
134 void OnWaitingForDecryptionKey(int player_id
) override
{}
135 MediaPlayerAndroid
* GetFullscreenPlayer() override
{ return nullptr; }
136 MediaPlayerAndroid
* GetPlayer(int player_id
) override
{ return nullptr; }
137 bool RequestPlay(int player_id
) override
{ return true; }
139 void OnMediaResourcesRequested(int player_id
) {}
141 // Time update callback that reports the internal progress of the stream.
142 // Implementation dependent, used for testing only.
143 void OnDecodersTimeUpdate(DemuxerStream::Type stream_type
,
144 base::TimeDelta now_playing
,
145 base::TimeDelta last_buffered
) {
146 render_stat_
[stream_type
].AddValue(
147 PTSTime(now_playing
, base::TimeTicks::Now()));
150 // Notification called on MediaCodec creation.
151 // Implementation dependent, used for testing only.
152 void OnMediaCodecCreated(DemuxerStream::Type stream_type
) {
153 if (stream_type
== DemuxerStream::AUDIO
)
154 ++num_audio_codecs_created_
;
155 else if (stream_type
== DemuxerStream::VIDEO
)
156 ++num_video_codecs_created_
;
159 // First frame information
160 base::TimeDelta
FirstFramePTS(DemuxerStream::Type stream_type
) const {
161 return render_stat_
[stream_type
].min().pts
;
163 base::TimeTicks
FirstFrameTime(DemuxerStream::Type stream_type
) const {
164 return render_stat_
[stream_type
].min().time
;
167 base::WeakPtr
<MockMediaPlayerManager
> GetWeakPtr() {
168 return weak_ptr_factory_
.GetWeakPtr();
171 // Conditions to wait for.
172 bool IsMetadataChanged() const { return media_metadata_
.modified
; }
173 bool IsPlaybackCompleted() const { return playback_completed_
; }
174 bool IsPlaybackStarted() const { return pts_stat_
.num_values() > 0; }
175 bool IsPlaybackBeyondPosition(const base::TimeDelta
& pts
) const {
176 return pts_stat_
.max() > pts
;
178 bool IsSeekCompleted() const { return num_seeks_completed_
> 0; }
179 bool HasFirstFrame(DemuxerStream::Type stream_type
) const {
180 return render_stat_
[stream_type
].num_values() != 0;
183 int num_audio_codecs_created() const { return num_audio_codecs_created_
; }
184 int num_video_codecs_created() const { return num_video_codecs_created_
; }
186 struct MediaMetadata
{
187 base::TimeDelta duration
;
191 MediaMetadata() : width(0), height(0), modified(false) {}
193 MediaMetadata media_metadata_
;
197 base::TimeTicks time
;
199 PTSTime() : pts(), time() {}
200 PTSTime(base::TimeDelta p
, base::TimeTicks t
) : pts(p
), time(t
) {}
201 bool is_null() const { return time
.is_null(); }
202 bool operator<(const PTSTime
& rhs
) const { return time
< rhs
.time
; }
204 Minimax
<PTSTime
> render_stat_
[DemuxerStream::NUM_TYPES
];
206 Minimax
<base::TimeDelta
> pts_stat_
;
209 bool playback_completed_
;
210 int num_seeks_completed_
;
211 int num_audio_codecs_created_
;
212 int num_video_codecs_created_
;
214 base::WeakPtrFactory
<MockMediaPlayerManager
> weak_ptr_factory_
;
216 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager
);
219 // Helper method that creates demuxer configuration.
221 DemuxerConfigs
CreateAudioVideoConfigs(const base::TimeDelta
& duration
,
222 const gfx::Size
& video_size
) {
223 DemuxerConfigs configs
=
224 TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration
);
225 configs
.video_codec
= kCodecVP8
;
226 configs
.video_size
= video_size
;
227 configs
.is_video_encrypted
= false;
231 DemuxerConfigs
CreateAudioVideoConfigs(const TestDataFactory
* audio
,
232 const TestDataFactory
* video
) {
233 DemuxerConfigs result
= audio
->GetConfigs();
234 DemuxerConfigs vconf
= video
->GetConfigs();
236 result
.video_codec
= vconf
.video_codec
;
237 result
.video_size
= vconf
.video_size
;
238 result
.is_video_encrypted
= vconf
.is_video_encrypted
;
239 result
.duration
= std::max(result
.duration
, vconf
.duration
);
243 // AudioFactory creates data chunks that simulate audio stream from demuxer.
245 class AudioFactory
: public TestDataFactory
{
247 AudioFactory(base::TimeDelta duration
)
248 : TestDataFactory("aac-44100-packet-%d", duration
, kAudioFramePeriod
) {}
250 DemuxerConfigs
GetConfigs() const override
{
251 return TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration_
);
255 void ModifyChunk(DemuxerData
* chunk
) override
{
257 for (AccessUnit
& unit
: chunk
->access_units
) {
258 if (!unit
.data
.empty())
259 unit
.is_key_frame
= true;
264 // VideoFactory creates a video stream from demuxer.
266 class VideoFactory
: public TestDataFactory
{
268 VideoFactory(base::TimeDelta duration
)
269 : TestDataFactory("h264-320x180-frame-%d", duration
, kVideoFramePeriod
),
270 key_frame_requested_(true) {}
272 DemuxerConfigs
GetConfigs() const override
{
273 return TestDataFactory::CreateVideoConfigs(kCodecH264
, duration_
,
274 gfx::Size(320, 180));
277 void RequestKeyFrame() { key_frame_requested_
= true; }
280 void ModifyChunk(DemuxerData
* chunk
) override
{
281 // The frames are taken from High profile and some are B-frames.
282 // The first 4 frames appear in the file in the following order:
285 // Decoding order: 0 1 2 3
286 // Presentation order: 0 2 1 4(3)
288 // I keep the last PTS to be 3 for simplicity.
290 // If the chunk contains EOS, it should not break the presentation order.
291 // For instance, the following chunk is ok:
294 // Decoding order: 0 1 2 -
295 // Presentation order: 0 2 1 -
297 // while this might cause decoder to block:
300 // Decoding order: 0 1 -
301 // Presentation order: 0 2 - <------- might wait for the B frame forever
303 // With current base class implementation that always has EOS at the 4th
304 // place we are covered (http://crbug.com/526755)
307 DCHECK(chunk
->access_units
.size() == 4);
309 // Swap pts for second and third frames.
310 base::TimeDelta tmp
= chunk
->access_units
[1].timestamp
;
311 chunk
->access_units
[1].timestamp
= chunk
->access_units
[2].timestamp
;
312 chunk
->access_units
[2].timestamp
= tmp
;
314 // Make first frame a key frame.
315 if (key_frame_requested_
) {
316 chunk
->access_units
[0].is_key_frame
= true;
317 key_frame_requested_
= false;
322 bool key_frame_requested_
;
325 // Mock of DemuxerAndroid for testing purpose.
327 class MockDemuxerAndroid
: public DemuxerAndroid
{
329 MockDemuxerAndroid(base::MessageLoop
* ui_message_loop
);
330 ~MockDemuxerAndroid() override
;
332 // DemuxerAndroid implementation
333 void Initialize(DemuxerAndroidClient
* client
) override
;
334 void RequestDemuxerData(DemuxerStream::Type type
) override
;
335 void RequestDemuxerSeek(const base::TimeDelta
& seek_request
,
336 bool is_browser_seek
) override
;
338 // Helper methods that enable using a weak pointer when posting to the player.
339 void OnDemuxerDataAvailable(const DemuxerData
& chunk
);
340 void OnDemuxerSeekDone(base::TimeDelta reported_seek_time
);
342 // Sets the callback that is fired when demuxer is deleted (deletion
343 // happens on the Media thread).
344 void SetDemuxerDeletedCallback(base::Closure cb
) { demuxer_deleted_cb_
= cb
; }
346 // Sets the audio data factory.
347 void SetAudioFactory(scoped_ptr
<AudioFactory
> factory
) {
348 audio_factory_
= factory
.Pass();
351 // Sets the video data factory.
352 void SetVideoFactory(scoped_ptr
<VideoFactory
> factory
) {
353 video_factory_
= factory
.Pass();
356 // Accessors for data factories.
357 AudioFactory
* audio_factory() const { return audio_factory_
.get(); }
358 VideoFactory
* video_factory() const { return video_factory_
.get(); }
360 // Set the preroll interval after seek for audio stream.
361 void SetAudioPrerollInterval(base::TimeDelta value
) {
362 audio_preroll_interval_
= value
;
365 // Set the preroll interval after seek for video stream.
366 void SetVideoPrerollInterval(base::TimeDelta value
) {
367 video_preroll_interval_
= value
;
370 // Sets the delay in OnDemuxerSeekDone response.
371 void SetSeekDoneDelay(base::TimeDelta delay
) { seek_done_delay_
= delay
; }
373 // Post DemuxerConfigs to the client (i.e. the player) on correct thread.
374 void PostConfigs(const DemuxerConfigs
& configs
);
376 // Post DemuxerConfigs derived from data factories that has been set.
377 void PostInternalConfigs();
379 // Conditions to wait for.
380 bool IsInitialized() const { return client_
; }
381 bool HasPendingConfigs() const { return pending_configs_
; }
382 bool ReceivedSeekRequest() const { return num_seeks_
> 0; }
383 bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_
> 0; }
386 base::MessageLoop
* ui_message_loop_
;
387 DemuxerAndroidClient
* client_
;
389 scoped_ptr
<DemuxerConfigs
> pending_configs_
;
390 scoped_ptr
<AudioFactory
> audio_factory_
;
391 scoped_ptr
<VideoFactory
> video_factory_
;
393 base::TimeDelta audio_preroll_interval_
;
394 base::TimeDelta video_preroll_interval_
;
395 base::TimeDelta seek_done_delay_
;
398 int num_browser_seeks_
;
400 base::Closure demuxer_deleted_cb_
;
402 // NOTE: WeakPtrFactory must be the last data member to be destroyed first.
403 base::WeakPtrFactory
<MockDemuxerAndroid
> weak_factory_
;
405 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid
);
408 MockDemuxerAndroid::MockDemuxerAndroid(base::MessageLoop
* ui_message_loop
)
409 : ui_message_loop_(ui_message_loop
),
412 num_browser_seeks_(0),
413 weak_factory_(this) {}
415 MockDemuxerAndroid::~MockDemuxerAndroid() {
416 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__
;
417 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
419 if (!demuxer_deleted_cb_
.is_null())
420 ui_message_loop_
->PostTask(FROM_HERE
, demuxer_deleted_cb_
);
423 void MockDemuxerAndroid::Initialize(DemuxerAndroidClient
* client
) {
424 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__
;
425 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
428 if (pending_configs_
)
429 client_
->OnDemuxerConfigsAvailable(*pending_configs_
);
432 void MockDemuxerAndroid::RequestDemuxerData(DemuxerStream::Type type
) {
433 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
436 base::TimeDelta delay
;
438 bool created
= false;
439 if (type
== DemuxerStream::AUDIO
&& audio_factory_
)
440 created
= audio_factory_
->CreateChunk(&chunk
, &delay
);
441 else if (type
== DemuxerStream::VIDEO
&& video_factory_
)
442 created
= video_factory_
->CreateChunk(&chunk
, &delay
);
447 // Request key frame after |kConfigChanged|
448 if (type
== DemuxerStream::VIDEO
&& !chunk
.demuxer_configs
.empty())
449 video_factory_
->RequestKeyFrame();
453 // Post to the Media thread. Use the weak pointer to prevent the data arrival
454 // after the player has been deleted.
455 GetMediaTaskRunner()->PostDelayedTask(
456 FROM_HERE
, base::Bind(&MockDemuxerAndroid::OnDemuxerDataAvailable
,
457 weak_factory_
.GetWeakPtr(), chunk
),
461 void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta
& seek_request
,
462 bool is_browser_seek
) {
463 // Tell data factories to start next chunk with the new timestamp.
464 if (audio_factory_
) {
465 base::TimeDelta time_to_seek
=
466 std::max(base::TimeDelta(), seek_request
- audio_preroll_interval_
);
467 audio_factory_
->SeekTo(time_to_seek
);
469 if (video_factory_
) {
470 base::TimeDelta time_to_seek
=
471 std::max(base::TimeDelta(), seek_request
- video_preroll_interval_
);
472 video_factory_
->SeekTo(time_to_seek
);
473 video_factory_
->RequestKeyFrame();
478 ++num_browser_seeks_
;
480 // Post OnDemuxerSeekDone() to the player.
482 base::TimeDelta reported_seek_time
=
483 is_browser_seek
? seek_request
: kNoTimestamp();
484 GetMediaTaskRunner()->PostDelayedTask(
485 FROM_HERE
, base::Bind(&MockDemuxerAndroid::OnDemuxerSeekDone
,
486 weak_factory_
.GetWeakPtr(), reported_seek_time
),
490 void MockDemuxerAndroid::OnDemuxerDataAvailable(const DemuxerData
& chunk
) {
491 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
493 client_
->OnDemuxerDataAvailable(chunk
);
496 void MockDemuxerAndroid::OnDemuxerSeekDone(base::TimeDelta reported_seek_time
) {
497 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
499 client_
->OnDemuxerSeekDone(reported_seek_time
);
502 void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs
& configs
) {
503 RUN_ON_MEDIA_THREAD(MockDemuxerAndroid
, PostConfigs
, configs
);
505 DVLOG(1) << "MockDemuxerAndroid::" << __FUNCTION__
;
507 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
510 client_
->OnDemuxerConfigsAvailable(configs
);
512 pending_configs_
= scoped_ptr
<DemuxerConfigs
>(new DemuxerConfigs(configs
));
515 void MockDemuxerAndroid::PostInternalConfigs() {
516 ASSERT_TRUE(audio_factory_
|| video_factory_
);
518 if (audio_factory_
&& video_factory_
) {
520 CreateAudioVideoConfigs(audio_factory_
.get(), video_factory_
.get()));
521 } else if (audio_factory_
) {
522 PostConfigs(audio_factory_
->GetConfigs());
523 } else if (video_factory_
) {
524 PostConfigs(video_factory_
->GetConfigs());
528 } // namespace (anonymous)
530 // The test fixture for MediaCodecPlayer
532 class MediaCodecPlayerTest
: public testing::Test
{
534 MediaCodecPlayerTest();
536 // Conditions to wait for.
537 bool IsPaused() const { return !(player_
&& player_
->IsPlaying()); }
540 typedef base::Callback
<bool()> Predicate
;
542 void TearDown() override
;
545 void SetVideoSurface();
546 void SetVideoSurfaceB();
547 void RemoveVideoSurface();
549 // Waits for condition to become true or for timeout to expire.
550 // Returns true if the condition becomes true.
551 bool WaitForCondition(const Predicate
& condition
,
552 const base::TimeDelta
& timeout
= kDefaultTimeout
);
554 // Waits for timeout to expire.
555 void WaitForDelay(const base::TimeDelta
& timeout
);
557 // Waits till playback position as determined by maximal reported pts
558 // reaches the given value or for timeout to expire. Returns true if the
559 // playback has passed the given position.
560 bool WaitForPlaybackBeyondPosition(
561 const base::TimeDelta
& pts
,
562 const base::TimeDelta
& timeout
= kDefaultTimeout
);
564 // Helper method that starts video only stream. Waits till it actually
566 bool StartVideoPlayback(base::TimeDelta duration
, const char* test_name
);
568 // Helper method that starts audio and video streams.
569 bool StartAVPlayback(scoped_ptr
<AudioFactory
> audio_factory
,
570 scoped_ptr
<VideoFactory
> video_factory
,
572 const char* test_name
);
574 // Helper method that starts audio and video streams with preroll.
575 // The preroll is achieved by setting significant video preroll interval
576 // so video will have to catch up with audio. To make room for this interval
577 // the Start() command is preceded by SeekTo().
578 bool StartAVSeekAndPreroll(scoped_ptr
<AudioFactory
> audio_factory
,
579 scoped_ptr
<VideoFactory
> video_factory
,
580 base::TimeDelta seek_position
,
582 const char* test_name
);
584 // Callback sent when demuxer is being deleted.
585 void OnDemuxerDeleted() { demuxer_
= nullptr; }
587 bool IsDemuxerDeleted() const { return !demuxer_
; }
589 base::MessageLoop message_loop_
;
590 MockMediaPlayerManager manager_
;
591 MockDemuxerAndroid
* demuxer_
; // owned by player_
592 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_a_
;
593 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_b_
;
594 MediaCodecPlayer
* player_
; // raw pointer due to DeleteOnCorrectThread()
597 bool is_timeout_expired() const { return is_timeout_expired_
; }
598 void SetTimeoutExpired(bool value
) { is_timeout_expired_
= value
; }
600 bool is_timeout_expired_
;
602 DISALLOW_COPY_AND_ASSIGN(MediaCodecPlayerTest
);
605 MediaCodecPlayerTest::MediaCodecPlayerTest()
606 : demuxer_(new MockDemuxerAndroid(&message_loop_
)),
608 is_timeout_expired_(false) {}
610 void MediaCodecPlayerTest::TearDown() {
611 DVLOG(1) << __FUNCTION__
;
613 // Wait till the player is destroyed on the Media thread.
616 // The player deletes the demuxer on the Media thread. The demuxer's
617 // destructor sends a notification to the UI thread. When this notification
618 // arrives we can conclude that player started destroying its member
619 // variables. By that time the media codecs should have been released.
622 demuxer_
->SetDemuxerDeletedCallback(base::Bind(
623 &MediaCodecPlayerTest::OnDemuxerDeleted
, base::Unretained(this)));
625 player_
->DeleteOnCorrectThread();
628 WaitForCondition(base::Bind(&MediaCodecPlayerTest::IsDemuxerDeleted
,
629 base::Unretained(this)),
630 base::TimeDelta::FromMilliseconds(500)));
636 void MediaCodecPlayerTest::CreatePlayer() {
638 player_
= new MediaCodecPlayer(
640 manager_
.GetWeakPtr(),
641 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested
,
642 base::Unretained(&manager_
)),
643 scoped_ptr
<MockDemuxerAndroid
>(demuxer_
), GURL());
648 void MediaCodecPlayerTest::SetVideoSurface() {
649 surface_texture_a_
= gfx::SurfaceTexture::Create(0);
650 gfx::ScopedJavaSurface
surface(surface_texture_a_
.get());
652 ASSERT_NE(nullptr, player_
);
653 player_
->SetVideoSurface(surface
.Pass());
656 void MediaCodecPlayerTest::SetVideoSurfaceB() {
657 surface_texture_b_
= gfx::SurfaceTexture::Create(1);
658 gfx::ScopedJavaSurface
surface(surface_texture_b_
.get());
660 ASSERT_NE(nullptr, player_
);
661 player_
->SetVideoSurface(surface
.Pass());
664 void MediaCodecPlayerTest::RemoveVideoSurface() {
665 player_
->SetVideoSurface(gfx::ScopedJavaSurface());
666 surface_texture_a_
= NULL
;
669 bool MediaCodecPlayerTest::WaitForCondition(const Predicate
& condition
,
670 const base::TimeDelta
& timeout
) {
671 // Let the message_loop_ process events.
672 // We start the timer and RunUntilIdle() until it signals.
674 SetTimeoutExpired(false);
676 base::Timer
timer(false, false);
677 timer
.Start(FROM_HERE
, timeout
,
678 base::Bind(&MediaCodecPlayerTest::SetTimeoutExpired
,
679 base::Unretained(this), true));
682 if (condition
.Run()) {
686 message_loop_
.RunUntilIdle();
687 } while (!is_timeout_expired());
689 DCHECK(!timer
.IsRunning());
693 void MediaCodecPlayerTest::WaitForDelay(const base::TimeDelta
& timeout
) {
694 WaitForCondition(base::Bind(&AlwaysFalse
), timeout
);
697 bool MediaCodecPlayerTest::WaitForPlaybackBeyondPosition(
698 const base::TimeDelta
& pts
,
699 const base::TimeDelta
& timeout
) {
700 return WaitForCondition(
701 base::Bind(&MockMediaPlayerManager::IsPlaybackBeyondPosition
,
702 base::Unretained(&manager_
), pts
),
706 bool MediaCodecPlayerTest::StartVideoPlayback(base::TimeDelta duration
,
707 const char* test_name
) {
708 const base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
710 demuxer_
->SetVideoFactory(
711 scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
715 // Wait till the player is initialized on media thread.
716 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
717 base::Unretained(demuxer_
))));
719 if (!demuxer_
->IsInitialized()) {
720 DVLOG(0) << test_name
<< ": demuxer is not initialized";
726 // Post configuration after the player has been initialized.
727 demuxer_
->PostInternalConfigs();
730 EXPECT_FALSE(manager_
.IsPlaybackStarted());
733 // Wait for playback to start.
735 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
736 base::Unretained(&manager_
)),
739 if (!manager_
.IsPlaybackStarted()) {
740 DVLOG(0) << test_name
<< ": playback did not start";
747 bool MediaCodecPlayerTest::StartAVPlayback(
748 scoped_ptr
<AudioFactory
> audio_factory
,
749 scoped_ptr
<VideoFactory
> video_factory
,
751 const char* test_name
) {
752 demuxer_
->SetAudioFactory(audio_factory
.Pass());
753 demuxer_
->SetVideoFactory(video_factory
.Pass());
758 // Wait till the player is initialized on media thread.
759 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
760 base::Unretained(demuxer_
))));
762 if (!demuxer_
->IsInitialized()) {
763 DVLOG(0) << test_name
<< ": demuxer is not initialized";
767 // Ask decoders to always reconfigure after the player has been initialized.
768 if (flags
& kAlwaysReconfigAudio
)
769 player_
->SetAlwaysReconfigureForTests(DemuxerStream::AUDIO
);
770 if (flags
& kAlwaysReconfigVideo
)
771 player_
->SetAlwaysReconfigureForTests(DemuxerStream::VIDEO
);
773 // Set a testing callback to receive PTS from decoders.
774 player_
->SetDecodersTimeCallbackForTests(
775 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
776 base::Unretained(&manager_
)));
778 // Set a testing callback to receive MediaCodec creation events from decoders.
779 player_
->SetCodecCreatedCallbackForTests(
780 base::Bind(&MockMediaPlayerManager::OnMediaCodecCreated
,
781 base::Unretained(&manager_
)));
783 // Post configuration after the player has been initialized.
784 demuxer_
->PostInternalConfigs();
786 // Start and wait for playback.
789 // Wait till we start to play.
790 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(2000);
793 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
794 base::Unretained(&manager_
)),
797 if (!manager_
.IsPlaybackStarted()) {
798 DVLOG(0) << test_name
<< ": playback did not start";
805 bool MediaCodecPlayerTest::StartAVSeekAndPreroll(
806 scoped_ptr
<AudioFactory
> audio_factory
,
807 scoped_ptr
<VideoFactory
> video_factory
,
808 base::TimeDelta seek_position
,
810 const char* test_name
) {
811 // Initialize A/V playback
813 demuxer_
->SetAudioFactory(audio_factory
.Pass());
814 demuxer_
->SetVideoFactory(video_factory
.Pass());
819 // Wait till the player is initialized on media thread.
820 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
821 base::Unretained(demuxer_
))));
823 if (!demuxer_
->IsInitialized()) {
824 DVLOG(0) << test_name
<< ": demuxer is not initialized";
828 // Ask decoders to always reconfigure after the player has been initialized.
829 if (flags
& kAlwaysReconfigAudio
)
830 player_
->SetAlwaysReconfigureForTests(DemuxerStream::AUDIO
);
831 if (flags
& kAlwaysReconfigVideo
)
832 player_
->SetAlwaysReconfigureForTests(DemuxerStream::VIDEO
);
834 // Set a testing callback to receive PTS from decoders.
835 player_
->SetDecodersTimeCallbackForTests(
836 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
837 base::Unretained(&manager_
)));
839 // Set a testing callback to receive MediaCodec creation events from decoders.
840 player_
->SetCodecCreatedCallbackForTests(
841 base::Bind(&MockMediaPlayerManager::OnMediaCodecCreated
,
842 base::Unretained(&manager_
)));
844 // Post configuration after the player has been initialized.
845 demuxer_
->PostInternalConfigs();
848 player_
->SeekTo(seek_position
);
850 // Start the playback.
853 // Wait till preroll starts.
854 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(2000);
855 EXPECT_TRUE(WaitForCondition(
856 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
857 base::Unretained(player_
), DemuxerStream::VIDEO
),
860 if (!player_
->IsPrerollingForTests(DemuxerStream::VIDEO
)) {
861 DVLOG(0) << test_name
<< ": preroll did not happen for video";
868 TEST_F(MediaCodecPlayerTest
, SetAudioConfigsBeforePlayerCreation
) {
869 // Post configuration when there is no player yet.
870 EXPECT_EQ(nullptr, player_
);
872 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
874 demuxer_
->PostConfigs(
875 TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration
));
877 // Wait until the configuration gets to the media thread.
878 EXPECT_TRUE(WaitForCondition(base::Bind(
879 &MockDemuxerAndroid::HasPendingConfigs
, base::Unretained(demuxer_
))));
881 // Then create the player.
884 // Configuration should propagate through the player and to the manager.
886 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged
,
887 base::Unretained(&manager_
))));
889 EXPECT_EQ(duration
, manager_
.media_metadata_
.duration
);
890 EXPECT_EQ(0, manager_
.media_metadata_
.width
);
891 EXPECT_EQ(0, manager_
.media_metadata_
.height
);
894 TEST_F(MediaCodecPlayerTest
, SetAudioConfigsAfterPlayerCreation
) {
897 // Wait till the player is initialized on media thread.
898 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
899 base::Unretained(demuxer_
))));
901 // Post configuration after the player has been initialized.
902 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
903 demuxer_
->PostConfigs(
904 TestDataFactory::CreateAudioConfigs(kCodecAAC
, duration
));
906 // Configuration should propagate through the player and to the manager.
908 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged
,
909 base::Unretained(&manager_
))));
911 EXPECT_EQ(duration
, manager_
.media_metadata_
.duration
);
912 EXPECT_EQ(0, manager_
.media_metadata_
.width
);
913 EXPECT_EQ(0, manager_
.media_metadata_
.height
);
916 TEST_F(MediaCodecPlayerTest
, SetAudioVideoConfigsAfterPlayerCreation
) {
919 // Wait till the player is initialized on media thread.
920 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
921 base::Unretained(demuxer_
))));
923 // Post configuration after the player has been initialized.
924 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
925 demuxer_
->PostConfigs(CreateAudioVideoConfigs(duration
, gfx::Size(320, 240)));
927 // Configuration should propagate through the player and to the manager.
929 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsMetadataChanged
,
930 base::Unretained(&manager_
))));
932 EXPECT_EQ(duration
, manager_
.media_metadata_
.duration
);
933 EXPECT_EQ(320, manager_
.media_metadata_
.width
);
934 EXPECT_EQ(240, manager_
.media_metadata_
.height
);
937 TEST_F(MediaCodecPlayerTest
, AudioPlayTillCompletion
) {
938 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
940 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
941 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(2000);
943 demuxer_
->SetAudioFactory(
944 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
948 // Wait till the player is initialized on media thread.
949 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
950 base::Unretained(demuxer_
))));
952 // Post configuration after the player has been initialized.
953 demuxer_
->PostInternalConfigs();
955 EXPECT_FALSE(manager_
.IsPlaybackCompleted());
960 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
961 base::Unretained(&manager_
)),
964 // Current timestamp reflects "now playing" time. It might come with delay
965 // relative to the frame's PTS. Allow for 100 ms delay here.
966 base::TimeDelta audio_pts_delay
= base::TimeDelta::FromMilliseconds(100);
967 EXPECT_LT(duration
- audio_pts_delay
, manager_
.pts_stat_
.max());
970 TEST_F(MediaCodecPlayerTest
, VideoPlayTillCompletion
) {
971 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
973 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(500);
974 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(2000);
976 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoPlayTillCompletion"));
978 // Wait till completion.
980 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
981 base::Unretained(&manager_
)),
984 EXPECT_LE(duration
, manager_
.pts_stat_
.max());
987 // http://crbug.com/518900
988 TEST_F(MediaCodecPlayerTest
, AudioSeekAfterStop
) {
989 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
991 // Play for 300 ms, then Pause, then Seek to beginning. The playback should
992 // start from the beginning.
994 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
996 demuxer_
->SetAudioFactory(
997 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1001 // Post configuration.
1002 demuxer_
->PostInternalConfigs();
1004 // Start the player.
1007 // Wait for playback to start.
1009 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1010 base::Unretained(&manager_
))));
1012 // Wait for 300 ms and stop. The 300 ms interval takes into account potential
1013 // audio delay: audio takes time reconfiguring after the first several packets
1014 // get written to the audio track.
1015 WaitForDelay(base::TimeDelta::FromMilliseconds(300));
1017 player_
->Pause(true);
1019 // Make sure we played at least 100 ms.
1020 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1022 // Wait till the Pause is completed.
1023 EXPECT_TRUE(WaitForCondition(
1024 base::Bind(&MediaCodecPlayerTest::IsPaused
, base::Unretained(this))));
1026 // Clear statistics.
1027 manager_
.pts_stat_
.Clear();
1029 // Now we can seek to the beginning and start the playback.
1030 player_
->SeekTo(base::TimeDelta());
1034 // Wait for playback to start.
1036 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1037 base::Unretained(&manager_
))));
1039 // Make sure we started from the beginninig
1040 EXPECT_GT(base::TimeDelta::FromMilliseconds(40), manager_
.pts_stat_
.min());
1042 // The player should have reported the seek completion to the manager.
1043 EXPECT_TRUE(WaitForCondition(base::Bind(
1044 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1047 TEST_F(MediaCodecPlayerTest
, AudioSeekThenPlay
) {
1048 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1050 // Issue Seek command immediately followed by Start. The playback should
1051 // start at the seek position.
1053 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1054 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(500);
1056 demuxer_
->SetAudioFactory(
1057 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1061 // Post configuration.
1062 demuxer_
->PostInternalConfigs();
1064 // Seek and immediately start.
1065 player_
->SeekTo(seek_position
);
1068 // Wait for playback to start.
1070 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1071 base::Unretained(&manager_
))));
1073 // The playback should start at |seek_position|
1074 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1076 // The player should have reported the seek completion to the manager.
1077 EXPECT_TRUE(WaitForCondition(base::Bind(
1078 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1081 TEST_F(MediaCodecPlayerTest
, AudioSeekThenPlayThenConfig
) {
1082 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1084 // Issue Seek command immediately followed by Start but without prior demuxer
1085 // configuration. Start should wait for configuration. After it has been
1086 // posted the playback should start at the seek position.
1088 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1089 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(500);
1091 demuxer_
->SetAudioFactory(
1092 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1096 // Seek and immediately start.
1097 player_
->SeekTo(seek_position
);
1100 // Make sure the player is waiting.
1101 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1102 EXPECT_FALSE(player_
->IsPlaying());
1104 // Post configuration.
1105 demuxer_
->PostInternalConfigs();
1107 // Wait for playback to start.
1109 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1110 base::Unretained(&manager_
))));
1112 // The playback should start at |seek_position|
1113 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1115 // The player should have reported the seek completion to the manager.
1116 EXPECT_TRUE(WaitForCondition(base::Bind(
1117 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1120 // http://crbug.com/518900
1121 TEST_F(MediaCodecPlayerTest
, AudioSeekWhilePlaying
) {
1122 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1124 // Play for 300 ms, then issue several Seek commands in the row.
1125 // The playback should continue at the last seek position.
1127 // To test this condition without analyzing the reported time details
1128 // and without introducing dependency on implementation I make a long (10s)
1129 // duration and test that the playback resumes after big time jump (5s) in a
1130 // short period of time (200 ms).
1131 base::TimeDelta duration
= base::TimeDelta::FromSeconds(10);
1133 demuxer_
->SetAudioFactory(
1134 scoped_ptr
<AudioFactory
>(new AudioFactory(duration
)));
1138 // Post configuration.
1139 demuxer_
->PostInternalConfigs();
1141 // Start the player.
1144 // Wait for playback to start.
1146 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1147 base::Unretained(&manager_
))));
1150 WaitForDelay(base::TimeDelta::FromMilliseconds(300));
1152 // Make sure we played at least 100 ms.
1153 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1155 // Seek forward several times.
1156 player_
->SeekTo(base::TimeDelta::FromSeconds(3));
1157 player_
->SeekTo(base::TimeDelta::FromSeconds(4));
1158 player_
->SeekTo(base::TimeDelta::FromSeconds(5));
1160 // Make sure that we reached the last timestamp within default timeout,
1162 EXPECT_TRUE(WaitForPlaybackBeyondPosition(base::TimeDelta::FromSeconds(5)));
1163 EXPECT_TRUE(player_
->IsPlaying());
1165 // The player should have reported the seek completion to the manager.
1166 EXPECT_TRUE(WaitForCondition(base::Bind(
1167 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1170 TEST_F(MediaCodecPlayerTest
, VideoReplaceSurface
) {
1171 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1173 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
1174 base::TimeDelta timeout
= base::TimeDelta::FromMilliseconds(1500);
1176 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoReplaceSurface"));
1178 // Wait for some time and check statistics.
1179 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1181 // Make sure we played at least 100 ms.
1182 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1184 // Set new video surface without removing the old one.
1187 // We should receive a browser seek request.
1188 EXPECT_TRUE(WaitForCondition(
1189 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest
,
1190 base::Unretained(demuxer_
))));
1192 // Playback should continue with a new surface. Wait till completion.
1194 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1195 base::Unretained(&manager_
)),
1197 EXPECT_LE(duration
, manager_
.pts_stat_
.max());
1200 TEST_F(MediaCodecPlayerTest
, VideoRemoveAndSetSurface
) {
1201 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1203 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
1205 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoRemoveAndSetSurface"));
1207 // Wait for some time and check statistics.
1208 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1210 // Make sure we played at least 100 ms.
1211 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1213 // Remove video surface.
1214 RemoveVideoSurface();
1216 // We should be stuck waiting for the new surface.
1217 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1218 EXPECT_FALSE(player_
->IsPlaying());
1220 // Save last PTS and clear statistics.
1221 base::TimeDelta max_pts_before_removal
= manager_
.pts_stat_
.max();
1222 manager_
.pts_stat_
.Clear();
1224 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1225 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1227 // Extra RemoveVideoSurface() should not change anything.
1228 RemoveVideoSurface();
1230 // Set another video surface.
1233 // We should receive a browser seek request.
1234 EXPECT_TRUE(WaitForCondition(
1235 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest
,
1236 base::Unretained(demuxer_
))));
1238 // Playback should continue with a new surface. Wait till it starts again.
1239 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(800);
1241 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1242 base::Unretained(&manager_
)),
1243 reconfigure_timeout
));
1245 // Timestamps should not go back.
1246 EXPECT_LE(max_pts_before_removal
, manager_
.pts_stat_
.max());
1249 // http://crbug.com/518900
1250 TEST_F(MediaCodecPlayerTest
, VideoReleaseAndStart
) {
1251 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1253 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1000);
1255 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoReleaseAndStart"));
1257 // Wait for some time and check statistics.
1258 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1260 // Make sure we played at least 100 ms.
1261 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1263 // When the user presses Tasks button Chrome calls Pause() and Release().
1264 player_
->Pause(true);
1267 // Make sure we are not playing any more.
1268 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1269 EXPECT_FALSE(player_
->IsPlaying());
1271 // Save last PTS and clear statistics.
1272 base::TimeDelta max_pts_before_backgrounding
= manager_
.pts_stat_
.max();
1273 manager_
.pts_stat_
.Clear();
1275 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1276 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1282 // We should receive a browser seek request.
1283 EXPECT_TRUE(WaitForCondition(
1284 base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest
,
1285 base::Unretained(demuxer_
))));
1287 // Wait for playback to start again.
1288 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(800);
1290 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1291 base::Unretained(&manager_
)),
1292 reconfigure_timeout
));
1294 // Timestamps should not go back.
1295 EXPECT_LE(max_pts_before_backgrounding
, manager_
.pts_stat_
.max());
1298 TEST_F(MediaCodecPlayerTest
, VideoSeekAndRelease
) {
1299 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1301 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1302 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1304 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoSeekAndRelease"));
1306 // Wait for some time and check statistics.
1307 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1309 // Make sure we played at least 100 ms.
1310 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1312 // Issue SeekTo() immediately followed by Release().
1313 player_
->SeekTo(seek_position
);
1316 // Make sure we are not playing any more.
1317 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1318 EXPECT_FALSE(player_
->IsPlaying());
1320 // The Release() should not cancel the SeekTo() and we should have received
1321 // the seek request by this time.
1322 EXPECT_TRUE(demuxer_
->ReceivedSeekRequest());
1324 // The player should have reported the seek completion to the manager.
1325 EXPECT_TRUE(WaitForCondition(base::Bind(
1326 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1328 // Clear statistics.
1329 manager_
.pts_stat_
.Clear();
1331 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1332 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1338 // Wait for playback to start again.
1339 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(800);
1341 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1342 base::Unretained(&manager_
)),
1343 reconfigure_timeout
));
1345 // Timestamps should start at the new seek position
1346 EXPECT_LE(seek_position
, manager_
.pts_stat_
.min());
1349 TEST_F(MediaCodecPlayerTest
, VideoReleaseWhileWaitingForSeek
) {
1350 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1352 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1353 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1355 ASSERT_TRUE(StartVideoPlayback(duration
, "VideoReleaseWhileWaitingForSeek"));
1357 // Wait for some time and check statistics.
1358 WaitForDelay(base::TimeDelta::FromMilliseconds(200));
1360 // Make sure we played at least 100 ms.
1361 EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_
.pts_stat_
.max());
1363 // Set artificial delay in the OnDemuxerSeekDone response so we can
1364 // issue commands while the player is in the STATE_WAITING_FOR_SEEK.
1365 demuxer_
->SetSeekDoneDelay(base::TimeDelta::FromMilliseconds(100));
1368 player_
->SeekTo(seek_position
);
1370 // Wait for the seek request to demuxer.
1371 EXPECT_TRUE(WaitForCondition(base::Bind(
1372 &MockDemuxerAndroid::ReceivedSeekRequest
, base::Unretained(demuxer_
))));
1374 // The player is supposed to be in STATE_WAITING_FOR_SEEK. Issue Release().
1377 // Make sure we are not playing any more.
1378 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1379 EXPECT_FALSE(player_
->IsPlaying());
1381 // Clear statistics.
1382 manager_
.pts_stat_
.Clear();
1384 // After clearing statistics we are ready to wait for IsPlaybackStarted again.
1385 EXPECT_FALSE(manager_
.IsPlaybackStarted());
1391 // Wait for playback to start again.
1392 base::TimeDelta reconfigure_timeout
= base::TimeDelta::FromMilliseconds(1000);
1394 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1395 base::Unretained(&manager_
)),
1396 reconfigure_timeout
));
1398 // Timestamps should start at the new seek position
1399 EXPECT_LE(seek_position
, manager_
.pts_stat_
.min());
1401 // The player should have reported the seek completion to the manager.
1402 EXPECT_TRUE(WaitForCondition(base::Bind(
1403 &MockMediaPlayerManager::IsSeekCompleted
, base::Unretained(&manager_
))));
1406 TEST_F(MediaCodecPlayerTest
, VideoPrerollAfterSeek
) {
1407 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1409 // A simple test for preroll for video stream only. After the seek is done
1410 // the data factory generates the frames with pts before the seek time, and
1411 // they should not be rendered. We deduce which frame is rendered by looking
1412 // at the reported time progress.
1414 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(600);
1415 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(500);
1416 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1418 // Tell demuxer to make the first frame 100ms earlier than the seek request.
1419 demuxer_
->SetVideoPrerollInterval(base::TimeDelta::FromMilliseconds(100));
1421 demuxer_
->SetVideoFactory(
1422 scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
1427 // Wait till the player is initialized on media thread.
1428 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
1429 base::Unretained(demuxer_
))));
1430 if (!demuxer_
->IsInitialized()) {
1431 DVLOG(0) << "VideoPrerollAfterSeek: demuxer is not initialized";
1435 // Post configuration after the player has been initialized.
1436 demuxer_
->PostInternalConfigs();
1439 player_
->SeekTo(seek_position
);
1441 // Start the playback and make sure it is started.
1445 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1446 base::Unretained(&manager_
)),
1449 // Wait for completion.
1451 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1452 base::Unretained(&manager_
))));
1454 // The first pts should be equal than seek position even if video frames
1455 // started 100 ms eralier than the seek request.
1456 EXPECT_EQ(seek_position
, manager_
.pts_stat_
.min());
1458 EXPECT_EQ(6, manager_
.pts_stat_
.num_values());
1461 TEST_F(MediaCodecPlayerTest
, AVPrerollAudioWaitsForVideo
) {
1462 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1464 // Test that during prerolling neither audio nor video plays and that both
1465 // resume simultaneously after preroll is finished. In other words, test
1466 // that preroll works.
1467 // We put the video into the long preroll and intercept the time when first
1468 // rendering happens in each stream. The moment of rendering is approximated
1469 // with a decoder PTS that is delivered by a test-only callback.
1471 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1473 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1474 // per frame it would take 250 ms to preroll.
1475 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1476 base::TimeDelta preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
1477 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(1000);
1479 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1480 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1482 demuxer_
->SetVideoPrerollInterval(preroll_intvl
);
1484 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
1486 "AVPrerollAudioWaitsForVideo"));
1488 // Wait till preroll finishes and the real playback starts.
1490 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1491 base::Unretained(&manager_
)),
1494 // Ensure that the first audio and video pts are close to each other and are
1495 // reported at the close moments in time.
1497 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1498 EXPECT_TRUE(WaitForCondition(
1499 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
1500 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
1502 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
1503 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
1505 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
1506 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
1508 // The playback should start at |seek_position|
1509 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1512 TEST_F(MediaCodecPlayerTest
, AVPrerollReleaseAndRestart
) {
1513 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1515 // Test that player will resume prerolling if prerolling is interrupted by
1516 // Release() and Start().
1518 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(2000);
1520 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1521 // per frame it would take 250 ms to preroll.
1522 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1523 base::TimeDelta preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
1525 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1526 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(1000);
1528 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1529 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1531 demuxer_
->SetVideoPrerollInterval(preroll_intvl
);
1533 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
1535 "AVPrerollReleaseAndRestart"));
1540 // Make sure we have not been playing.
1541 WaitForDelay(base::TimeDelta::FromMilliseconds(400));
1543 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1544 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1546 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::AUDIO
));
1547 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::VIDEO
));
1548 EXPECT_EQ(0, manager_
.pts_stat_
.num_values());
1550 // Restart. Release() removed the video surface, we need to set it again.
1554 // The playback should pass through prerolling phase.
1555 EXPECT_TRUE(WaitForCondition(
1556 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
1557 base::Unretained(player_
), DemuxerStream::VIDEO
),
1560 // Wait till preroll finishes and the real playback starts.
1562 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1563 base::Unretained(&manager_
)),
1566 // Ensure that the first audio and video pts are close to each other and are
1567 // reported at the close moments in time.
1569 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1570 EXPECT_TRUE(WaitForCondition(
1571 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
1572 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
1574 // Release() might disacrd first audio frame.
1575 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
1576 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 50));
1578 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
1579 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
1581 // The playback should start at |seek_position|, but Release() might discard
1582 // the first audio frame.
1583 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 50));
1586 TEST_F(MediaCodecPlayerTest
, AVPrerollStopAndRestart
) {
1587 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1589 // Test that if Pause() happens during the preroll phase,
1590 // we continue to do preroll after restart.
1592 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1594 // Set significant preroll interval. 500 ms means 25 frames, at 10 ms
1595 // per frame it would take 250 ms to preroll.
1596 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1597 base::TimeDelta preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
1599 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1600 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(1000);
1602 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1603 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1605 demuxer_
->SetVideoPrerollInterval(preroll_intvl
);
1607 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
1609 "AVPrerollStopAndRestart"));
1611 // Video stream should be prerolling. Request to stop.
1612 EXPECT_FALSE(IsPaused());
1613 player_
->Pause(true);
1615 EXPECT_TRUE(WaitForCondition(
1616 base::Bind(&MediaCodecPlayerTest::IsPaused
, base::Unretained(this))));
1618 // Test that we have not been playing.
1619 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1620 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1622 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::AUDIO
));
1623 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::VIDEO
));
1624 EXPECT_EQ(0, manager_
.pts_stat_
.num_values());
1629 // There should be preroll after the start.
1630 EXPECT_TRUE(WaitForCondition(
1631 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
1632 base::Unretained(player_
), DemuxerStream::VIDEO
),
1635 // Wait for a short period of time, so that preroll is still ongoing,
1637 WaitForDelay(base::TimeDelta::FromMilliseconds(100));
1639 EXPECT_FALSE(IsPaused());
1640 player_
->Pause(true);
1642 EXPECT_TRUE(WaitForCondition(
1643 base::Bind(&MediaCodecPlayerTest::IsPaused
, base::Unretained(this))));
1645 // Check that we still haven't started rendering.
1646 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1647 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1649 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::AUDIO
));
1650 EXPECT_FALSE(player_
->IsPrerollingForTests(DemuxerStream::VIDEO
));
1651 EXPECT_EQ(0, manager_
.pts_stat_
.num_values());
1656 // Wait till we start to play.
1658 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1659 base::Unretained(&manager_
)),
1662 // Check that we did prerolling, i.e. audio did wait for video.
1663 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1664 EXPECT_TRUE(WaitForCondition(
1665 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
1666 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
1668 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
1669 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
1671 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
1672 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
1674 // The playback should start at |seek_position|
1675 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
1678 TEST_F(MediaCodecPlayerTest
, AVPrerollVideoEndsWhilePrerolling
) {
1679 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1681 // Test that when one stream ends in the preroll phase and another is not
1682 // the preroll finishes and playback continues after it.
1684 // http://crbug.com/526755
1685 // TODO(timav): remove these logs after verifying that the bug is fixed.
1686 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: begin";
1688 base::TimeDelta audio_duration
= base::TimeDelta::FromMilliseconds(1100);
1689 base::TimeDelta video_duration
= base::TimeDelta::FromMilliseconds(900);
1690 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
1691 base::TimeDelta video_preroll_intvl
= base::TimeDelta::FromMilliseconds(200);
1693 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(800);
1694 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(400);
1696 demuxer_
->SetVideoPrerollInterval(video_preroll_intvl
);
1698 demuxer_
->SetAudioFactory(
1699 scoped_ptr
<AudioFactory
>(new AudioFactory(audio_duration
)));
1700 demuxer_
->SetVideoFactory(
1701 scoped_ptr
<VideoFactory
>(new VideoFactory(video_duration
)));
1706 // Set special testing callback to receive PTS from decoders.
1707 player_
->SetDecodersTimeCallbackForTests(
1708 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
1709 base::Unretained(&manager_
)));
1711 // Wait till the player is initialized on media thread.
1712 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
1713 base::Unretained(demuxer_
))));
1715 if (!demuxer_
->IsInitialized()) {
1716 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: demuxer is not initialized";
1720 // Post configuration after the player has been initialized.
1721 demuxer_
->PostInternalConfigs();
1724 player_
->SeekTo(seek_position
);
1726 // Start the playback.
1729 // The video decoder should start prerolling.
1730 // Wait till preroll starts.
1731 EXPECT_TRUE(WaitForCondition(
1732 base::Bind(&MediaCodecPlayer::IsPrerollingForTests
,
1733 base::Unretained(player_
), DemuxerStream::VIDEO
),
1736 // Wait for playback to start.
1737 bool playback_started
=
1738 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1739 base::Unretained(&manager_
)),
1742 // http://crbug.com/526755
1743 if (!playback_started
) {
1744 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: playback did not start for "
1747 ASSERT_TRUE(playback_started
);
1749 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
1751 // Play till completion.
1753 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1754 base::Unretained(&manager_
))));
1756 // There should not be any video frames.
1757 EXPECT_FALSE(manager_
.HasFirstFrame(DemuxerStream::VIDEO
));
1759 // http://crbug.com/526755
1760 DVLOG(0) << "AVPrerollVideoEndsWhilePrerolling: end";
1763 TEST_F(MediaCodecPlayerTest
, VideoConfigChangeWhilePlaying
) {
1764 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1766 // Test that video only playback continues after video config change.
1768 // Initialize video playback
1769 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1770 base::TimeDelta config_change_position
=
1771 base::TimeDelta::FromMilliseconds(1000);
1773 base::TimeDelta start_timeout
= base::TimeDelta::FromMilliseconds(2000);
1774 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1776 demuxer_
->SetVideoFactory(
1777 scoped_ptr
<VideoFactory
>(new VideoFactory(duration
)));
1779 demuxer_
->video_factory()->RequestConfigChange(config_change_position
);
1784 // Wait till the player is initialized on media thread.
1785 EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized
,
1786 base::Unretained(demuxer_
))));
1788 if (!demuxer_
->IsInitialized()) {
1789 DVLOG(0) << "VideoConfigChangeWhilePlaying: demuxer is not initialized";
1793 // Ask decoders to always reconfigure after the player has been initialized.
1794 player_
->SetAlwaysReconfigureForTests(DemuxerStream::VIDEO
);
1796 // Set a testing callback to receive PTS from decoders.
1797 player_
->SetDecodersTimeCallbackForTests(
1798 base::Bind(&MockMediaPlayerManager::OnDecodersTimeUpdate
,
1799 base::Unretained(&manager_
)));
1801 // Set a testing callback to receive MediaCodec creation events from decoders.
1802 player_
->SetCodecCreatedCallbackForTests(
1803 base::Bind(&MockMediaPlayerManager::OnMediaCodecCreated
,
1804 base::Unretained(&manager_
)));
1806 // Post configuration after the player has been initialized.
1807 demuxer_
->PostInternalConfigs();
1809 // Start and wait for playback.
1812 // Wait till we start to play.
1814 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
1815 base::Unretained(&manager_
)),
1818 // Wait till completion
1820 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1821 base::Unretained(&manager_
)),
1822 completion_timeout
));
1824 // The video codec should be recreated upon config changes.
1825 EXPECT_EQ(2, manager_
.num_video_codecs_created());
1827 // Check that we did not miss video frames
1828 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
1829 EXPECT_EQ(expected_video_frames
,
1830 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
1833 TEST_F(MediaCodecPlayerTest
, AVVideoConfigChangeWhilePlaying
) {
1834 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1836 // Test that A/V playback continues after video config change.
1838 // Initialize A/V playback
1839 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1840 base::TimeDelta config_change_position
=
1841 base::TimeDelta::FromMilliseconds(1000);
1843 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1845 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1846 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1848 video_factory
->RequestConfigChange(config_change_position
);
1850 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
1851 kAlwaysReconfigVideo
,
1852 "AVVideoConfigChangeWhilePlaying"));
1854 // Wait till completion
1856 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1857 base::Unretained(&manager_
)),
1858 completion_timeout
));
1860 // The audio codec should be kept.
1861 EXPECT_EQ(1, manager_
.num_audio_codecs_created());
1863 // The video codec should be recreated upon config changes.
1864 EXPECT_EQ(2, manager_
.num_video_codecs_created());
1866 // Check that we did not miss video frames
1867 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
1868 EXPECT_EQ(expected_video_frames
,
1869 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
1871 // Check that we did not miss audio frames. We expect one postponed frames
1872 // that are not reported.
1873 // For Nexus 4 KitKat the AAC decoder seems to swallow the first frame
1874 // but reports the last pts twice, maybe it just shifts the reported PTS.
1875 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 0) - 1;
1876 EXPECT_EQ(expected_audio_frames
,
1877 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
1880 TEST_F(MediaCodecPlayerTest
, AVAudioConfigChangeWhilePlaying
) {
1881 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1883 // Test that A/V playback continues after audio config change.
1885 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1886 base::TimeDelta config_change_position
=
1887 base::TimeDelta::FromMilliseconds(1000);
1889 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1891 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1892 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1894 audio_factory
->RequestConfigChange(config_change_position
);
1896 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
1897 kAlwaysReconfigAudio
,
1898 "AVAudioConfigChangeWhilePlaying"));
1900 // Wait till completion
1902 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1903 base::Unretained(&manager_
)),
1904 completion_timeout
));
1906 // The audio codec should be recreated upon config changes.
1907 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
1909 // The video codec should be kept.
1910 EXPECT_EQ(1, manager_
.num_video_codecs_created());
1912 // Check that we did not miss video frames.
1913 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 0);
1914 EXPECT_EQ(expected_video_frames
,
1915 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
1917 // Check that we did not miss audio frames. We expect two postponed frames
1918 // that are not reported.
1919 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 1) - 2;
1920 EXPECT_EQ(expected_audio_frames
,
1921 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
1924 TEST_F(MediaCodecPlayerTest
, AVSimultaneousConfigChange_1
) {
1925 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1927 // Test that the playback continues if audio and video config changes happen
1928 // at the same time.
1930 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1931 base::TimeDelta config_change_audio
= base::TimeDelta::FromMilliseconds(1000);
1932 base::TimeDelta config_change_video
= base::TimeDelta::FromMilliseconds(1000);
1934 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1936 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1937 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1939 audio_factory
->RequestConfigChange(config_change_audio
);
1940 video_factory
->RequestConfigChange(config_change_video
);
1942 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
1943 kAlwaysReconfigAudio
| kAlwaysReconfigVideo
,
1944 "AVSimultaneousConfigChange_1"));
1946 // Wait till completion
1948 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1949 base::Unretained(&manager_
)),
1950 completion_timeout
));
1952 // The audio codec should be recreated upon config changes.
1953 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
1955 // The video codec should be recreated upon config changes.
1956 EXPECT_EQ(2, manager_
.num_video_codecs_created());
1958 // Check that we did not miss video frames.
1959 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
1960 EXPECT_EQ(expected_video_frames
,
1961 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
1963 // Check that we did not miss audio frames. We expect two postponed frames
1964 // that are not reported.
1965 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 1) - 2;
1966 EXPECT_EQ(expected_audio_frames
,
1967 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
1970 TEST_F(MediaCodecPlayerTest
, AVSimultaneousConfigChange_2
) {
1971 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1973 // Test that the playback continues if audio and video config changes happen
1974 // at the same time. Move audio change moment slightly to make it drained
1977 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
1978 base::TimeDelta config_change_audio
= base::TimeDelta::FromMilliseconds(1020);
1979 base::TimeDelta config_change_video
= base::TimeDelta::FromMilliseconds(1000);
1981 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
1983 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
1984 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
1986 audio_factory
->RequestConfigChange(config_change_audio
);
1987 video_factory
->RequestConfigChange(config_change_video
);
1989 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
1990 kAlwaysReconfigAudio
| kAlwaysReconfigVideo
,
1991 "AVSimultaneousConfigChange_2"));
1993 // Wait till completion
1995 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
1996 base::Unretained(&manager_
)),
1997 completion_timeout
));
1999 // The audio codec should be recreated upon config changes.
2000 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
2002 // The video codec should be recreated upon config changes.
2003 EXPECT_EQ(2, manager_
.num_video_codecs_created());
2005 // Check that we did not miss video frames.
2006 int expected_video_frames
= GetFrameCount(duration
, kVideoFramePeriod
, 1);
2007 EXPECT_EQ(expected_video_frames
,
2008 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
2010 // Check that we did not miss audio frames. We expect two postponed frames
2011 // that are not reported.
2012 int expected_audio_frames
= GetFrameCount(duration
, kAudioFramePeriod
, 1) - 2;
2013 EXPECT_EQ(expected_audio_frames
,
2014 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
2017 TEST_F(MediaCodecPlayerTest
, AVAudioEndsAcrossVideoConfigChange
) {
2018 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2020 // Test that audio can end while video config change processing.
2022 base::TimeDelta audio_duration
= base::TimeDelta::FromMilliseconds(1000);
2023 base::TimeDelta video_duration
= base::TimeDelta::FromMilliseconds(1200);
2024 base::TimeDelta config_change_video
= base::TimeDelta::FromMilliseconds(1000);
2026 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
2028 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(audio_duration
));
2029 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(video_duration
));
2031 video_factory
->RequestConfigChange(config_change_video
);
2033 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
2034 kAlwaysReconfigVideo
,
2035 "AVAudioEndsAcrossVideoConfigChange"));
2037 // Wait till completion
2039 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
2040 base::Unretained(&manager_
)),
2041 completion_timeout
));
2043 // The audio codec should not be recreated.
2044 EXPECT_EQ(1, manager_
.num_audio_codecs_created());
2046 // The video codec should be recreated upon config changes.
2047 EXPECT_EQ(2, manager_
.num_video_codecs_created());
2049 // Check that we did not miss video frames.
2050 int expected_video_frames
=
2051 GetFrameCount(video_duration
, kVideoFramePeriod
, 1);
2052 EXPECT_EQ(expected_video_frames
,
2053 manager_
.render_stat_
[DemuxerStream::VIDEO
].num_values());
2055 // Check the last video frame timestamp. The maximum render pts may differ
2056 // from |video_duration| because of the testing artefact: if the last video
2057 // chunk is incomplete if will have different last pts due to B-frames
2059 EXPECT_LE(video_duration
,
2060 manager_
.render_stat_
[DemuxerStream::VIDEO
].max().pts
);
2062 // Check that the playback time reported by the player goes past
2063 // the audio time and corresponds to video after the audio ended.
2064 EXPECT_EQ(video_duration
, manager_
.pts_stat_
.max());
2067 TEST_F(MediaCodecPlayerTest
, AVVideoEndsAcrossAudioConfigChange
) {
2068 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2070 // Test that video can end while audio config change processing.
2071 base::TimeDelta audio_duration
= base::TimeDelta::FromMilliseconds(1200);
2072 base::TimeDelta video_duration
= base::TimeDelta::FromMilliseconds(1000);
2073 base::TimeDelta config_change_audio
= base::TimeDelta::FromMilliseconds(1000);
2075 base::TimeDelta completion_timeout
= base::TimeDelta::FromMilliseconds(3000);
2077 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(audio_duration
));
2078 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(video_duration
));
2080 audio_factory
->RequestConfigChange(config_change_audio
);
2082 ASSERT_TRUE(StartAVPlayback(audio_factory
.Pass(), video_factory
.Pass(),
2083 kAlwaysReconfigAudio
,
2084 "AVVideoEndsAcrossAudioConfigChange"));
2086 // Wait till completion
2088 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted
,
2089 base::Unretained(&manager_
)),
2090 completion_timeout
));
2092 // The audio codec should be recreated upon config changes.
2093 EXPECT_EQ(2, manager_
.num_audio_codecs_created());
2095 // The video codec should not be recreated.
2096 EXPECT_EQ(1, manager_
.num_video_codecs_created());
2098 // Check that we did not miss audio frames. We expect two postponed frames
2099 // that are not reported.
2100 int expected_audio_frames
=
2101 GetFrameCount(audio_duration
, kAudioFramePeriod
, 1) - 2;
2102 EXPECT_EQ(expected_audio_frames
,
2103 manager_
.render_stat_
[DemuxerStream::AUDIO
].num_values());
2106 TEST_F(MediaCodecPlayerTest
, AVPrerollAcrossVideoConfigChange
) {
2107 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2109 // Test that preroll continues if interrupted by video config change.
2111 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
2112 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
2113 base::TimeDelta config_change_position
=
2114 base::TimeDelta::FromMilliseconds(800);
2115 base::TimeDelta video_preroll_intvl
= base::TimeDelta::FromMilliseconds(500);
2116 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(3000);
2118 demuxer_
->SetVideoPrerollInterval(video_preroll_intvl
);
2120 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
2122 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
2123 video_factory
->RequestConfigChange(config_change_position
);
2125 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
2126 seek_position
, kAlwaysReconfigVideo
,
2127 "AVPrerollAcrossVideoConfigChange"));
2129 // Wait till preroll finishes and the real playback starts.
2131 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
2132 base::Unretained(&manager_
)),
2135 // The presense of config change should not affect preroll behavior:
2137 // Ensure that the first audio and video pts are close to each other and are
2138 // reported at the close moments in time.
2140 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
2141 EXPECT_TRUE(WaitForCondition(
2142 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
2143 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
2145 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
2146 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
2148 EXPECT_TRUE(AlmostEqual(manager_
.FirstFrameTime(DemuxerStream::AUDIO
),
2149 manager_
.FirstFrameTime(DemuxerStream::VIDEO
), 50));
2151 // The playback should start at |seek_position|
2152 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
2155 TEST_F(MediaCodecPlayerTest
, AVPrerollAcrossAudioConfigChange
) {
2156 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2158 // Test that preroll continues if interrupted by video config change.
2160 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(1200);
2161 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(1000);
2162 base::TimeDelta config_change_position
=
2163 base::TimeDelta::FromMilliseconds(800);
2164 base::TimeDelta audio_preroll_intvl
= base::TimeDelta::FromMilliseconds(400);
2165 base::TimeDelta preroll_timeout
= base::TimeDelta::FromMilliseconds(3000);
2167 demuxer_
->SetAudioPrerollInterval(audio_preroll_intvl
);
2169 scoped_ptr
<AudioFactory
> audio_factory(new AudioFactory(duration
));
2170 audio_factory
->RequestConfigChange(config_change_position
);
2172 scoped_ptr
<VideoFactory
> video_factory(new VideoFactory(duration
));
2174 ASSERT_TRUE(StartAVSeekAndPreroll(audio_factory
.Pass(), video_factory
.Pass(),
2175 seek_position
, kAlwaysReconfigAudio
,
2176 "AVPrerollAcrossAudioConfigChange"));
2178 // Wait till preroll finishes and the real playback starts.
2180 WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted
,
2181 base::Unretained(&manager_
)),
2184 // The presense of config change should not affect preroll behavior:
2186 // Ensure that the first audio and video pts are close to each other and are
2187 // reported at the close moments in time.
2189 EXPECT_TRUE(manager_
.HasFirstFrame(DemuxerStream::AUDIO
));
2190 EXPECT_TRUE(WaitForCondition(
2191 base::Bind(&MockMediaPlayerManager::HasFirstFrame
,
2192 base::Unretained(&manager_
), DemuxerStream::VIDEO
)));
2194 // Wait for some more video
2195 WaitForDelay(base::TimeDelta::FromMilliseconds(100));
2197 EXPECT_TRUE(AlmostEqual(manager_
.FirstFramePTS(DemuxerStream::AUDIO
),
2198 manager_
.FirstFramePTS(DemuxerStream::VIDEO
), 25));
2200 // Because for video preroll the first frame after preroll renders during the
2201 // preroll stage (and not after the preroll is done) we cannot guarantee the
2202 // proper video timimg in this test.
2203 // TODO(timav): maybe we should not call the testing callback for
2204 // kRenderAfterPreroll for video (for audio we already do not call).
2205 // EXPECT_TRUE(AlmostEqual(manager_.FirstFrameTime(DemuxerStream::AUDIO),
2206 // manager_.FirstFrameTime(DemuxerStream::VIDEO), 50));
2208 // The playback should start at |seek_position|
2209 EXPECT_TRUE(AlmostEqual(seek_position
, manager_
.pts_stat_
.min(), 25));
2212 } // namespace media