1 // Copyright 2013 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.
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/stringprintf.h"
11 #include "media/base/android/audio_decoder_job.h"
12 #include "media/base/android/media_codec_bridge.h"
13 #include "media/base/android/media_drm_bridge.h"
14 #include "media/base/android/media_player_manager.h"
15 #include "media/base/android/media_source_player.h"
16 #include "media/base/android/media_url_interceptor.h"
17 #include "media/base/android/video_decoder_job.h"
18 #include "media/base/bind_to_current_loop.h"
19 #include "media/base/decoder_buffer.h"
20 #include "media/base/test_data_util.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "ui/gl/android/surface_texture.h"
26 // Helper macro to skip the test if MediaCodecBridge isn't available.
27 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
29 if (!MediaCodecBridge::IsAvailable()) { \
30 VLOG(0) << "Could not run test - not supported on device."; \
35 const base::TimeDelta kDefaultDuration
=
36 base::TimeDelta::FromMilliseconds(10000);
38 // TODO(wolenetz/qinmin): Simplify tests with more effective mock usage, and
39 // fix flaky pointer-based MDJ inequality testing. See http://crbug.com/327839.
41 // Mock of MediaPlayerManager for testing purpose.
42 class MockMediaPlayerManager
: public MediaPlayerManager
{
44 explicit MockMediaPlayerManager(base::MessageLoop
* message_loop
)
45 : message_loop_(message_loop
),
46 playback_completed_(false),
47 num_resources_requested_(0),
48 num_metadata_changes_(0),
49 timestamp_updated_(false) {}
50 virtual ~MockMediaPlayerManager() {}
52 // MediaPlayerManager implementation.
53 virtual MediaResourceGetter
* GetMediaResourceGetter() override
{
56 virtual MediaUrlInterceptor
* GetMediaUrlInterceptor() override
{
59 virtual void OnTimeUpdate(int player_id
,
60 base::TimeDelta current_time
,
61 base::TimeTicks current_time_ticks
) override
{
62 timestamp_updated_
= true;
64 virtual void OnMediaMetadataChanged(
65 int player_id
, base::TimeDelta duration
, int width
, int height
,
66 bool success
) override
{
67 num_metadata_changes_
++;
69 virtual void OnPlaybackComplete(int player_id
) override
{
70 playback_completed_
= true;
71 if (message_loop_
->is_running())
72 message_loop_
->Quit();
74 virtual void OnMediaInterrupted(int player_id
) override
{}
75 virtual void OnBufferingUpdate(int player_id
, int percentage
) override
{}
76 virtual void OnSeekComplete(int player_id
,
77 const base::TimeDelta
& current_time
) override
{}
78 virtual void OnError(int player_id
, int error
) override
{}
79 virtual void OnVideoSizeChanged(int player_id
, int width
,
80 int height
) override
{}
81 virtual MediaPlayerAndroid
* GetFullscreenPlayer() override
{ return NULL
; }
82 virtual MediaPlayerAndroid
* GetPlayer(int player_id
) override
{ return NULL
; }
83 virtual void RequestFullScreen(int player_id
) override
{}
84 #if defined(VIDEO_HOLE)
85 virtual bool ShouldUseVideoOverlayForEmbeddedEncryptedVideo() override
{
88 #endif // defined(VIDEO_HOLE)
90 bool playback_completed() const {
91 return playback_completed_
;
94 int num_resources_requested() const {
95 return num_resources_requested_
;
98 int num_metadata_changes() const {
99 return num_metadata_changes_
;
102 void OnMediaResourcesRequested(int player_id
) {
103 num_resources_requested_
++;
106 bool timestamp_updated() const {
107 return timestamp_updated_
;
110 void ResetTimestampUpdated() {
111 timestamp_updated_
= false;
115 base::MessageLoop
* message_loop_
;
116 bool playback_completed_
;
117 // The number of resource requests this object has seen.
118 int num_resources_requested_
;
119 // The number of metadata changes reported by the player.
120 int num_metadata_changes_
;
121 // Playback timestamp was updated.
122 bool timestamp_updated_
;
124 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager
);
127 class MockDemuxerAndroid
: public DemuxerAndroid
{
129 explicit MockDemuxerAndroid(base::MessageLoop
* message_loop
)
130 : message_loop_(message_loop
),
131 num_data_requests_(0),
132 num_seek_requests_(0),
133 num_browser_seek_requests_(0) {}
134 virtual ~MockDemuxerAndroid() {}
136 virtual void Initialize(DemuxerAndroidClient
* client
) override
{}
137 virtual void RequestDemuxerData(DemuxerStream::Type type
) override
{
138 num_data_requests_
++;
139 if (message_loop_
->is_running())
140 message_loop_
->Quit();
142 virtual void RequestDemuxerSeek(const base::TimeDelta
& time_to_seek
,
143 bool is_browser_seek
) override
{
144 num_seek_requests_
++;
146 num_browser_seek_requests_
++;
149 int num_data_requests() const { return num_data_requests_
; }
150 int num_seek_requests() const { return num_seek_requests_
; }
151 int num_browser_seek_requests() const { return num_browser_seek_requests_
; }
154 base::MessageLoop
* message_loop_
;
156 // The number of encoded data requests this object has seen.
157 int num_data_requests_
;
159 // The number of regular and browser seek requests this object has seen.
160 int num_seek_requests_
;
162 // The number of browser seek requests this object has seen.
163 int num_browser_seek_requests_
;
165 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid
);
168 class MediaSourcePlayerTest
: public testing::Test
{
170 MediaSourcePlayerTest()
171 : manager_(&message_loop_
),
172 demuxer_(new MockDemuxerAndroid(&message_loop_
)),
173 player_(0, &manager_
,
174 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested
,
175 base::Unretained(&manager_
)),
176 scoped_ptr
<DemuxerAndroid
>(demuxer_
),
178 decoder_callback_hook_executed_(false),
179 surface_texture_a_is_next_(true) {}
180 virtual ~MediaSourcePlayerTest() {}
183 // Get the decoder job from the MediaSourcePlayer. The return value must not
185 MediaDecoderJob
* GetMediaDecoderJob(bool is_audio
) {
187 return reinterpret_cast<MediaDecoderJob
*>(
188 player_
.audio_decoder_job_
.get());
190 return reinterpret_cast<MediaDecoderJob
*>(
191 player_
.video_decoder_job_
.get());
194 // Get the MediaCodecBridge from the decoder job. The return value could be
195 // NULL if the decoder is not yet created.
196 MediaCodecBridge
* GetMediaCodecBridge(bool is_audio
) {
198 return player_
.audio_decoder_job_
->media_codec_bridge_
.get();
199 return player_
.video_decoder_job_
->media_codec_bridge_
.get();
202 // Get the per-job prerolling status from the MediaSourcePlayer's job matching
203 // |is_audio|. Caller must guard against NPE if the player's job is NULL.
204 bool IsPrerolling(bool is_audio
) {
205 return GetMediaDecoderJob(is_audio
)->prerolling_
;
208 // Get the preroll timestamp from the MediaSourcePlayer.
209 base::TimeDelta
GetPrerollTimestamp() {
210 return player_
.preroll_timestamp_
;
213 // Simulate player has reached starvation timeout.
214 void TriggerPlayerStarvation() {
215 player_
.decoder_starvation_callback_
.Cancel();
216 player_
.OnDecoderStarved();
219 // Release() the player.
220 void ReleasePlayer() {
221 EXPECT_TRUE(player_
.IsPlaying());
223 EXPECT_FALSE(player_
.IsPlaying());
226 // Upon the next successful decode callback, post a task to call Release()
227 // on the |player_|. TEST_F's do not have access to the private player
228 // members, hence this helper method.
229 // Prevent usage creep of MSP::set_decode_callback_for_testing() by
230 // only using it for the ReleaseWithOnPrefetchDoneAlreadyPosted test.
231 void OnNextTestDecodeCallbackPostTaskToReleasePlayer() {
232 DCHECK_EQ(&message_loop_
, base::MessageLoop::current());
233 player_
.set_decode_callback_for_testing(media::BindToCurrentLoop(
235 &MediaSourcePlayerTest::ReleaseWithPendingPrefetchDoneVerification
,
236 base::Unretained(this))));
239 // Asynch test callback posted upon decode completion to verify that a pending
240 // prefetch done event is not cleared across |player_|'s Release(). This helps
241 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
242 void ReleaseWithPendingPrefetchDoneVerification() {
243 EXPECT_TRUE(player_
.IsEventPending(player_
.PREFETCH_DONE_EVENT_PENDING
));
245 EXPECT_TRUE(player_
.IsEventPending(player_
.PREFETCH_DONE_EVENT_PENDING
));
246 EXPECT_FALSE(decoder_callback_hook_executed_
);
247 EXPECT_FALSE(GetMediaCodecBridge(true));
248 decoder_callback_hook_executed_
= true;
251 DemuxerConfigs
CreateAudioDemuxerConfigs(AudioCodec audio_codec
,
252 bool use_low_sample_rate
) {
253 DemuxerConfigs configs
;
254 configs
.audio_codec
= audio_codec
;
255 configs
.audio_channels
= 2;
256 configs
.is_audio_encrypted
= false;
257 configs
.duration
= kDefaultDuration
;
259 if (audio_codec
== kCodecVorbis
) {
260 configs
.audio_sampling_rate
= use_low_sample_rate
? 11025 : 44100;
261 scoped_refptr
<DecoderBuffer
> buffer
= ReadTestDataFile(
263 configs
.audio_extra_data
= std::vector
<uint8
>(
265 buffer
->data() + buffer
->data_size());
269 // Other codecs are not yet supported by this helper.
270 EXPECT_EQ(audio_codec
, kCodecAAC
);
272 configs
.audio_sampling_rate
= 48000;
273 uint8 aac_extra_data
[] = { 0x13, 0x10 };
274 configs
.audio_extra_data
= std::vector
<uint8
>(
280 DemuxerConfigs
CreateVideoDemuxerConfigs(bool use_larger_size
) {
281 DemuxerConfigs configs
;
282 configs
.video_codec
= kCodecVP8
;
284 use_larger_size
? gfx::Size(640, 240) : gfx::Size(320, 240);
285 configs
.is_video_encrypted
= false;
286 configs
.duration
= kDefaultDuration
;
290 DemuxerConfigs
CreateAudioVideoDemuxerConfigs() {
291 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, false);
292 configs
.video_codec
= kCodecVP8
;
293 configs
.video_size
= gfx::Size(320, 240);
294 configs
.is_video_encrypted
= false;
298 DemuxerConfigs
CreateDemuxerConfigs(bool have_audio
, bool have_video
) {
299 DCHECK(have_audio
|| have_video
);
301 if (have_audio
&& !have_video
)
302 return CreateAudioDemuxerConfigs(kCodecVorbis
, false);
304 if (have_video
&& !have_audio
)
305 return CreateVideoDemuxerConfigs(false);
307 return CreateAudioVideoDemuxerConfigs();
310 // Starts an audio decoder job.
311 void StartAudioDecoderJob() {
312 Start(CreateAudioDemuxerConfigs(kCodecVorbis
, false));
315 // Starts a video decoder job.
316 void StartVideoDecoderJob() {
317 Start(CreateVideoDemuxerConfigs(false));
320 // Starts decoding the data.
321 void Start(const DemuxerConfigs
& configs
) {
322 EXPECT_EQ(demuxer_
->num_data_requests(), 0);
323 player_
.OnDemuxerConfigsAvailable(configs
);
326 EXPECT_TRUE(player_
.IsPlaying());
327 int expected_num_requests
= (player_
.HasAudio() ? 1 : 0) +
328 (player_
.HasVideo() ? 1 : 0);
329 EXPECT_EQ(expected_num_requests
, demuxer_
->num_data_requests());
332 // Resumes decoding the data. Verifies player behavior relative to
333 // |expect_player_requests_audio_data| and
334 // |expect_player_requests_video_data|.
335 void Resume(bool expect_player_requests_audio_data
,
336 bool expect_player_requests_video_data
) {
337 EXPECT_FALSE(player_
.IsPlaying());
338 EXPECT_TRUE(player_
.HasVideo() || player_
.HasAudio());
339 int original_num_data_requests
= demuxer_
->num_data_requests();
340 int expected_request_delta
=
341 (expect_player_requests_audio_data
? 1 : 0) +
342 (expect_player_requests_video_data
? 1 : 0);
346 EXPECT_TRUE(player_
.IsPlaying());
347 EXPECT_EQ(original_num_data_requests
+ expected_request_delta
,
348 demuxer_
->num_data_requests());
351 // Keeps decoding audio data until the decoder starts to output samples.
352 // Gives up if no audio output after decoding 10 frames.
353 void DecodeAudioDataUntilOutputBecomesAvailable() {
354 EXPECT_TRUE(player_
.IsPlaying());
355 base::TimeDelta current_time
= player_
.GetCurrentTime();
356 base::TimeDelta start_timestamp
= current_time
;
357 for (int i
= 0; i
< 10; ++i
) {
358 manager_
.ResetTimestampUpdated();
359 player_
.OnDemuxerDataAvailable(
360 CreateReadFromDemuxerAckForAudio(i
> 3 ? 3 : i
));
361 WaitForAudioDecodeDone();
362 base::TimeDelta new_current_time
= player_
.GetCurrentTime();
363 EXPECT_LE(current_time
.InMilliseconds(),
364 new_current_time
.InMilliseconds());
365 current_time
= new_current_time
;
366 if (manager_
.timestamp_updated()) {
367 // TODO(qinmin): the current time is from the decoder thread and it does
368 // not take the delay from posting the task into consideration.
369 // http://crbug.com/421616.
370 EXPECT_LE(start_timestamp
.InMillisecondsF(),
371 new_current_time
.InMillisecondsF());
378 AccessUnit
CreateAccessUnitWithData(bool is_audio
, int audio_packet_id
,
379 bool use_large_size_video
) {
382 unit
.status
= DemuxerStream::kOk
;
383 scoped_refptr
<DecoderBuffer
> buffer
;
385 buffer
= ReadTestDataFile(
386 base::StringPrintf("vorbis-packet-%d", audio_packet_id
));
388 buffer
= ReadTestDataFile(
389 use_large_size_video
? "vp8-I-frame-640x240" : "vp8-I-frame-320x240");
391 unit
.data
= std::vector
<uint8
>(
392 buffer
->data(), buffer
->data() + buffer
->data_size());
395 // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
396 // NuMediaExtractor.cpp in Android source code.
397 uint8 padding
[4] = { 0xff , 0xff , 0xff , 0xff };
398 unit
.data
.insert(unit
.data
.end(), padding
, padding
+ 4);
404 DemuxerData
CreateReadFromDemuxerAckForAudio(int packet_id
) {
406 data
.type
= DemuxerStream::AUDIO
;
407 data
.access_units
.resize(1);
408 data
.access_units
[0] = CreateAccessUnitWithData(true, packet_id
, false);
413 DemuxerData
CreateReadFromDemuxerAckForVideo(bool use_large_size
) {
415 data
.type
= DemuxerStream::VIDEO
;
416 data
.access_units
.resize(1);
417 data
.access_units
[0] = CreateAccessUnitWithData(false, 0, use_large_size
);
421 DemuxerData
CreateEOSAck(bool is_audio
) {
423 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
424 data
.access_units
.resize(1);
425 data
.access_units
[0].status
= DemuxerStream::kOk
;
426 data
.access_units
[0].end_of_stream
= true;
430 DemuxerData
CreateAbortedAck(bool is_audio
) {
432 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
433 data
.access_units
.resize(1);
434 data
.access_units
[0].status
= DemuxerStream::kAborted
;
438 // Helper method for use at test start. It starts an audio decoder job and
439 // immediately feeds it some data to decode. Then, without letting the decoder
440 // job complete a decode cycle, it also starts player SeekTo(). Upon return,
441 // the player should not yet have sent the DemuxerSeek IPC request, though
442 // seek event should be pending. The audio decoder job will also still be
444 void StartAudioDecoderJobAndSeekToWhileDecoding(
445 const base::TimeDelta
& seek_time
) {
446 EXPECT_FALSE(GetMediaCodecBridge(true));
447 EXPECT_FALSE(player_
.IsPlaying());
448 EXPECT_EQ(0, demuxer_
->num_data_requests());
449 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
450 EXPECT_EQ(player_
.GetCurrentTime(), GetPrerollTimestamp());
451 StartAudioDecoderJob();
452 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
453 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
454 EXPECT_EQ(2, demuxer_
->num_data_requests());
455 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
456 player_
.SeekTo(seek_time
);
457 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
458 EXPECT_EQ(0, demuxer_
->num_seek_requests());
459 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
462 // Seek, including simulated receipt of |kAborted| read between SeekTo() and
463 // OnDemuxerSeekDone(). Use this helper method only when the player already
464 // has created the media codec bridge. Exactly one request for more data is
465 // expected following the seek, so use this helper for players with only audio
467 void SeekPlayerWithAbort(bool is_audio
, const base::TimeDelta
& seek_time
) {
468 int original_num_seeks
= demuxer_
->num_seek_requests();
469 int original_num_data_requests
= demuxer_
->num_data_requests();
471 // Initiate a seek. Skip the round-trip of requesting seek from renderer.
472 // Instead behave as if the renderer has asked us to seek.
473 player_
.SeekTo(seek_time
);
475 // Verify that the seek does not occur until previously outstanding data
476 // request is satisfied.
477 EXPECT_EQ(original_num_seeks
, demuxer_
->num_seek_requests());
479 // Simulate seeking causes the demuxer to abort the outstanding read
480 // caused by the seek.
481 player_
.OnDemuxerDataAvailable(CreateAbortedAck(is_audio
));
483 // Wait for the decode job to finish so we can process the seek request.
484 WaitForDecodeDone(is_audio
, !is_audio
);
486 // Verify that the seek is requested.
487 EXPECT_EQ(original_num_seeks
+ 1, demuxer_
->num_seek_requests());
489 // Send back the seek done notification. This should trigger the player to
490 // call OnReadFromDemuxer() again.
491 EXPECT_EQ(original_num_data_requests
, demuxer_
->num_data_requests());
492 player_
.OnDemuxerSeekDone(kNoTimestamp());
493 EXPECT_EQ(original_num_data_requests
+ 1, demuxer_
->num_data_requests());
495 // No other seek should have been requested.
496 EXPECT_EQ(original_num_seeks
+ 1, demuxer_
->num_seek_requests());
499 // Preroll the decoder job to |target_timestamp|. The first access unit
500 // to decode will have a timestamp equal to |start_timestamp|.
501 // |is_clock_manager| indicates whether the decoder serves as the clock
502 // manager for the player.
503 // TODO(qinmin): Add additional test cases for out-of-order decodes.
504 // See http://crbug.com/331421.
505 void PrerollDecoderToTime(bool is_audio
,
506 const base::TimeDelta
& start_timestamp
,
507 const base::TimeDelta
& target_timestamp
,
508 bool is_clock_manager
) {
509 // For streams with both audio and video, it is possible that audio rolls
510 // past the |target_timestamp|. As a result, the current time may be larger
511 // than the |target_timestamp| for video as it may not be the clock manager.
512 EXPECT_TRUE(!is_clock_manager
||
513 target_timestamp
== player_
.GetCurrentTime());
514 // |start_timestamp| must be smaller than |target_timestamp|.
515 EXPECT_LE(start_timestamp
, target_timestamp
);
516 DemuxerData data
= is_audio
? CreateReadFromDemuxerAckForAudio(1) :
517 CreateReadFromDemuxerAckForVideo(false);
518 int current_timestamp
= start_timestamp
.InMilliseconds();
520 // Send some data with access unit timestamps before the |target_timestamp|,
521 // and continue sending the data until preroll finishes.
522 // This simulates the common condition that AUs received after browser
523 // seek begin with timestamps before the seek target, and don't
524 // immediately complete preroll.
525 while (IsPrerolling(is_audio
)) {
526 data
.access_units
[0].timestamp
=
527 base::TimeDelta::FromMilliseconds(current_timestamp
);
528 player_
.OnDemuxerDataAvailable(data
);
529 EXPECT_TRUE(GetMediaDecoderJob(is_audio
)->is_decoding());
530 EXPECT_TRUE(GetMediaCodecBridge(is_audio
));
531 EXPECT_TRUE(!is_clock_manager
||
532 target_timestamp
== player_
.GetCurrentTime());
533 current_timestamp
+= 30;
534 WaitForDecodeDone(is_audio
, !is_audio
);
536 EXPECT_LE(target_timestamp
, player_
.GetCurrentTime());
539 DemuxerData
CreateReadFromDemuxerAckWithConfigChanged(
541 int config_unit_index
,
542 const DemuxerConfigs
& configs
) {
544 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
545 data
.access_units
.resize(config_unit_index
+ 1);
547 for (int i
= 0; i
< config_unit_index
; ++i
)
548 data
.access_units
[i
] = CreateAccessUnitWithData(is_audio
, i
, false);
550 data
.access_units
[config_unit_index
].status
= DemuxerStream::kConfigChanged
;
551 data
.demuxer_configs
.resize(1);
552 data
.demuxer_configs
[0] = configs
;
556 // Valid only for video-only player tests. If |trigger_with_release_start| is
557 // true, triggers the browser seek with a Release() + video data received +
558 // Start() with a new surface. If false, triggers the browser seek by
559 // setting a new video surface after beginning decode of received video data.
560 // Such data receipt causes possibility that an I-frame is not next, and
561 // browser seek results once decode completes and surface change processing
563 void BrowserSeekPlayer(bool trigger_with_release_start
) {
564 int expected_num_data_requests
= demuxer_
->num_data_requests() + 2;
565 int expected_num_seek_requests
= demuxer_
->num_seek_requests();
566 int expected_num_browser_seek_requests
=
567 demuxer_
->num_browser_seek_requests();
569 CreateNextTextureAndSetVideoSurface();
570 StartVideoDecoderJob();
571 if (trigger_with_release_start
) {
572 // Consume the first frame, so that the next VideoDecoderJob will not
573 // inherit the I-frame from the previous decoder.
574 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
576 WaitForVideoDecodeDone();
578 // Simulate demuxer's response to the video data request. The data will be
579 // passed to the next MediaCodecBridge.
580 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
581 EXPECT_FALSE(GetMediaCodecBridge(false));
582 EXPECT_FALSE(player_
.IsPlaying());
583 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
585 CreateNextTextureAndSetVideoSurface();
586 Resume(false, false);
587 EXPECT_FALSE(GetMediaCodecBridge(false));
589 // Run the message loop so that prefetch will complete.
590 while (expected_num_seek_requests
== demuxer_
->num_seek_requests())
591 message_loop_
.RunUntilIdle();
593 // Simulate demuxer's response to the video data request.
594 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
596 // While the decoder is decoding, trigger a browser seek by changing
597 // surface. Demuxer does not know of browser seek in advance, so no
598 // |kAborted| data is required (though |kAborted| can certainly occur for
599 // any pending read in reality due to renderer preparing for a regular
601 CreateNextTextureAndSetVideoSurface();
603 // Browser seek should not begin until decoding has completed.
604 EXPECT_TRUE(GetMediaCodecBridge(false));
605 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
607 // Wait for the media codec bridge to finish decoding and be reset pending
609 WaitForVideoDecodeDone();
610 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
613 // Only one browser seek should have been initiated, and no further data
614 // should have been requested.
615 expected_num_seek_requests
++;
616 expected_num_browser_seek_requests
++;
617 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
618 EXPECT_EQ(expected_num_browser_seek_requests
,
619 demuxer_
->num_browser_seek_requests());
620 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
623 // Creates a new media codec bridge and feeds it data ending with a
624 // |kConfigChanged| access unit. If |config_unit_in_prefetch| is true, sends
625 // feeds the config change AU in response to the job's first read request
626 // (prefetch). If false, regular data is fed and decoded prior to feeding the
627 // config change AU in response to the second data request (after prefetch
628 // completed). |config_unit_index| controls which access unit is
629 // |kConfigChanged|. If |enable_adaptive_playback| is true, config change will
630 // not cause the decoder to recreate the media codec bridge. Otherwise, the
631 // decoder has to drain all its data before recreating the new codec.
632 void SendConfigChangeToDecoder(bool is_audio
,
633 bool config_unit_in_prefetch
,
634 int config_unit_index
,
635 bool enable_adaptive_playback
) {
636 EXPECT_FALSE(GetMediaCodecBridge(is_audio
));
638 StartAudioDecoderJob();
640 CreateNextTextureAndSetVideoSurface();
641 StartVideoDecoderJob();
644 int expected_num_data_requests
= demuxer_
->num_data_requests();
645 // Feed and decode a standalone access unit so the player exits prefetch.
646 if (!config_unit_in_prefetch
) {
648 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
650 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
651 EnableAdaptiveVideoPlayback(enable_adaptive_playback
);
654 WaitForDecodeDone(is_audio
, !is_audio
);
656 // We should have completed the prefetch phase at this point.
657 expected_num_data_requests
++;
658 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
661 DemuxerConfigs configs
= is_audio
?
662 CreateAudioDemuxerConfigs(kCodecVorbis
, true) :
663 CreateVideoDemuxerConfigs(true);
664 // Feed and decode access units with data for any units prior to
665 // |config_unit_index|, and a |kConfigChanged| unit at that index.
666 // Player should prepare to reconfigure the decoder job, and should request
667 // new demuxer configs.
668 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
669 is_audio
, config_unit_index
, configs
));
671 expected_num_data_requests
++;
672 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
674 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
676 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(true));
678 // If the adaptive playback setting was not passed to the MediaCodecBridge
679 // earlier, do it here.
680 if (config_unit_in_prefetch
&& !is_audio
)
681 EnableAdaptiveVideoPlayback(enable_adaptive_playback
);
684 // Send a config change to the decoder job and drain the decoder so that the
685 // config change is processed.
686 void StartConfigChange(bool is_audio
,
687 bool config_unit_in_prefetch
,
688 int config_unit_index
,
689 bool enable_adaptive_playback
) {
690 SendConfigChangeToDecoder(is_audio
, config_unit_in_prefetch
,
691 config_unit_index
, enable_adaptive_playback
);
693 EXPECT_EQ(!config_unit_in_prefetch
&& !enable_adaptive_playback
&&
694 config_unit_index
== 0, IsDrainingDecoder(is_audio
));
695 int expected_num_data_requests
= demuxer_
->num_data_requests();
696 // Run until decoder starts to request new data.
697 while (demuxer_
->num_data_requests() == expected_num_data_requests
)
698 message_loop_
.RunUntilIdle();
699 EXPECT_FALSE(IsDrainingDecoder(is_audio
));
702 void EnableAdaptiveVideoPlayback(bool enable
) {
703 EXPECT_TRUE(GetMediaCodecBridge(false));
704 static_cast<VideoCodecBridge
*>(GetMediaCodecBridge(false))->
705 set_adaptive_playback_supported_for_testing(
709 void CreateNextTextureAndSetVideoSurface() {
710 gfx::SurfaceTexture
* surface_texture
;
711 if (surface_texture_a_is_next_
) {
712 surface_texture_a_
= gfx::SurfaceTexture::Create(next_texture_id_
++);
713 surface_texture
= surface_texture_a_
.get();
715 surface_texture_b_
= gfx::SurfaceTexture::Create(next_texture_id_
++);
716 surface_texture
= surface_texture_b_
.get();
719 surface_texture_a_is_next_
= !surface_texture_a_is_next_
;
720 gfx::ScopedJavaSurface surface
= gfx::ScopedJavaSurface(surface_texture
);
721 player_
.SetVideoSurface(surface
.Pass());
724 // Wait for one or both of the jobs to complete decoding. Media codec bridges
725 // are assumed to exist for any stream whose decode completion is awaited.
726 void WaitForDecodeDone(bool wait_for_audio
, bool wait_for_video
) {
727 DCHECK(wait_for_audio
|| wait_for_video
);
728 while ((wait_for_audio
&& GetMediaCodecBridge(true) &&
729 GetMediaDecoderJob(true)->HasData() &&
730 GetMediaDecoderJob(true)->is_decoding()) ||
731 (wait_for_video
&& GetMediaCodecBridge(false) &&
732 GetMediaDecoderJob(false)->HasData() &&
733 GetMediaDecoderJob(false)->is_decoding())) {
734 message_loop_
.RunUntilIdle();
738 void WaitForAudioDecodeDone() {
739 WaitForDecodeDone(true, false);
742 void WaitForVideoDecodeDone() {
743 WaitForDecodeDone(false, true);
746 void WaitForAudioVideoDecodeDone() {
747 WaitForDecodeDone(true, true);
750 // If |send_eos| is true, generates EOS for the stream corresponding to
751 // |eos_for_audio|. Verifies that playback completes and no further data
753 // If |send_eos| is false, then it is assumed that caller previously arranged
754 // for player to receive EOS for each stream, but the player has not yet
755 // decoded all of them. In this case, |eos_for_audio| is ignored.
756 void VerifyPlaybackCompletesOnEOSDecode(bool send_eos
, bool eos_for_audio
) {
757 int original_num_data_requests
= demuxer_
->num_data_requests();
759 player_
.OnDemuxerDataAvailable(CreateEOSAck(eos_for_audio
));
760 EXPECT_FALSE(manager_
.playback_completed());
762 EXPECT_TRUE(manager_
.playback_completed());
763 EXPECT_EQ(original_num_data_requests
, demuxer_
->num_data_requests());
766 void VerifyCompletedPlaybackResumesOnSeekPlusStart(bool have_audio
,
768 DCHECK(have_audio
|| have_video
);
770 EXPECT_TRUE(manager_
.playback_completed());
772 player_
.SeekTo(base::TimeDelta());
773 player_
.OnDemuxerSeekDone(kNoTimestamp());
774 Resume(have_audio
, have_video
);
777 // Starts the appropriate decoder jobs according to |have_audio| and
778 // |have_video|. Then starts seek during decode of EOS or non-EOS according to
779 // |eos_audio| and |eos_video|. Simulates seek completion and verifies that
780 // playback never completed. |eos_{audio,video}| is ignored if the
781 // corresponding |have_{audio,video}| is false.
782 void VerifySeekDuringEOSDecodePreventsPlaybackCompletion(bool have_audio
,
786 DCHECK(have_audio
|| have_video
);
789 CreateNextTextureAndSetVideoSurface();
791 Start(CreateDemuxerConfigs(have_audio
, have_video
));
794 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
797 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
799 // Run until more data is requested a number of times equal to the number of
800 // media types configured. Since prefetching may be in progress, we cannot
801 // reliably expect Run() to complete until we have sent demuxer data for all
802 // configured media types, above.
803 WaitForDecodeDone(have_audio
, have_video
);
805 // Simulate seek while decoding EOS or non-EOS for the appropriate
809 player_
.OnDemuxerDataAvailable(CreateEOSAck(true));
811 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
816 player_
.OnDemuxerDataAvailable(CreateEOSAck(false));
818 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
821 player_
.SeekTo(base::TimeDelta());
822 EXPECT_EQ(0, demuxer_
->num_seek_requests());
823 WaitForDecodeDone(have_audio
, have_video
);
824 EXPECT_EQ(1, demuxer_
->num_seek_requests());
826 player_
.OnDemuxerSeekDone(kNoTimestamp());
827 EXPECT_FALSE(manager_
.playback_completed());
830 base::TimeTicks
StartTimeTicks() {
831 return player_
.start_time_ticks_
;
834 bool IsRequestingDemuxerData(bool is_audio
) {
835 return GetMediaDecoderJob(is_audio
)->is_requesting_demuxer_data_
;
838 bool IsDrainingDecoder(bool is_audio
) {
839 return GetMediaDecoderJob(is_audio
)->drain_decoder_
;
842 base::MessageLoop message_loop_
;
843 MockMediaPlayerManager manager_
;
844 MockDemuxerAndroid
* demuxer_
; // Owned by |player_|.
845 MediaSourcePlayer player_
;
847 // Track whether a possibly async decoder callback test hook has run.
848 bool decoder_callback_hook_executed_
;
850 // We need to keep the surface texture while the decoder is actively decoding.
851 // Otherwise, it may trigger unexpected crashes on some devices. To switch
852 // surfaces, tests need to create a new surface texture without releasing
853 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
854 // between two surface textures, only replacing the N-2 texture. Assumption is
855 // that no more than N-1 texture is in use by decoder when
856 // CreateNextTextureAndSetVideoSurface() is called.
857 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_a_
;
858 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_b_
;
859 bool surface_texture_a_is_next_
;
860 int next_texture_id_
;
862 DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayerTest
);
865 TEST_F(MediaSourcePlayerTest
, StartAudioDecoderWithValidConfig
) {
866 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
868 // Test audio codec will be created when valid configs and data are passed to
869 // the audio decoder job.
870 StartAudioDecoderJob();
871 EXPECT_EQ(0, demuxer_
->num_seek_requests());
872 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
873 EXPECT_TRUE(GetMediaCodecBridge(true));
876 TEST_F(MediaSourcePlayerTest
, StartAudioDecoderWithInvalidConfig
) {
877 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
879 // Test audio decoder job will not be created when failed to start the codec.
880 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, false);
881 // Replace with invalid |audio_extra_data|
882 configs
.audio_extra_data
.clear();
883 uint8 invalid_codec_data
[] = { 0x00, 0xff, 0xff, 0xff, 0xff };
884 configs
.audio_extra_data
.insert(configs
.audio_extra_data
.begin(),
885 invalid_codec_data
, invalid_codec_data
+ 4);
888 // Decoder is not created after data is received.
889 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
890 EXPECT_FALSE(GetMediaCodecBridge(true));
893 TEST_F(MediaSourcePlayerTest
, StartVideoCodecWithValidSurface
) {
894 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
896 // Test video codec will not be created until data is received.
897 StartVideoDecoderJob();
899 // Set both an initial and a later video surface without receiving any
901 CreateNextTextureAndSetVideoSurface();
902 EXPECT_FALSE(GetMediaCodecBridge(false));
903 CreateNextTextureAndSetVideoSurface();
904 EXPECT_FALSE(GetMediaCodecBridge(false));
906 // No seeks, even on setting surface, should have occurred. (Browser seeks can
907 // occur on setting surface, but only after previously receiving video data.)
908 EXPECT_EQ(0, demuxer_
->num_seek_requests());
910 // Send the first input chunk and verify that decoder will be created.
911 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
912 EXPECT_TRUE(GetMediaCodecBridge(false));
913 WaitForVideoDecodeDone();
916 TEST_F(MediaSourcePlayerTest
, StartVideoCodecWithInvalidSurface
) {
917 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
919 // Test video codec will not be created when surface is invalid.
920 scoped_refptr
<gfx::SurfaceTexture
> surface_texture(
921 gfx::SurfaceTexture::Create(0));
922 gfx::ScopedJavaSurface
surface(surface_texture
.get());
923 StartVideoDecoderJob();
925 // Release the surface texture.
926 surface_texture
= NULL
;
927 player_
.SetVideoSurface(surface
.Pass());
929 // Player should not seek the demuxer on setting initial surface.
930 EXPECT_EQ(0, demuxer_
->num_seek_requests());
931 EXPECT_EQ(1, demuxer_
->num_data_requests());
933 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
934 EXPECT_FALSE(GetMediaCodecBridge(false));
937 TEST_F(MediaSourcePlayerTest
, ReadFromDemuxerAfterSeek
) {
938 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
940 // Test decoder job will resend a ReadFromDemuxer request after seek.
941 StartAudioDecoderJob();
942 SeekPlayerWithAbort(true, base::TimeDelta());
945 TEST_F(MediaSourcePlayerTest
, SetSurfaceWhileSeeking
) {
946 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
948 // Test SetVideoSurface() will not cause an extra seek while the player is
949 // waiting for demuxer to indicate seek is done.
950 player_
.OnDemuxerConfigsAvailable(
951 CreateVideoDemuxerConfigs(false));
953 // Initiate a seek. Skip requesting element seek of renderer.
954 // Instead behave as if the renderer has asked us to seek.
955 player_
.SeekTo(base::TimeDelta());
956 EXPECT_EQ(1, demuxer_
->num_seek_requests());
958 CreateNextTextureAndSetVideoSurface();
959 EXPECT_EQ(1, demuxer_
->num_seek_requests());
962 // Send the seek done notification. The player should start requesting data.
963 player_
.OnDemuxerSeekDone(kNoTimestamp());
964 EXPECT_FALSE(GetMediaCodecBridge(false));
965 EXPECT_EQ(1, demuxer_
->num_data_requests());
966 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
967 EXPECT_TRUE(GetMediaCodecBridge(false));
969 // Reconfirm exactly 1 seek request has been made of demuxer, and that it
970 // was not a browser seek request.
971 EXPECT_EQ(1, demuxer_
->num_seek_requests());
972 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
973 WaitForVideoDecodeDone();
976 TEST_F(MediaSourcePlayerTest
, ChangeMultipleSurfaceWhileDecoding
) {
977 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
979 // Test MediaSourcePlayer can switch multiple surfaces during decoding.
980 CreateNextTextureAndSetVideoSurface();
981 StartVideoDecoderJob();
982 EXPECT_EQ(0, demuxer_
->num_seek_requests());
984 // Send the first input chunk.
985 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
987 // While the decoder is decoding, change multiple surfaces. Pass an empty
989 gfx::ScopedJavaSurface empty_surface
;
990 player_
.SetVideoSurface(empty_surface
.Pass());
991 // Next, pass a new non-empty surface.
992 CreateNextTextureAndSetVideoSurface();
994 // Wait for the media codec bridge to finish decoding and be reset pending a
996 WaitForVideoDecodeDone();
997 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
999 // Only one browser seek should have been initiated. No further data request
1000 // should have been processed on |message_loop_| before surface change event
1001 // became pending, above.
1002 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
1003 EXPECT_EQ(2, demuxer_
->num_data_requests());
1005 // Simulate browser seek is done and confirm player requests more data for new
1007 player_
.OnDemuxerSeekDone(player_
.GetCurrentTime());
1008 EXPECT_FALSE(GetMediaCodecBridge(false));
1009 EXPECT_EQ(3, demuxer_
->num_data_requests());
1010 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1012 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1013 EXPECT_TRUE(GetMediaCodecBridge(false));
1014 WaitForVideoDecodeDone();
1017 TEST_F(MediaSourcePlayerTest
, SetEmptySurfaceAndStarveWhileDecoding
) {
1018 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1020 // Test player pauses if an empty surface is passed.
1021 CreateNextTextureAndSetVideoSurface();
1022 StartVideoDecoderJob();
1023 EXPECT_EQ(1, demuxer_
->num_data_requests());
1025 // Send the first input chunk.
1026 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1028 // While the decoder is decoding, pass an empty surface.
1029 gfx::ScopedJavaSurface empty_surface
;
1030 player_
.SetVideoSurface(empty_surface
.Pass());
1031 // Let the player starve. However, it should not issue any new data request in
1033 TriggerPlayerStarvation();
1034 // Wait for the media codec bridge to finish decoding and be reset.
1035 while (GetMediaDecoderJob(false)->is_decoding())
1036 message_loop_
.RunUntilIdle();
1038 // No further seek or data requests should have been received since the
1039 // surface is empty.
1040 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
1041 EXPECT_EQ(2, demuxer_
->num_data_requests());
1042 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1044 // Playback resumes once a non-empty surface is passed.
1045 CreateNextTextureAndSetVideoSurface();
1046 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
1047 WaitForVideoDecodeDone();
1050 TEST_F(MediaSourcePlayerTest
, ReleaseVideoDecoderResourcesWhileDecoding
) {
1051 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1053 // Test that if video decoder is released while decoding, the resources will
1054 // not be immediately released.
1055 CreateNextTextureAndSetVideoSurface();
1056 StartVideoDecoderJob();
1057 // No resource is requested since there is no data to decode.
1058 EXPECT_EQ(0, manager_
.num_resources_requested());
1060 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1062 // Recreate the video decoder.
1063 CreateNextTextureAndSetVideoSurface();
1065 while (!GetMediaDecoderJob(false)->is_decoding())
1066 message_loop_
.RunUntilIdle();
1067 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
1068 EXPECT_EQ(1, manager_
.num_resources_requested());
1070 // Wait for the media codec bridge to finish decoding and be reset.
1071 while (GetMediaDecoderJob(false)->is_decoding())
1072 message_loop_
.RunUntilIdle();
1075 TEST_F(MediaSourcePlayerTest
, AudioOnlyStartAfterSeekFinish
) {
1076 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1078 // Test audio decoder job will not start until pending seek event is handled.
1079 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, false);
1080 player_
.OnDemuxerConfigsAvailable(configs
);
1082 // Initiate a seek. Skip requesting element seek of renderer.
1083 // Instead behave as if the renderer has asked us to seek.
1084 player_
.SeekTo(base::TimeDelta());
1085 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1088 EXPECT_EQ(0, demuxer_
->num_data_requests());
1090 // Sending back the seek done notification.
1091 player_
.OnDemuxerSeekDone(kNoTimestamp());
1092 EXPECT_FALSE(GetMediaCodecBridge(true));
1093 EXPECT_EQ(1, demuxer_
->num_data_requests());
1095 // Reconfirm exactly 1 seek request has been made of demuxer.
1096 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1098 // Decoder is created after data is received.
1099 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1100 EXPECT_TRUE(GetMediaCodecBridge(true));
1103 TEST_F(MediaSourcePlayerTest
, VideoOnlyStartAfterSeekFinish
) {
1104 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1106 // Test video decoder job will not start until pending seek event is handled.
1107 CreateNextTextureAndSetVideoSurface();
1108 DemuxerConfigs configs
= CreateVideoDemuxerConfigs(false);
1109 player_
.OnDemuxerConfigsAvailable(configs
);
1111 // Initiate a seek. Skip requesting element seek of renderer.
1112 // Instead behave as if the renderer has asked us to seek.
1113 player_
.SeekTo(base::TimeDelta());
1114 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1117 EXPECT_EQ(0, demuxer_
->num_data_requests());
1119 // Sending back the seek done notification.
1120 player_
.OnDemuxerSeekDone(kNoTimestamp());
1121 EXPECT_FALSE(GetMediaCodecBridge(false));
1122 EXPECT_EQ(1, demuxer_
->num_data_requests());
1124 // Reconfirm exactly 1 seek request has been made of demuxer.
1125 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1127 // Decoder is created after data is received.
1128 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1129 EXPECT_TRUE(GetMediaCodecBridge(false));
1130 WaitForVideoDecodeDone();
1133 TEST_F(MediaSourcePlayerTest
, StartImmediatelyAfterPause
) {
1134 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1136 // Test that if the decoding job is not fully stopped after Pause(),
1137 // calling Start() will be a noop.
1138 StartAudioDecoderJob();
1140 MediaDecoderJob
* decoder_job
= GetMediaDecoderJob(true);
1141 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
1143 // Sending data to player.
1144 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1145 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1146 EXPECT_EQ(2, demuxer_
->num_data_requests());
1148 // Decoder job will not immediately stop after Pause() since it is
1149 // running on another thread.
1150 player_
.Pause(true);
1151 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1153 // Nothing happens when calling Start() again.
1155 // Verify that Start() will not destroy and recreate the media codec bridge.
1156 EXPECT_EQ(decoder_job
, GetMediaDecoderJob(true));
1158 while (GetMediaDecoderJob(true)->is_decoding())
1159 message_loop_
.RunUntilIdle();
1160 // The decoder job should finish and wait for data.
1161 EXPECT_EQ(2, demuxer_
->num_data_requests());
1162 EXPECT_TRUE(IsRequestingDemuxerData(true));
1165 TEST_F(MediaSourcePlayerTest
, DecoderJobsCannotStartWithoutAudio
) {
1166 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1168 // Test that when Start() is called, video decoder job will wait for audio
1169 // decoder job before start decoding the data.
1170 CreateNextTextureAndSetVideoSurface();
1171 Start(CreateAudioVideoDemuxerConfigs());
1172 MediaDecoderJob
* audio_decoder_job
= GetMediaDecoderJob(true);
1173 MediaDecoderJob
* video_decoder_job
= GetMediaDecoderJob(false);
1175 EXPECT_FALSE(audio_decoder_job
->is_decoding());
1176 EXPECT_FALSE(video_decoder_job
->is_decoding());
1178 // Sending video data to player, video decoder should not start.
1179 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1180 EXPECT_FALSE(video_decoder_job
->is_decoding());
1182 // Sending audio data to player, both decoders should start now.
1183 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1184 EXPECT_TRUE(audio_decoder_job
->is_decoding());
1185 EXPECT_TRUE(video_decoder_job
->is_decoding());
1187 // No seeks should have occurred.
1188 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1189 WaitForVideoDecodeDone();
1192 TEST_F(MediaSourcePlayerTest
, StartTimeTicksResetAfterDecoderUnderruns
) {
1193 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1195 // Test start time ticks will reset after decoder job underruns.
1196 StartAudioDecoderJob();
1198 DecodeAudioDataUntilOutputBecomesAvailable();
1200 // The decoder job should finish prerolling and start prefetching.
1201 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1202 base::TimeTicks previous
= StartTimeTicks();
1204 // Let the decoder starve.
1205 TriggerPlayerStarvation();
1206 WaitForAudioDecodeDone();
1207 EXPECT_TRUE(StartTimeTicks() == previous
);
1209 // Send new data to the decoder so it can finish prefetching. This should
1210 // reset the start time ticks.
1211 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1212 EXPECT_TRUE(StartTimeTicks() != previous
);
1214 base::TimeTicks current
= StartTimeTicks();
1215 EXPECT_LE(0, (current
- previous
).InMillisecondsF());
1218 TEST_F(MediaSourcePlayerTest
, V_SecondAccessUnitIsEOSAndResumePlayAfterSeek
) {
1219 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1221 // Test MediaSourcePlayer can replay video after input EOS is reached.
1222 CreateNextTextureAndSetVideoSurface();
1223 StartVideoDecoderJob();
1225 // Send the first input chunk.
1226 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1227 WaitForVideoDecodeDone();
1229 VerifyPlaybackCompletesOnEOSDecode(true, false);
1230 VerifyCompletedPlaybackResumesOnSeekPlusStart(false, true);
1233 TEST_F(MediaSourcePlayerTest
, A_FirstAccessUnitIsEOSAndResumePlayAfterSeek
) {
1234 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1236 // Test decode of audio EOS buffer without any prior decode. See also
1237 // http://b/11696552.
1238 // Also tests that seeking+Start() after completing audio playback resumes
1240 Start(CreateAudioDemuxerConfigs(kCodecAAC
, false));
1241 VerifyPlaybackCompletesOnEOSDecode(true, true);
1242 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, false);
1245 TEST_F(MediaSourcePlayerTest
, V_FirstAccessUnitAfterSeekIsEOS
) {
1246 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1248 // Test decode of video EOS buffer, just after seeking, without any prior
1249 // decode (other than the simulated |kAborted| resulting from the seek
1251 CreateNextTextureAndSetVideoSurface();
1252 StartVideoDecoderJob();
1253 SeekPlayerWithAbort(false, base::TimeDelta());
1254 VerifyPlaybackCompletesOnEOSDecode(true, false);
1257 TEST_F(MediaSourcePlayerTest
, A_FirstAccessUnitAfterSeekIsEOS
) {
1258 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1260 // Test decode of audio EOS buffer, just after seeking, without any prior
1261 // decode (other than the simulated |kAborted| resulting from the seek
1262 // process.) See also http://b/11696552.
1263 Start(CreateAudioDemuxerConfigs(kCodecAAC
, false));
1264 SeekPlayerWithAbort(true, base::TimeDelta());
1265 VerifyPlaybackCompletesOnEOSDecode(true, true);
1268 TEST_F(MediaSourcePlayerTest
, AV_PlaybackCompletionAcrossConfigChange
) {
1269 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1271 // Test that if one stream (audio) has completed decode of EOS and the other
1272 // stream (video) processes config change, that subsequent video EOS completes
1274 // Also tests that seeking+Start() after completing playback resumes playback.
1275 CreateNextTextureAndSetVideoSurface();
1276 Start(CreateAudioVideoDemuxerConfigs());
1278 player_
.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1279 DemuxerConfigs configs
= CreateVideoDemuxerConfigs(true);
1280 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1281 false, 0, configs
)); // Video |kConfigChanged| as first unit.
1283 WaitForAudioVideoDecodeDone();
1285 EXPECT_EQ(3, demuxer_
->num_data_requests());
1287 // At no time after completing audio EOS decode, above, should the
1288 // audio decoder job resume decoding. Send and decode video EOS.
1289 VerifyPlaybackCompletesOnEOSDecode(true, false);
1290 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1293 TEST_F(MediaSourcePlayerTest
, VA_PlaybackCompletionAcrossConfigChange
) {
1294 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1296 // Test that if one stream (video) has completed decode of EOS and the other
1297 // stream (audio) processes config change, that subsequent audio EOS completes
1299 // Also tests that seeking+Start() after completing playback resumes playback.
1300 CreateNextTextureAndSetVideoSurface();
1301 Start(CreateAudioVideoDemuxerConfigs());
1303 player_
.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1304 // Audio |kConfigChanged| as first unit.
1305 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1306 true, 0, CreateAudioDemuxerConfigs(kCodecVorbis
, false)));
1308 WaitForAudioVideoDecodeDone();
1310 EXPECT_EQ(3, demuxer_
->num_data_requests());
1312 // At no time after completing video EOS decode, above, should the
1313 // video decoder job resume decoding. Send and decode audio EOS.
1314 VerifyPlaybackCompletesOnEOSDecode(true, true);
1315 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1318 TEST_F(MediaSourcePlayerTest
, AV_NoPrefetchForFinishedVideoOnAudioStarvation
) {
1319 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1321 // Test that if one stream (video) has completed decode of EOS, prefetch
1322 // resulting from player starvation occurs only for the other stream (audio),
1323 // and responding to that prefetch with EOS completes A/V playback, even if
1324 // another starvation occurs during the latter EOS's decode.
1325 CreateNextTextureAndSetVideoSurface();
1326 Start(CreateAudioVideoDemuxerConfigs());
1328 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1329 player_
.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1331 // Wait until video EOS is processed and more data (assumed to be audio) is
1333 WaitForAudioVideoDecodeDone();
1334 EXPECT_EQ(3, demuxer_
->num_data_requests());
1336 // Simulate decoder underrun to trigger prefetch while still decoding audio.
1337 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
1338 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding() &&
1339 !GetMediaDecoderJob(false)->is_decoding());
1340 TriggerPlayerStarvation();
1342 // Complete the audio decode that was in progress when simulated player
1343 // starvation was triggered.
1344 WaitForAudioDecodeDone();
1345 EXPECT_EQ(4, demuxer_
->num_data_requests());
1346 player_
.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1347 EXPECT_FALSE(GetMediaDecoderJob(false)->is_decoding());
1348 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1350 // Simulate another decoder underrun to trigger prefetch while decoding EOS.
1351 TriggerPlayerStarvation();
1352 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1355 TEST_F(MediaSourcePlayerTest
, V_StarvationDuringEOSDecode
) {
1356 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1358 // Test that video-only playback completes without further data requested when
1359 // starvation occurs during EOS decode.
1360 CreateNextTextureAndSetVideoSurface();
1361 StartVideoDecoderJob();
1362 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1363 WaitForVideoDecodeDone();
1365 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1366 player_
.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1367 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1368 TriggerPlayerStarvation();
1369 VerifyPlaybackCompletesOnEOSDecode(false, false /* ignored */);
1372 TEST_F(MediaSourcePlayerTest
, A_StarvationDuringEOSDecode
) {
1373 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1375 // Test that audio-only playback completes without further data requested when
1376 // starvation occurs during EOS decode.
1377 StartAudioDecoderJob();
1378 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1379 WaitForAudioDecodeDone();
1381 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1382 player_
.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1383 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1384 TriggerPlayerStarvation();
1385 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1388 TEST_F(MediaSourcePlayerTest
, AV_SeekDuringEOSDecodePreventsCompletion
) {
1389 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1391 // Test that seek supercedes audio+video playback completion on simultaneous
1392 // audio and video EOS decode, if SeekTo() occurs during these EOS decodes.
1393 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, true);
1396 TEST_F(MediaSourcePlayerTest
, AV_SeekDuringAudioEOSDecodePreventsCompletion
) {
1397 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1399 // Test that seek supercedes audio+video playback completion on simultaneous
1400 // audio EOS and video non-EOS decode, if SeekTo() occurs during these
1402 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, false);
1405 TEST_F(MediaSourcePlayerTest
, AV_SeekDuringVideoEOSDecodePreventsCompletion
) {
1406 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1408 // Test that seek supercedes audio+video playback completion on simultaneous
1409 // audio non-EOS and video EOS decode, if SeekTo() occurs during these
1411 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, false, true);
1414 TEST_F(MediaSourcePlayerTest
, V_SeekDuringEOSDecodePreventsCompletion
) {
1415 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1417 // Test that seek supercedes video-only playback completion on EOS decode, if
1418 // SeekTo() occurs during EOS decode.
1419 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(false, true, false, true);
1422 TEST_F(MediaSourcePlayerTest
, A_SeekDuringEOSDecodePreventsCompletion
) {
1423 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1425 // Test that seek supercedes audio-only playback completion on EOS decode, if
1426 // SeekTo() occurs during EOS decode.
1427 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, false, true, false);
1430 TEST_F(MediaSourcePlayerTest
, NoRequestForDataAfterAbort
) {
1431 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1433 // Test that the decoder will not request new data after receiving an aborted
1435 StartAudioDecoderJob();
1437 // Send an aborted access unit.
1438 player_
.OnDemuxerDataAvailable(CreateAbortedAck(true));
1439 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1440 WaitForAudioDecodeDone();
1442 // No request will be sent for new data.
1443 EXPECT_EQ(1, demuxer_
->num_data_requests());
1445 // No seek requests should have occurred.
1446 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1449 TEST_F(MediaSourcePlayerTest
, DemuxerDataArrivesAfterRelease
) {
1450 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1452 // Test that the decoder should not crash if demuxer data arrives after
1454 StartAudioDecoderJob();
1457 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1459 // The media codec bridge should have been released.
1460 EXPECT_FALSE(player_
.IsPlaying());
1462 // No further data should have been requested.
1463 EXPECT_EQ(1, demuxer_
->num_data_requests());
1465 // No seek requests should have occurred.
1466 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1469 TEST_F(MediaSourcePlayerTest
, BrowserSeek_RegularSeekPendsBrowserSeekDone
) {
1470 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1472 // Test that a browser seek, once started, delays a newly arrived regular
1473 // SeekTo() request's demuxer seek until the browser seek is done.
1474 BrowserSeekPlayer(false);
1476 // Simulate renderer requesting a regular seek while browser seek in progress.
1477 player_
.SeekTo(base::TimeDelta());
1479 // Simulate browser seek is done. Confirm player requests the regular seek,
1480 // still has no video codec configured, and has not requested any
1481 // further data since the surface change event became pending in
1482 // BrowserSeekPlayer().
1483 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1484 player_
.OnDemuxerSeekDone(base::TimeDelta());
1485 EXPECT_EQ(2, demuxer_
->num_seek_requests());
1486 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
1488 // Simulate regular seek is done and confirm player requests more data for
1490 player_
.OnDemuxerSeekDone(kNoTimestamp());
1491 EXPECT_FALSE(GetMediaCodecBridge(false));
1492 EXPECT_EQ(3, demuxer_
->num_data_requests());
1493 EXPECT_EQ(2, demuxer_
->num_seek_requests());
1494 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1495 EXPECT_TRUE(GetMediaCodecBridge(false));
1496 WaitForVideoDecodeDone();
1499 TEST_F(MediaSourcePlayerTest
, BrowserSeek_InitialReleaseAndStart
) {
1500 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1502 // Test that no browser seek is requested if player Release() + Start() occurs
1503 // prior to receiving any data.
1504 CreateNextTextureAndSetVideoSurface();
1505 StartVideoDecoderJob();
1508 // Pass a new non-empty surface.
1509 CreateNextTextureAndSetVideoSurface();
1513 // No data request is issued since there is still one pending.
1514 EXPECT_EQ(1, demuxer_
->num_data_requests());
1515 EXPECT_FALSE(GetMediaCodecBridge(false));
1517 // No browser seek is needed.
1518 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1519 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
1520 EXPECT_EQ(2, demuxer_
->num_data_requests());
1521 WaitForVideoDecodeDone();
1524 TEST_F(MediaSourcePlayerTest
, BrowserSeek_MidStreamReleaseAndStart
) {
1525 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1527 // Test that one browser seek is requested if player Release() + Start(), with
1528 // video data received between Release() and Start().
1529 BrowserSeekPlayer(true);
1531 // Simulate browser seek is done and confirm player requests more data.
1532 player_
.OnDemuxerSeekDone(base::TimeDelta());
1533 EXPECT_EQ(3, demuxer_
->num_data_requests());
1534 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1537 TEST_F(MediaSourcePlayerTest
, PrerollAudioAfterSeek
) {
1538 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1540 // Test decoder job will preroll the media to the seek position.
1541 StartAudioDecoderJob();
1543 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1544 EXPECT_TRUE(IsPrerolling(true));
1545 PrerollDecoderToTime(
1546 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1549 TEST_F(MediaSourcePlayerTest
, PrerollVideoAfterSeek
) {
1550 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1552 // Test decoder job will preroll the media to the seek position.
1553 CreateNextTextureAndSetVideoSurface();
1554 StartVideoDecoderJob();
1556 SeekPlayerWithAbort(false, base::TimeDelta::FromMilliseconds(100));
1557 EXPECT_TRUE(IsPrerolling(false));
1558 PrerollDecoderToTime(
1559 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1562 TEST_F(MediaSourcePlayerTest
, SeekingAfterCompletingPrerollRestartsPreroll
) {
1563 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1565 // Test decoder job will begin prerolling upon seek, when it was not
1566 // prerolling prior to the seek.
1567 StartAudioDecoderJob();
1568 MediaDecoderJob
* decoder_job
= GetMediaDecoderJob(true);
1569 EXPECT_TRUE(IsPrerolling(true));
1571 // Complete the initial preroll by feeding data to the decoder.
1572 DecodeAudioDataUntilOutputBecomesAvailable();
1573 EXPECT_FALSE(IsPrerolling(true));
1575 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500));
1577 // Prerolling should have begun again.
1578 EXPECT_TRUE(IsPrerolling(true));
1579 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF());
1581 // Send data at and after the seek position. Prerolling should complete.
1582 for (int i
= 0; i
< 4; ++i
) {
1583 DemuxerData data
= CreateReadFromDemuxerAckForAudio(i
);
1584 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(
1585 500 + 30 * (i
- 1));
1586 player_
.OnDemuxerDataAvailable(data
);
1587 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1588 WaitForAudioDecodeDone();
1590 EXPECT_LT(500.0, player_
.GetCurrentTime().InMillisecondsF());
1591 EXPECT_FALSE(IsPrerolling(true));
1593 // Throughout this test, we should have not re-created the media codec bridge,
1594 // so IsPrerolling() transition from false to true was not due to constructor
1595 // initialization. It was due to BeginPrerolling().
1596 EXPECT_EQ(decoder_job
, GetMediaDecoderJob(true));
1599 TEST_F(MediaSourcePlayerTest
, PrerollContinuesAcrossReleaseAndStart
) {
1600 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1602 // Test decoder job will resume media prerolling if interrupted by Release()
1604 StartAudioDecoderJob();
1606 base::TimeDelta target_timestamp
= base::TimeDelta::FromMilliseconds(100);
1607 SeekPlayerWithAbort(true, target_timestamp
);
1608 EXPECT_TRUE(IsPrerolling(true));
1609 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1611 // Send some data before the seek position.
1612 // Test uses 'large' number of iterations because decoder job may not get
1613 // MEDIA_CODEC_OK output status until after a few dequeue output attempts.
1614 // This allows decoder status to stabilize prior to AU timestamp reaching
1615 // the preroll target.
1617 for (int i
= 0; i
< 10; ++i
) {
1618 data
= CreateReadFromDemuxerAckForAudio(3);
1619 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(i
* 10);
1621 // While still prerolling, Release() and Start() the player.
1623 // The decoder is still decoding and will not be immediately released.
1624 EXPECT_TRUE(GetMediaCodecBridge(true));
1625 Resume(false, false);
1627 player_
.OnDemuxerDataAvailable(data
);
1628 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1629 WaitForAudioDecodeDone();
1631 EXPECT_TRUE(IsPrerolling(true));
1633 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1634 EXPECT_TRUE(IsPrerolling(true));
1636 // Send data after the seek position.
1637 PrerollDecoderToTime(true, target_timestamp
, target_timestamp
, true);
1640 // Flaky on Android: crbug.com/419122.
1641 #if defined(OS_ANDROID)
1642 #define MAYBE_PrerollContinuesAcrossConfigChange \
1643 DISABLED_PrerollContinuesAcrossConfigChange
1645 #define MAYBE_PrerollContinuesAcrossConfigChange \
1646 PrerollContinuesAcrossConfigChange
1648 TEST_F(MediaSourcePlayerTest
, MAYBE_PrerollContinuesAcrossConfigChange
) {
1649 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1651 // Test decoder job will resume media prerolling if interrupted by
1652 // |kConfigChanged| and OnDemuxerConfigsAvailable().
1653 StartAudioDecoderJob();
1655 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1656 EXPECT_TRUE(IsPrerolling(true));
1657 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1659 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, true);
1661 // In response to data request, simulate that demuxer signals config change by
1662 // sending an AU with |kConfigChanged|.
1663 DemuxerData data
= CreateReadFromDemuxerAckWithConfigChanged(
1665 player_
.OnDemuxerDataAvailable(data
);
1667 PrerollDecoderToTime(
1668 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1671 TEST_F(MediaSourcePlayerTest
, PrerollContinuesAfterUnchangedConfigs
) {
1672 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1674 // Test decoder job will resume media prerolling if interrupted by a config
1675 // change access unit with unchanged configs.
1676 StartAudioDecoderJob();
1678 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1679 EXPECT_TRUE(IsPrerolling(true));
1680 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1682 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, false);
1684 // In response to data request, simulate that demuxer signals config change by
1685 // sending an AU with |kConfigChanged|.
1686 DemuxerData data
= CreateReadFromDemuxerAckWithConfigChanged(
1688 player_
.OnDemuxerDataAvailable(data
);
1689 PrerollDecoderToTime(
1690 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1693 TEST_F(MediaSourcePlayerTest
, AudioPrerollFinishesBeforeVideo
) {
1694 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1696 // Test that after audio finishes prerolling, it will wait for video to finish
1697 // prerolling before advancing together.
1698 CreateNextTextureAndSetVideoSurface();
1699 Start(CreateAudioVideoDemuxerConfigs());
1702 base::TimeDelta seek_position
= base::TimeDelta::FromMilliseconds(100);
1703 player_
.SeekTo(seek_position
);
1704 player_
.OnDemuxerDataAvailable(CreateAbortedAck(true));
1705 player_
.OnDemuxerDataAvailable(CreateAbortedAck(false));
1706 WaitForDecodeDone(true, true);
1708 // Verify that the seek is requested.
1709 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1710 player_
.OnDemuxerSeekDone(kNoTimestamp());
1711 EXPECT_EQ(4, demuxer_
->num_data_requests());
1712 EXPECT_EQ(player_
.GetCurrentTime().InMillisecondsF(), 100.0);
1713 EXPECT_EQ(GetPrerollTimestamp().InMillisecondsF(), 100.0);
1715 // Send both audio and video data to finish prefetching.
1716 base::TimeDelta seek_ack_position
= base::TimeDelta::FromMilliseconds(70);
1717 DemuxerData audio_data
= CreateReadFromDemuxerAckForAudio(0);
1718 audio_data
.access_units
[0].timestamp
= seek_ack_position
;
1719 DemuxerData video_data
= CreateReadFromDemuxerAckForVideo(false);
1720 video_data
.access_units
[0].timestamp
= seek_ack_position
;
1721 player_
.OnDemuxerDataAvailable(audio_data
);
1722 player_
.OnDemuxerDataAvailable(video_data
);
1723 WaitForAudioDecodeDone();
1724 WaitForVideoDecodeDone();
1726 // Send audio data at and after the seek position. Audio should finish
1727 // prerolling and stop decoding.
1728 EXPECT_EQ(6, demuxer_
->num_data_requests());
1729 PrerollDecoderToTime(true, seek_position
, seek_position
, true);
1730 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
1731 EXPECT_FALSE(IsPrerolling(true));
1732 EXPECT_TRUE(IsPrerolling(false));
1734 // Send video data to let video finish prerolling.
1735 PrerollDecoderToTime(false, seek_position
, seek_position
, false);
1736 EXPECT_FALSE(IsPrerolling(false));
1738 // Both audio and video decoders should start decoding again.
1739 player_
.OnDemuxerDataAvailable(audio_data
);
1740 player_
.OnDemuxerDataAvailable(video_data
);
1741 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1742 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1745 TEST_F(MediaSourcePlayerTest
, SimultaneousAudioVideoConfigChange
) {
1746 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1748 // Test that the player allows simultaneous audio and video config change,
1749 // such as might occur during OnPrefetchDone() if next access unit for both
1750 // audio and video jobs is |kConfigChanged|.
1751 CreateNextTextureAndSetVideoSurface();
1752 Start(CreateAudioVideoDemuxerConfigs());
1753 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1754 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1755 EXPECT_TRUE(GetMediaCodecBridge(true));
1756 EXPECT_TRUE(GetMediaCodecBridge(false));
1757 EnableAdaptiveVideoPlayback(false);
1758 WaitForAudioVideoDecodeDone();
1760 // If audio or video hasn't finished prerolling, let them finish it.
1761 if (IsPrerolling(true))
1762 PrerollDecoderToTime(true, base::TimeDelta(), base::TimeDelta(), true);
1763 if (IsPrerolling(false))
1764 PrerollDecoderToTime(false, base::TimeDelta(), base::TimeDelta(), false);
1765 int expected_num_data_requests
= demuxer_
->num_data_requests();
1767 // Simulate audio |kConfigChanged| prefetched as standalone access unit.
1768 DemuxerConfigs audio_configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, true);
1769 player_
.OnDemuxerDataAvailable(
1770 CreateReadFromDemuxerAckWithConfigChanged(true, 0, audio_configs
));
1772 // Simulate video |kConfigChanged| prefetched as standalone access unit.
1773 player_
.OnDemuxerDataAvailable(
1774 CreateReadFromDemuxerAckWithConfigChanged(
1775 false, 0, CreateVideoDemuxerConfigs(true)));
1776 EXPECT_EQ(expected_num_data_requests
+ 2, demuxer_
->num_data_requests());
1777 EXPECT_TRUE(IsDrainingDecoder(true));
1778 EXPECT_TRUE(IsDrainingDecoder(false));
1780 // Waiting for decoder to finish draining.
1781 while (IsDrainingDecoder(true) || IsDrainingDecoder(false))
1782 message_loop_
.RunUntilIdle();
1785 TEST_F(MediaSourcePlayerTest
,
1786 SimultaneousAudioVideoConfigChangeWithAdaptivePlayback
) {
1787 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1789 // Test that the player allows simultaneous audio and video config change with
1790 // adaptive video playback enabled.
1791 CreateNextTextureAndSetVideoSurface();
1792 Start(CreateAudioVideoDemuxerConfigs());
1793 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1794 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1795 EXPECT_EQ(4, demuxer_
->num_data_requests());
1796 EXPECT_TRUE(GetMediaCodecBridge(true));
1797 EXPECT_TRUE(GetMediaCodecBridge(false));
1798 EnableAdaptiveVideoPlayback(true);
1799 WaitForAudioVideoDecodeDone();
1801 // If audio or video hasn't finished prerolling, let them finish it.
1802 if (IsPrerolling(true))
1803 PrerollDecoderToTime(true, base::TimeDelta(), base::TimeDelta(), true);
1804 if (IsPrerolling(false))
1805 PrerollDecoderToTime(false, base::TimeDelta(), base::TimeDelta(), false);
1806 int expected_num_data_requests
= demuxer_
->num_data_requests();
1808 // Simulate audio |kConfigChanged| prefetched as standalone access unit.
1809 DemuxerConfigs audio_configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, true);
1810 player_
.OnDemuxerDataAvailable(
1811 CreateReadFromDemuxerAckWithConfigChanged(true, 0, audio_configs
));
1813 // Simulate video |kConfigChanged| prefetched as standalone access unit.
1814 player_
.OnDemuxerDataAvailable(
1815 CreateReadFromDemuxerAckWithConfigChanged(
1816 false, 0, CreateVideoDemuxerConfigs(true)));
1817 EXPECT_EQ(expected_num_data_requests
+ 2, demuxer_
->num_data_requests());
1818 EXPECT_TRUE(IsDrainingDecoder(true));
1819 EXPECT_FALSE(IsDrainingDecoder(false));
1821 // Waiting for audio decoder to finish draining.
1822 while (IsDrainingDecoder(true))
1823 message_loop_
.RunUntilIdle();
1826 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInPrefetchUnit0
) {
1827 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1829 // Test that the player detects need for and requests demuxer configs if
1830 // the |kConfigChanged| unit is the very first unit in the set of units
1831 // received in OnDemuxerDataAvailable() ostensibly while
1832 // |PREFETCH_DONE_EVENT_PENDING|.
1833 StartConfigChange(true, true, 0, false);
1834 WaitForAudioDecodeDone();
1837 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInPrefetchUnit1
) {
1838 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1840 // Test that the player detects need for and requests demuxer configs if
1841 // the |kConfigChanged| unit is not the first unit in the set of units
1842 // received in OnDemuxerDataAvailable() ostensibly while
1843 // |PREFETCH_DONE_EVENT_PENDING|.
1844 StartConfigChange(true, true, 1, false);
1845 WaitForAudioDecodeDone();
1848 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInUnit0AfterPrefetch
) {
1849 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1851 // Test that the player detects need for and requests demuxer configs if
1852 // the |kConfigChanged| unit is the very first unit in the set of units
1853 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1855 StartConfigChange(true, false, 0, false);
1856 WaitForAudioDecodeDone();
1859 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInUnit1AfterPrefetch
) {
1860 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1862 // Test that the player detects need for and requests demuxer configs if
1863 // the |kConfigChanged| unit is not the first unit in the set of units
1864 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1866 StartConfigChange(true, false, 1, false);
1867 WaitForAudioDecodeDone();
1870 TEST_F(MediaSourcePlayerTest
, BrowserSeek_PrerollAfterBrowserSeek
) {
1871 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1873 // Test decoder job will preroll the media to the actual seek position
1874 // resulting from a browser seek.
1875 BrowserSeekPlayer(false);
1877 // Simulate browser seek is done, but to a later time than was requested.
1878 EXPECT_LT(player_
.GetCurrentTime().InMillisecondsF(), 100);
1879 player_
.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100));
1880 // Because next AU is not I-frame, MediaCodecBridge will not be recreated.
1881 EXPECT_FALSE(GetMediaCodecBridge(false));
1882 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1883 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1884 EXPECT_EQ(3, demuxer_
->num_data_requests());
1886 PrerollDecoderToTime(
1887 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1890 TEST_F(MediaSourcePlayerTest
, VideoDemuxerConfigChange
) {
1891 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1893 // Test that video config change notification results in creating a new
1894 // video codec without any browser seek.
1895 StartConfigChange(false, true, 1, false);
1897 // New video codec should have been created and configured, without any
1899 EXPECT_TRUE(GetMediaCodecBridge(false));
1900 EXPECT_EQ(3, demuxer_
->num_data_requests());
1901 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1903 // 2 codecs should have been created, one before the config change, and one
1905 EXPECT_EQ(2, manager_
.num_resources_requested());
1906 WaitForVideoDecodeDone();
1909 TEST_F(MediaSourcePlayerTest
, VideoDemuxerConfigChangeWithAdaptivePlayback
) {
1910 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1912 // Test that if codec supports adaptive playback, no new codec should be
1913 // created beyond the one used to decode the prefetch media data prior to
1914 // the kConfigChanged.
1915 StartConfigChange(false, true, 1, true);
1917 // No browser seek should be needed.
1918 EXPECT_TRUE(GetMediaCodecBridge(false));
1919 EXPECT_EQ(3, demuxer_
->num_data_requests());
1920 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1922 // Only 1 codec should have been created so far.
1923 EXPECT_EQ(1, manager_
.num_resources_requested());
1924 WaitForVideoDecodeDone();
1927 TEST_F(MediaSourcePlayerTest
, DecoderDrainInterruptedBySeek
) {
1928 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1930 // Test if a decoder is being drained while receiving a seek request, draining
1932 SendConfigChangeToDecoder(true, false, 0, false);
1933 EXPECT_TRUE(IsDrainingDecoder(true));
1935 player_
.SeekTo(base::TimeDelta::FromMilliseconds(100));
1936 WaitForAudioDecodeDone();
1937 EXPECT_FALSE(IsDrainingDecoder(true));
1938 player_
.OnDemuxerSeekDone(kNoTimestamp());
1940 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1941 EXPECT_EQ(4, demuxer_
->num_data_requests());
1944 TEST_F(MediaSourcePlayerTest
, DecoderDrainInterruptedByRelease
) {
1945 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1947 // Test if a decoder is being drained while receiving a release request,
1948 // draining is canceled.
1949 SendConfigChangeToDecoder(true, false, 0, false);
1950 EXPECT_TRUE(IsDrainingDecoder(true));
1953 WaitForAudioDecodeDone();
1954 EXPECT_EQ(3, demuxer_
->num_data_requests());
1955 EXPECT_FALSE(IsDrainingDecoder(true));
1957 EXPECT_FALSE(GetMediaCodecBridge(true));
1958 EXPECT_FALSE(player_
.IsPlaying());
1961 EXPECT_TRUE(player_
.IsPlaying());
1962 EXPECT_EQ(3, demuxer_
->num_data_requests());
1965 TEST_F(MediaSourcePlayerTest
, DecoderDrainInterruptedBySurfaceChange
) {
1966 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1968 // Test if a video decoder is being drained while surface changes, draining
1970 SendConfigChangeToDecoder(false, false, 0, false);
1971 EXPECT_TRUE(IsDrainingDecoder(false));
1973 CreateNextTextureAndSetVideoSurface();
1974 WaitForVideoDecodeDone();
1976 EXPECT_FALSE(IsDrainingDecoder(false));
1977 EXPECT_TRUE(player_
.IsPlaying());
1979 // The frame after the config change should always be an iframe, so no browser
1980 // seek is needed when recreating the video decoder due to surface change.
1981 EXPECT_TRUE(GetMediaCodecBridge(false));
1982 EXPECT_EQ(4, demuxer_
->num_data_requests());
1983 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1986 TEST_F(MediaSourcePlayerTest
,
1987 BrowserSeek_DecoderStarvationWhilePendingSurfaceChange
) {
1988 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1990 // Test video decoder starvation while handling a pending surface change
1991 // should not cause any crashes.
1992 CreateNextTextureAndSetVideoSurface();
1993 StartVideoDecoderJob();
1994 DemuxerData data
= CreateReadFromDemuxerAckForVideo(false);
1995 player_
.OnDemuxerDataAvailable(data
);
1997 // Trigger a surface change and decoder starvation.
1998 CreateNextTextureAndSetVideoSurface();
1999 TriggerPlayerStarvation();
2000 WaitForVideoDecodeDone();
2001 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
2003 // Surface change should trigger a seek.
2004 player_
.OnDemuxerDataAvailable(data
);
2005 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
2006 player_
.OnDemuxerSeekDone(base::TimeDelta());
2007 // After seek is done, prefetch is handled first. MediaCodecBridge is not
2008 // created at this moment.
2009 EXPECT_FALSE(GetMediaCodecBridge(false));
2011 // A new data request should be sent.
2012 EXPECT_EQ(3, demuxer_
->num_data_requests());
2015 TEST_F(MediaSourcePlayerTest
, ReleaseWithOnPrefetchDoneAlreadyPosted
) {
2016 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2018 // Test if OnPrefetchDone() had already been posted before and is executed
2019 // after Release(), then player does not DCHECK. This test is fragile to
2020 // change to MediaDecoderJob::Prefetch() implementation; it assumes task
2021 // is posted to run |prefetch_cb| if the job already HasData().
2022 // TODO(wolenetz): Remove MSP::set_decode_callback_for_testing() if this test
2023 // becomes obsolete. See http://crbug.com/304234.
2024 StartAudioDecoderJob();
2026 // Escape the original prefetch by decoding a single access unit.
2027 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
2028 WaitForAudioDecodeDone();
2030 // Prime the job with a few more access units, so that a later prefetch,
2031 // triggered by starvation to simulate decoder underrun, can trivially
2032 // post task to run OnPrefetchDone().
2033 player_
.OnDemuxerDataAvailable(
2034 CreateReadFromDemuxerAckWithConfigChanged(
2035 true, 4, CreateAudioDemuxerConfigs(kCodecVorbis
, false)));
2036 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
2038 // Simulate decoder underrun, so trivial prefetch starts while still decoding.
2039 // The prefetch and posting of OnPrefetchDone() will not occur until next
2040 // MediaDecoderCallBack() occurs.
2041 TriggerPlayerStarvation();
2043 // Upon the next successful decode callback, post a task to call Release() on
2044 // the |player_|, such that the trivial OnPrefetchDone() task posting also
2045 // occurs and should execute after the Release().
2046 OnNextTestDecodeCallbackPostTaskToReleasePlayer();
2048 WaitForAudioDecodeDone();
2049 EXPECT_TRUE(decoder_callback_hook_executed_
);
2051 EXPECT_EQ(3, demuxer_
->num_data_requests());
2053 // Player should not request any new data since the access units haven't
2054 // been fully decoded yet.
2055 Resume(false, false);
2058 TEST_F(MediaSourcePlayerTest
, SeekToThenReleaseThenDemuxerSeekAndDone
) {
2059 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2061 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
2062 // has not yet been sent, then the seek request is sent after Release(). Also,
2063 // test if OnDemuxerSeekDone() occurs prior to next Start(), then the player
2064 // will resume correct post-seek preroll upon Start().
2065 StartAudioDecoderJobAndSeekToWhileDecoding(
2066 base::TimeDelta::FromMilliseconds(100));
2068 EXPECT_EQ(0, demuxer_
->num_seek_requests());
2069 WaitForAudioDecodeDone();
2070 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2072 player_
.OnDemuxerSeekDone(kNoTimestamp());
2073 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2074 EXPECT_FALSE(GetMediaCodecBridge(true));
2075 EXPECT_FALSE(player_
.IsPlaying());
2077 // Player should begin prefetch and resume preroll upon Start().
2078 EXPECT_EQ(2, demuxer_
->num_data_requests());
2079 Resume(true, false);
2080 EXPECT_TRUE(IsPrerolling(true));
2081 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2083 // No further seek should have been requested since Release(), above.
2084 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2087 TEST_F(MediaSourcePlayerTest
, SeekToThenReleaseThenDemuxerSeekThenStart
) {
2088 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2090 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
2091 // has not yet been sent, then the seek request is sent after Release(). Also,
2092 // test if OnDemuxerSeekDone() does not occur until after the next Start(),
2093 // then the player remains pending seek done until (and resumes correct
2094 // post-seek preroll after) OnDemuxerSeekDone().
2095 StartAudioDecoderJobAndSeekToWhileDecoding(
2096 base::TimeDelta::FromMilliseconds(100));
2098 EXPECT_EQ(0, demuxer_
->num_seek_requests());
2100 // Player should not prefetch upon Start() nor create the media codec bridge,
2101 // due to awaiting DemuxerSeekDone.
2102 EXPECT_EQ(2, demuxer_
->num_data_requests());
2103 Resume(false, false);
2105 WaitForAudioDecodeDone();
2106 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2107 player_
.OnDemuxerSeekDone(kNoTimestamp());
2108 EXPECT_TRUE(GetMediaDecoderJob(true));
2109 EXPECT_TRUE(IsPrerolling(true));
2110 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2111 EXPECT_EQ(3, demuxer_
->num_data_requests());
2113 // No further seek should have been requested since Release(), above.
2114 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2117 TEST_F(MediaSourcePlayerTest
, SeekToThenDemuxerSeekThenReleaseThenSeekDone
) {
2118 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2120 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC
2121 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the
2122 // player will resume correct post-seek preroll upon Start().
2123 StartAudioDecoderJobAndSeekToWhileDecoding(
2124 base::TimeDelta::FromMilliseconds(100));
2125 WaitForAudioDecodeDone();
2126 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2129 player_
.OnDemuxerSeekDone(kNoTimestamp());
2130 EXPECT_FALSE(player_
.IsPlaying());
2131 EXPECT_FALSE(GetMediaCodecBridge(true));
2132 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2134 // Player should begin prefetch and resume preroll upon Start().
2135 EXPECT_EQ(2, demuxer_
->num_data_requests());
2136 Resume(true, false);
2137 EXPECT_TRUE(IsPrerolling(true));
2138 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2140 // No further seek should have been requested since before Release(), above.
2141 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2144 TEST_F(MediaSourcePlayerTest
, SeekToThenReleaseThenStart
) {
2145 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2147 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC
2148 // request and OnDemuxerSeekDone() does not occur until after the next
2149 // Start(), then the player remains pending seek done until (and resumes
2150 // correct post-seek preroll after) OnDemuxerSeekDone().
2151 StartAudioDecoderJobAndSeekToWhileDecoding(
2152 base::TimeDelta::FromMilliseconds(100));
2153 WaitForAudioDecodeDone();
2154 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2157 EXPECT_EQ(2, demuxer_
->num_data_requests());
2158 Resume(false, false);
2160 player_
.OnDemuxerSeekDone(kNoTimestamp());
2161 EXPECT_FALSE(GetMediaCodecBridge(true));
2162 EXPECT_TRUE(IsPrerolling(true));
2163 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2164 EXPECT_EQ(3, demuxer_
->num_data_requests());
2166 // No further seek should have been requested since before Release(), above.
2167 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2170 TEST_F(MediaSourcePlayerTest
, ConfigChangedThenReleaseThenStart
) {
2171 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2173 // Test if Release() occurs after |kConfigChanged| is processed, new data
2174 // requested of demuxer, and the requested data arrive before the next
2175 // Start(), then the player starts to decode the new data without any seek.
2176 StartConfigChange(true, true, 0, false);
2179 EXPECT_TRUE(GetMediaCodecBridge(true));
2180 EXPECT_FALSE(player_
.IsPlaying());
2181 EXPECT_EQ(3, demuxer_
->num_data_requests());
2182 player_
.OnDemuxerDataAvailable(
2183 CreateReadFromDemuxerAckWithConfigChanged(
2184 true, 4, CreateAudioDemuxerConfigs(kCodecVorbis
, false)));
2185 WaitForAudioDecodeDone();
2186 EXPECT_FALSE(GetMediaCodecBridge(true));
2188 // Player should resume upon Start(), even without further configs supplied.
2190 EXPECT_TRUE(player_
.IsPlaying());
2191 EXPECT_EQ(3, demuxer_
->num_data_requests());
2192 EXPECT_EQ(0, demuxer_
->num_seek_requests());
2193 WaitForAudioDecodeDone();
2196 TEST_F(MediaSourcePlayerTest
, BrowserSeek_ThenReleaseThenDemuxerSeekDone
) {
2197 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2199 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
2200 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() occurs
2201 // before the next Start()+SetVideoSurface(), then the player will resume
2202 // correct post-seek preroll upon Start()+SetVideoSurface().
2203 BrowserSeekPlayer(false);
2204 base::TimeDelta expected_preroll_timestamp
= player_
.GetCurrentTime();
2207 player_
.OnDemuxerSeekDone(expected_preroll_timestamp
);
2208 EXPECT_FALSE(player_
.IsPlaying());
2209 EXPECT_FALSE(GetMediaCodecBridge(false));
2210 EXPECT_EQ(expected_preroll_timestamp
, GetPrerollTimestamp());
2212 // Player should begin prefetch and resume preroll upon Start().
2213 EXPECT_EQ(2, demuxer_
->num_data_requests());
2214 CreateNextTextureAndSetVideoSurface();
2215 Resume(false, true);
2216 EXPECT_TRUE(IsPrerolling(false));
2217 EXPECT_EQ(expected_preroll_timestamp
, GetPrerollTimestamp());
2218 EXPECT_EQ(expected_preroll_timestamp
, player_
.GetCurrentTime());
2220 // No further seek should have been requested since BrowserSeekPlayer().
2221 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2224 TEST_F(MediaSourcePlayerTest
, BrowserSeek_ThenReleaseThenStart
) {
2225 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2227 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
2228 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
2229 // occur until after the next Start()+SetVideoSurface(), then the player
2230 // remains pending seek done until (and resumes correct post-seek preroll
2231 // after) OnDemuxerSeekDone().
2232 BrowserSeekPlayer(false);
2233 base::TimeDelta expected_preroll_timestamp
= player_
.GetCurrentTime();
2236 EXPECT_EQ(2, demuxer_
->num_data_requests());
2237 CreateNextTextureAndSetVideoSurface();
2238 Resume(false, false);
2240 player_
.OnDemuxerSeekDone(expected_preroll_timestamp
);
2241 // Prefetch takes place first, and the decoder is not created yet.
2242 EXPECT_FALSE(GetMediaCodecBridge(false));
2243 EXPECT_TRUE(IsPrerolling(false));
2244 EXPECT_EQ(expected_preroll_timestamp
, GetPrerollTimestamp());
2245 EXPECT_EQ(expected_preroll_timestamp
, player_
.GetCurrentTime());
2246 EXPECT_EQ(3, demuxer_
->num_data_requests());
2248 // No further seek should have been requested since BrowserSeekPlayer().
2249 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2251 // Decoder will be created once data is received.
2252 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
2253 EXPECT_TRUE(GetMediaCodecBridge(false));
2254 WaitForVideoDecodeDone();
2257 // TODO(xhwang): Once we add tests to cover DrmBridge, update this test to
2258 // also verify that the job is successfully created if SetDrmBridge(), Start()
2259 // and eventually OnMediaCrypto() occur. This would increase test coverage of
2260 // http://crbug.com/313470 and allow us to remove inspection of internal player
2261 // pending event state. See http://crbug.com/313860.
2262 TEST_F(MediaSourcePlayerTest
, SurfaceChangeClearedEvenIfMediaCryptoAbsent
) {
2263 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2265 // Test that |SURFACE_CHANGE_EVENT_PENDING| is not pending after
2266 // SetVideoSurface() for a player configured for encrypted video, when the
2267 // player has not yet received media crypto.
2268 DemuxerConfigs configs
= CreateVideoDemuxerConfigs(false);
2269 configs
.is_video_encrypted
= true;
2271 player_
.OnDemuxerConfigsAvailable(configs
);
2272 CreateNextTextureAndSetVideoSurface();
2273 EXPECT_FALSE(GetMediaCodecBridge(false));
2276 TEST_F(MediaSourcePlayerTest
, CurrentTimeUpdatedWhileDecoderStarved
) {
2277 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2279 // Test that current time is updated while decoder is starved.
2280 StartAudioDecoderJob();
2281 DecodeAudioDataUntilOutputBecomesAvailable();
2283 // Trigger starvation while the decoder is decoding.
2284 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
2285 manager_
.ResetTimestampUpdated();
2286 TriggerPlayerStarvation();
2287 WaitForAudioDecodeDone();
2289 // Current time should be updated.
2290 EXPECT_TRUE(manager_
.timestamp_updated());
2293 TEST_F(MediaSourcePlayerTest
, CurrentTimeKeepsIncreasingAfterConfigChange
) {
2294 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2296 // Test current time keep on increasing after audio config change.
2297 // Test that current time is updated while decoder is starved.
2298 StartAudioDecoderJob();
2300 DecodeAudioDataUntilOutputBecomesAvailable();
2302 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
, true);
2303 DemuxerData data
= CreateReadFromDemuxerAckWithConfigChanged(
2305 player_
.OnDemuxerDataAvailable(data
);
2306 WaitForAudioDecodeDone();
2307 DecodeAudioDataUntilOutputBecomesAvailable();
2310 TEST_F(MediaSourcePlayerTest
, VideoMetadataChangeAfterConfigChange
) {
2311 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2313 // Test that after a config change, metadata change will be happen
2314 // after decoder is drained.
2315 StartConfigChange(false, true, 2, false);
2316 EXPECT_EQ(1, manager_
.num_metadata_changes());
2317 EXPECT_FALSE(IsDrainingDecoder(false));
2319 // Create video data with new resolutions.
2320 DemuxerData data
= CreateReadFromDemuxerAckForVideo(true);
2322 // Wait for the metadata change.
2323 while(manager_
.num_metadata_changes() == 1) {
2324 player_
.OnDemuxerDataAvailable(data
);
2325 WaitForVideoDecodeDone();
2327 EXPECT_EQ(2, manager_
.num_metadata_changes());
2328 WaitForVideoDecodeDone();
2331 } // namespace media