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/media_codec_bridge.h"
12 #include "media/base/android/media_drm_bridge.h"
13 #include "media/base/android/media_player_manager.h"
14 #include "media/base/android/media_source_player.h"
15 #include "media/base/bind_to_current_loop.h"
16 #include "media/base/decoder_buffer.h"
17 #include "media/base/test_data_util.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "ui/gl/android/surface_texture.h"
23 // Helper macro to skip the test if MediaCodecBridge isn't available.
24 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
26 if (!MediaCodecBridge::IsAvailable()) { \
27 VLOG(0) << "Could not run test - not supported on device."; \
32 const base::TimeDelta kDefaultDuration
=
33 base::TimeDelta::FromMilliseconds(10000);
35 // TODO(wolenetz/qinmin): Simplify tests with more effective mock usage, and
36 // fix flaky pointer-based MDJ inequality testing. See http://crbug.com/327839.
38 // Mock of MediaPlayerManager for testing purpose.
39 class MockMediaPlayerManager
: public MediaPlayerManager
{
41 explicit MockMediaPlayerManager(base::MessageLoop
* message_loop
)
42 : message_loop_(message_loop
),
43 playback_completed_(false),
44 num_resources_requested_(0),
45 num_resources_released_(0),
46 timestamp_updated_(false) {}
47 virtual ~MockMediaPlayerManager() {}
49 // MediaPlayerManager implementation.
50 virtual MediaResourceGetter
* GetMediaResourceGetter() OVERRIDE
{
53 virtual void OnTimeUpdate(int player_id
,
54 base::TimeDelta current_time
) OVERRIDE
{
55 timestamp_updated_
= true;
57 virtual void OnMediaMetadataChanged(
58 int player_id
, base::TimeDelta duration
, int width
, int height
,
59 bool success
) OVERRIDE
{}
60 virtual void OnPlaybackComplete(int player_id
) OVERRIDE
{
61 playback_completed_
= true;
62 if (message_loop_
->is_running())
63 message_loop_
->Quit();
65 virtual void OnMediaInterrupted(int player_id
) OVERRIDE
{}
66 virtual void OnBufferingUpdate(int player_id
, int percentage
) OVERRIDE
{}
67 virtual void OnSeekComplete(int player_id
,
68 const base::TimeDelta
& current_time
) OVERRIDE
{}
69 virtual void OnError(int player_id
, int error
) OVERRIDE
{}
70 virtual void OnVideoSizeChanged(int player_id
, int width
,
71 int height
) OVERRIDE
{}
72 virtual MediaPlayerAndroid
* GetFullscreenPlayer() OVERRIDE
{ return NULL
; }
73 virtual MediaPlayerAndroid
* GetPlayer(int player_id
) OVERRIDE
{ return NULL
; }
74 virtual void DestroyAllMediaPlayers() OVERRIDE
{}
75 virtual MediaDrmBridge
* GetDrmBridge(int cdm_id
) OVERRIDE
{ return NULL
; }
76 virtual void RequestFullScreen(int player_id
) OVERRIDE
{}
77 virtual void OnSessionCreated(int cdm_id
,
79 const std::string
& web_session_id
) OVERRIDE
{}
80 virtual void OnSessionMessage(int cdm_id
,
82 const std::vector
<uint8
>& message
,
83 const GURL
& destination_url
) OVERRIDE
{}
84 virtual void OnSessionReady(int cdm_id
, uint32 session_id
) OVERRIDE
{}
85 virtual void OnSessionClosed(int cdm_id
, uint32 session_id
) OVERRIDE
{}
86 virtual void OnSessionError(int cdm_id
,
88 media::MediaKeys::KeyError error_code
,
89 uint32 system_code
) OVERRIDE
{}
91 bool playback_completed() const {
92 return playback_completed_
;
95 int num_resources_requested() const {
96 return num_resources_requested_
;
99 int num_resources_released() const {
100 return num_resources_released_
;
103 void OnMediaResourcesRequested(int player_id
) {
104 num_resources_requested_
++;
107 void OnMediaResourcesReleased(int player_id
) {
108 num_resources_released_
++;
111 bool timestamp_updated() const {
112 return timestamp_updated_
;
115 void ResetTimestampUpdated() {
116 timestamp_updated_
= false;
120 base::MessageLoop
* message_loop_
;
121 bool playback_completed_
;
122 // The number of resource requests this object has seen.
123 int num_resources_requested_
;
124 // The number of released resources.
125 int num_resources_released_
;
126 // Playback timestamp was updated.
127 bool timestamp_updated_
;
129 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager
);
132 class MockDemuxerAndroid
: public DemuxerAndroid
{
134 explicit MockDemuxerAndroid(base::MessageLoop
* message_loop
)
135 : message_loop_(message_loop
),
136 num_data_requests_(0),
137 num_seek_requests_(0),
138 num_browser_seek_requests_(0),
139 num_config_requests_(0) {}
140 virtual ~MockDemuxerAndroid() {}
142 virtual void Initialize(DemuxerAndroidClient
* client
) OVERRIDE
{}
143 virtual void RequestDemuxerConfigs() OVERRIDE
{
144 num_config_requests_
++;
146 virtual void RequestDemuxerData(DemuxerStream::Type type
) OVERRIDE
{
147 num_data_requests_
++;
148 if (message_loop_
->is_running())
149 message_loop_
->Quit();
151 virtual void RequestDemuxerSeek(const base::TimeDelta
& time_to_seek
,
152 bool is_browser_seek
) OVERRIDE
{
153 num_seek_requests_
++;
155 num_browser_seek_requests_
++;
158 int num_data_requests() const { return num_data_requests_
; }
159 int num_seek_requests() const { return num_seek_requests_
; }
160 int num_browser_seek_requests() const { return num_browser_seek_requests_
; }
161 int num_config_requests() const { return num_config_requests_
; }
164 base::MessageLoop
* message_loop_
;
166 // The number of encoded data requests this object has seen.
167 int num_data_requests_
;
169 // The number of regular and browser seek requests this object has seen.
170 int num_seek_requests_
;
172 // The number of browser seek requests this object has seen.
173 int num_browser_seek_requests_
;
175 // The number of demuxer config requests this object has seen.
176 int num_config_requests_
;
178 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid
);
181 class MediaSourcePlayerTest
: public testing::Test
{
183 MediaSourcePlayerTest()
184 : manager_(&message_loop_
),
185 demuxer_(new MockDemuxerAndroid(&message_loop_
)),
186 player_(0, &manager_
,
187 base::Bind(&MockMediaPlayerManager::OnMediaResourcesRequested
,
188 base::Unretained(&manager_
)),
189 base::Bind(&MockMediaPlayerManager::OnMediaResourcesReleased
,
190 base::Unretained(&manager_
)),
191 scoped_ptr
<DemuxerAndroid
>(demuxer_
)),
192 decoder_callback_hook_executed_(false),
193 surface_texture_a_is_next_(true) {}
194 virtual ~MediaSourcePlayerTest() {}
197 // Get the decoder job from the MediaSourcePlayer.
198 MediaDecoderJob
* GetMediaDecoderJob(bool is_audio
) {
200 return reinterpret_cast<MediaDecoderJob
*>(
201 player_
.audio_decoder_job_
.get());
203 return reinterpret_cast<MediaDecoderJob
*>(
204 player_
.video_decoder_job_
.get());
207 // Get the per-job prerolling status from the MediaSourcePlayer's job matching
208 // |is_audio|. Caller must guard against NPE if the player's job is NULL.
209 bool IsPrerolling(bool is_audio
) {
210 return GetMediaDecoderJob(is_audio
)->prerolling();
213 // Get the preroll timestamp from the MediaSourcePlayer.
214 base::TimeDelta
GetPrerollTimestamp() {
215 return player_
.preroll_timestamp_
;
218 // Simulate player has reached starvation timeout.
219 void TriggerPlayerStarvation() {
220 player_
.decoder_starvation_callback_
.Cancel();
221 player_
.OnDecoderStarved();
224 // Release() the player.
225 void ReleasePlayer() {
226 EXPECT_TRUE(player_
.IsPlaying());
228 EXPECT_FALSE(player_
.IsPlaying());
229 EXPECT_FALSE(GetMediaDecoderJob(true));
230 EXPECT_FALSE(GetMediaDecoderJob(false));
233 // Upon the next successful decode callback, post a task to call Release()
234 // on the |player_|. TEST_F's do not have access to the private player
235 // members, hence this helper method.
236 // Prevent usage creep of MSP::set_decode_callback_for_testing() by
237 // only using it for the ReleaseWithOnPrefetchDoneAlreadyPosted test.
238 void OnNextTestDecodeCallbackPostTaskToReleasePlayer() {
239 DCHECK_EQ(&message_loop_
, base::MessageLoop::current());
240 player_
.set_decode_callback_for_testing(media::BindToCurrentLoop(
242 &MediaSourcePlayerTest::ReleaseWithPendingPrefetchDoneVerification
,
243 base::Unretained(this))));
246 // Asynch test callback posted upon decode completion to verify that a pending
247 // prefetch done event is cleared across |player_|'s Release(). This helps
248 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
249 void ReleaseWithPendingPrefetchDoneVerification() {
250 EXPECT_TRUE(player_
.IsEventPending(player_
.PREFETCH_DONE_EVENT_PENDING
));
252 EXPECT_FALSE(player_
.IsEventPending(player_
.PREFETCH_DONE_EVENT_PENDING
));
253 EXPECT_FALSE(decoder_callback_hook_executed_
);
254 decoder_callback_hook_executed_
= true;
257 // Inspect internal pending_event_ state of |player_|. This is for infrequent
258 // use by tests, only where required.
259 bool IsPendingSurfaceChange() {
260 return player_
.IsEventPending(player_
.SURFACE_CHANGE_EVENT_PENDING
);
263 DemuxerConfigs
CreateAudioDemuxerConfigs(AudioCodec audio_codec
) {
264 DemuxerConfigs configs
;
265 configs
.audio_codec
= audio_codec
;
266 configs
.audio_channels
= 2;
267 configs
.is_audio_encrypted
= false;
268 configs
.duration
= kDefaultDuration
;
270 if (audio_codec
== kCodecVorbis
) {
271 configs
.audio_sampling_rate
= 44100;
272 scoped_refptr
<DecoderBuffer
> buffer
= ReadTestDataFile(
274 configs
.audio_extra_data
= std::vector
<uint8
>(
276 buffer
->data() + buffer
->data_size());
280 // Other codecs are not yet supported by this helper.
281 EXPECT_EQ(audio_codec
, kCodecAAC
);
283 configs
.audio_sampling_rate
= 48000;
284 uint8 aac_extra_data
[] = { 0x13, 0x10 };
285 configs
.audio_extra_data
= std::vector
<uint8
>(
291 DemuxerConfigs
CreateVideoDemuxerConfigs() {
292 DemuxerConfigs configs
;
293 configs
.video_codec
= kCodecVP8
;
294 configs
.video_size
= gfx::Size(320, 240);
295 configs
.is_video_encrypted
= false;
296 configs
.duration
= kDefaultDuration
;
300 DemuxerConfigs
CreateAudioVideoDemuxerConfigs() {
301 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
);
302 configs
.video_codec
= kCodecVP8
;
303 configs
.video_size
= gfx::Size(320, 240);
304 configs
.is_video_encrypted
= false;
308 DemuxerConfigs
CreateDemuxerConfigs(bool have_audio
, bool have_video
) {
309 DCHECK(have_audio
|| have_video
);
311 if (have_audio
&& !have_video
)
312 return CreateAudioDemuxerConfigs(kCodecVorbis
);
314 if (have_video
&& !have_audio
)
315 return CreateVideoDemuxerConfigs();
317 return CreateAudioVideoDemuxerConfigs();
320 // Starts an audio decoder job. Verifies player behavior relative to
321 // |expect_player_requests_data|.
322 void StartAudioDecoderJob(bool expect_player_requests_data
) {
323 Start(CreateAudioDemuxerConfigs(kCodecVorbis
), expect_player_requests_data
);
326 // Starts a video decoder job. Verifies player behavior relative to
327 // |expect_player_requests_data|.
328 void StartVideoDecoderJob(bool expect_player_requests_data
) {
329 Start(CreateVideoDemuxerConfigs(), expect_player_requests_data
);
332 // Starts decoding the data. Verifies player behavior relative to
333 // |expect_player_requests_data|.
334 void Start(const DemuxerConfigs
& configs
, bool expect_player_requests_data
) {
335 bool has_audio
= configs
.audio_codec
!= kUnknownAudioCodec
;
336 bool has_video
= configs
.video_codec
!= kUnknownVideoCodec
;
337 int original_num_data_requests
= demuxer_
->num_data_requests();
338 int expected_request_delta
= expect_player_requests_data
?
339 ((has_audio
? 1 : 0) + (has_video
? 1 : 0)) : 0;
341 player_
.OnDemuxerConfigsAvailable(configs
);
344 EXPECT_TRUE(player_
.IsPlaying());
345 EXPECT_EQ(original_num_data_requests
+ expected_request_delta
,
346 demuxer_
->num_data_requests());
348 // Verify player has decoder job iff the config included the media type for
349 // the job and the player is expected to request data due to Start(), above.
350 EXPECT_EQ(expect_player_requests_data
&& has_audio
,
351 GetMediaDecoderJob(true) != NULL
);
352 EXPECT_EQ(expect_player_requests_data
&& has_video
,
353 GetMediaDecoderJob(false) != NULL
);
356 // Keeps decoding audio data until the decoder starts to output samples.
357 // Gives up if no audio output after decoding 10 frames.
358 void DecodeAudioDataUntilOutputBecomesAvailable() {
359 EXPECT_TRUE(player_
.IsPlaying());
360 base::TimeDelta current_time
= player_
.GetCurrentTime();
361 base::TimeDelta start_timestamp
= current_time
;
362 for (int i
= 0; i
< 10; ++i
) {
363 manager_
.ResetTimestampUpdated();
364 player_
.OnDemuxerDataAvailable(
365 CreateReadFromDemuxerAckForAudio(i
> 3 ? 3 : i
));
366 WaitForAudioDecodeDone();
367 base::TimeDelta new_current_time
= player_
.GetCurrentTime();
368 EXPECT_LE(current_time
.InMilliseconds(),
369 new_current_time
.InMilliseconds());
370 current_time
= new_current_time
;
371 if (manager_
.timestamp_updated()) {
372 EXPECT_LT(start_timestamp
.InMillisecondsF(),
373 new_current_time
.InMillisecondsF());
380 AccessUnit
CreateAccessUnitWithData(bool is_audio
, int audio_packet_id
) {
383 unit
.status
= DemuxerStream::kOk
;
384 scoped_refptr
<DecoderBuffer
> buffer
= ReadTestDataFile(
385 is_audio
? base::StringPrintf("vorbis-packet-%d", audio_packet_id
)
386 : "vp8-I-frame-320x240");
387 unit
.data
= std::vector
<uint8
>(
388 buffer
->data(), buffer
->data() + buffer
->data_size());
391 // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
392 // NuMediaExtractor.cpp in Android source code.
393 uint8 padding
[4] = { 0xff , 0xff , 0xff , 0xff };
394 unit
.data
.insert(unit
.data
.end(), padding
, padding
+ 4);
400 DemuxerData
CreateReadFromDemuxerAckForAudio(int packet_id
) {
402 data
.type
= DemuxerStream::AUDIO
;
403 data
.access_units
.resize(1);
404 data
.access_units
[0] = CreateAccessUnitWithData(true, packet_id
);
408 DemuxerData
CreateReadFromDemuxerAckForVideo() {
410 data
.type
= DemuxerStream::VIDEO
;
411 data
.access_units
.resize(1);
412 data
.access_units
[0] = CreateAccessUnitWithData(false, 0);
416 DemuxerData
CreateEOSAck(bool is_audio
) {
418 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
419 data
.access_units
.resize(1);
420 data
.access_units
[0].status
= DemuxerStream::kOk
;
421 data
.access_units
[0].end_of_stream
= true;
425 DemuxerData
CreateAbortedAck(bool is_audio
) {
427 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
428 data
.access_units
.resize(1);
429 data
.access_units
[0].status
= DemuxerStream::kAborted
;
433 // Helper method for use at test start. It starts an audio decoder job and
434 // immediately feeds it some data to decode. Then, without letting the decoder
435 // job complete a decode cycle, it also starts player SeekTo(). Upon return,
436 // the player should not yet have sent the DemuxerSeek IPC request, though
437 // seek event should be pending. The audio decoder job will also still be
439 void StartAudioDecoderJobAndSeekToWhileDecoding(
440 const base::TimeDelta
& seek_time
) {
441 EXPECT_FALSE(GetMediaDecoderJob(true));
442 EXPECT_FALSE(player_
.IsPlaying());
443 EXPECT_EQ(0, demuxer_
->num_data_requests());
444 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
445 EXPECT_EQ(player_
.GetCurrentTime(), GetPrerollTimestamp());
446 StartAudioDecoderJob(true);
447 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
448 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
449 EXPECT_EQ(2, demuxer_
->num_data_requests());
450 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
451 player_
.SeekTo(seek_time
);
452 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
453 EXPECT_EQ(0, demuxer_
->num_seek_requests());
454 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
457 // Seek, including simulated receipt of |kAborted| read between SeekTo() and
458 // OnDemuxerSeekDone(). Use this helper method only when the player already
459 // has created the decoder job. Exactly one request for more data is expected
460 // following the seek, so use this helper for players with only audio or only
462 void SeekPlayerWithAbort(bool is_audio
, const base::TimeDelta
& seek_time
) {
463 int original_num_seeks
= demuxer_
->num_seek_requests();
464 int original_num_data_requests
= demuxer_
->num_data_requests();
466 // Initiate a seek. Skip the round-trip of requesting seek from renderer.
467 // Instead behave as if the renderer has asked us to seek.
468 player_
.SeekTo(seek_time
);
470 // Verify that the seek does not occur until previously outstanding data
471 // request is satisfied.
472 EXPECT_EQ(original_num_seeks
, demuxer_
->num_seek_requests());
474 // Simulate seeking causes the demuxer to abort the outstanding read
475 // caused by the seek.
476 player_
.OnDemuxerDataAvailable(CreateAbortedAck(is_audio
));
478 // Verify that the seek is requested.
479 EXPECT_EQ(original_num_seeks
+ 1, demuxer_
->num_seek_requests());
481 // Send back the seek done notification. This should trigger the player to
482 // call OnReadFromDemuxer() again.
483 EXPECT_EQ(original_num_data_requests
, demuxer_
->num_data_requests());
484 player_
.OnDemuxerSeekDone(kNoTimestamp());
485 EXPECT_EQ(original_num_data_requests
+ 1, demuxer_
->num_data_requests());
487 // No other seek should have been requested.
488 EXPECT_EQ(original_num_seeks
+ 1, demuxer_
->num_seek_requests());
491 // Preroll the decoder job to |target_timestamp|. The first access unit
492 // to decode will have a timestamp equal to |start_timestamp|.
493 // TODO(qinmin): Add additional test cases for out-of-order decodes.
494 // See http://crbug.com/331421.
495 void PrerollDecoderToTime(bool is_audio
,
496 const base::TimeDelta
& start_timestamp
,
497 const base::TimeDelta
& target_timestamp
) {
498 EXPECT_EQ(target_timestamp
, player_
.GetCurrentTime());
499 // |start_timestamp| must be smaller than |target_timestamp|.
500 EXPECT_LE(start_timestamp
, target_timestamp
);
501 DemuxerData data
= is_audio
? CreateReadFromDemuxerAckForAudio(1) :
502 CreateReadFromDemuxerAckForVideo();
503 int current_timestamp
= start_timestamp
.InMilliseconds();
505 // Send some data with access unit timestamps before the |target_timestamp|,
506 // and continue sending the data until preroll finishes.
507 // This simulates the common condition that AUs received after browser
508 // seek begin with timestamps before the seek target, and don't
509 // immediately complete preroll.
510 while (IsPrerolling(is_audio
)) {
511 data
.access_units
[0].timestamp
=
512 base::TimeDelta::FromMilliseconds(current_timestamp
);
513 player_
.OnDemuxerDataAvailable(data
);
514 EXPECT_TRUE(GetMediaDecoderJob(is_audio
)->is_decoding());
515 EXPECT_EQ(target_timestamp
, player_
.GetCurrentTime());
516 current_timestamp
+= 30;
517 WaitForDecodeDone(is_audio
, !is_audio
);
519 EXPECT_LE(target_timestamp
, player_
.GetCurrentTime());
522 DemuxerData
CreateReadFromDemuxerAckWithConfigChanged(bool is_audio
,
523 int config_unit_index
) {
525 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
526 data
.access_units
.resize(config_unit_index
+ 1);
528 for (int i
= 0; i
< config_unit_index
; ++i
)
529 data
.access_units
[i
] = CreateAccessUnitWithData(is_audio
, i
);
531 data
.access_units
[config_unit_index
].status
= DemuxerStream::kConfigChanged
;
535 // Valid only for video-only player tests. If |trigger_with_release_start| is
536 // true, triggers the browser seek with a Release() + video data received +
537 // Start() with a new surface. If false, triggers the browser seek by
538 // setting a new video surface after beginning decode of received video data.
539 // Such data receipt causes possibility that an I-frame is not next, and
540 // browser seek results once decode completes and surface change processing
542 void BrowserSeekPlayer(bool trigger_with_release_start
) {
543 int expected_num_data_requests
= demuxer_
->num_data_requests() +
544 (trigger_with_release_start
? 1 : 2);
545 int expected_num_seek_requests
= demuxer_
->num_seek_requests();
546 int expected_num_browser_seek_requests
=
547 demuxer_
->num_browser_seek_requests();
549 EXPECT_FALSE(GetMediaDecoderJob(false));
550 CreateNextTextureAndSetVideoSurface();
551 StartVideoDecoderJob(true);
553 if (trigger_with_release_start
) {
556 // Simulate demuxer's response to the video data request. The data will be
558 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
559 EXPECT_FALSE(GetMediaDecoderJob(false));
560 EXPECT_FALSE(player_
.IsPlaying());
561 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
563 CreateNextTextureAndSetVideoSurface();
564 StartVideoDecoderJob(false);
565 EXPECT_FALSE(GetMediaDecoderJob(false));
567 // Simulate demuxer's response to the video data request.
568 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
570 // While the decoder is decoding, trigger a browser seek by changing
571 // surface. Demuxer does not know of browser seek in advance, so no
572 // |kAborted| data is required (though |kAborted| can certainly occur for
573 // any pending read in reality due to renderer preparing for a regular
575 CreateNextTextureAndSetVideoSurface();
577 // Browser seek should not begin until decoding has completed.
578 EXPECT_TRUE(GetMediaDecoderJob(false));
579 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
581 // Wait for the decoder job to finish decoding and be reset pending the
583 WaitForVideoDecodeDone();
584 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
587 // Only one browser seek should have been initiated, and no further data
588 // should have been requested.
589 expected_num_seek_requests
++;
590 expected_num_browser_seek_requests
++;
591 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
592 EXPECT_EQ(expected_num_browser_seek_requests
,
593 demuxer_
->num_browser_seek_requests());
594 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
597 // Creates a new decoder job and feeds it data ending with a |kConfigChanged|
598 // access unit. If |config_unit_in_prefetch| is true, sends feeds the config
599 // change AU in response to the job's first read request (prefetch). If
600 // false, regular data is fed and decoded prior to feeding the config change
601 // AU in response to the second data request (after prefetch completed).
602 // |config_unit_index| controls which access unit is |kConfigChanged|.
603 void StartConfigChange(bool is_audio
,
604 bool config_unit_in_prefetch
,
605 int config_unit_index
) {
606 int expected_num_config_requests
= demuxer_
->num_config_requests();
608 EXPECT_FALSE(GetMediaDecoderJob(is_audio
));
610 StartAudioDecoderJob(true);
612 CreateNextTextureAndSetVideoSurface();
613 StartVideoDecoderJob(true);
616 int expected_num_data_requests
= demuxer_
->num_data_requests();
618 // Feed and decode a standalone access unit so the player exits prefetch.
619 if (!config_unit_in_prefetch
) {
621 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
623 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
625 WaitForDecodeDone(is_audio
, !is_audio
);
627 // We should have completed the prefetch phase at this point.
628 expected_num_data_requests
++;
629 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
632 EXPECT_EQ(expected_num_config_requests
, demuxer_
->num_config_requests());
634 // Feed and decode access units with data for any units prior to
635 // |config_unit_index|, and a |kConfigChanged| unit at that index.
636 // Player should prepare to reconfigure the decoder job, and should request
637 // new demuxer configs.
638 player_
.OnDemuxerDataAvailable(
639 CreateReadFromDemuxerAckWithConfigChanged(is_audio
, config_unit_index
));
640 WaitForDecodeDone(is_audio
, !is_audio
);
642 expected_num_config_requests
++;
643 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
644 EXPECT_EQ(expected_num_config_requests
, demuxer_
->num_config_requests());
647 void CreateNextTextureAndSetVideoSurface() {
648 gfx::SurfaceTexture
* surface_texture
;
649 if (surface_texture_a_is_next_
) {
650 surface_texture_a_
= gfx::SurfaceTexture::Create(next_texture_id_
++);
651 surface_texture
= surface_texture_a_
.get();
653 surface_texture_b_
= gfx::SurfaceTexture::Create(next_texture_id_
++);
654 surface_texture
= surface_texture_b_
.get();
657 surface_texture_a_is_next_
= !surface_texture_a_is_next_
;
658 gfx::ScopedJavaSurface surface
= gfx::ScopedJavaSurface(surface_texture
);
659 player_
.SetVideoSurface(surface
.Pass());
662 // Wait for one or both of the jobs to complete decoding. Decoder jobs are
663 // assumed to exist for any stream whose decode completion is awaited.
664 void WaitForDecodeDone(bool wait_for_audio
, bool wait_for_video
) {
665 DCHECK(wait_for_audio
|| wait_for_video
);
666 while ((wait_for_audio
&& GetMediaDecoderJob(true) &&
667 GetMediaDecoderJob(true)->HasData() &&
668 GetMediaDecoderJob(true)->is_decoding()) ||
669 (wait_for_video
&& GetMediaDecoderJob(false) &&
670 GetMediaDecoderJob(false)->HasData() &&
671 GetMediaDecoderJob(false)->is_decoding())) {
672 message_loop_
.RunUntilIdle();
676 void WaitForAudioDecodeDone() {
677 WaitForDecodeDone(true, false);
680 void WaitForVideoDecodeDone() {
681 WaitForDecodeDone(false, true);
684 void WaitForAudioVideoDecodeDone() {
685 WaitForDecodeDone(true, true);
688 // If |send_eos| is true, generates EOS for the stream corresponding to
689 // |eos_for_audio|. Verifies that playback completes and no further data
691 // If |send_eos| is false, then it is assumed that caller previously arranged
692 // for player to receive EOS for each stream, but the player has not yet
693 // decoded all of them. In this case, |eos_for_audio| is ignored.
694 void VerifyPlaybackCompletesOnEOSDecode(bool send_eos
, bool eos_for_audio
) {
695 int original_num_data_requests
= demuxer_
->num_data_requests();
697 player_
.OnDemuxerDataAvailable(CreateEOSAck(eos_for_audio
));
698 EXPECT_FALSE(manager_
.playback_completed());
700 EXPECT_TRUE(manager_
.playback_completed());
701 EXPECT_EQ(original_num_data_requests
, demuxer_
->num_data_requests());
704 void VerifyCompletedPlaybackResumesOnSeekPlusStart(bool have_audio
,
706 DCHECK(have_audio
|| have_video
);
708 EXPECT_TRUE(manager_
.playback_completed());
710 player_
.SeekTo(base::TimeDelta());
711 player_
.OnDemuxerSeekDone(kNoTimestamp());
712 Start(CreateDemuxerConfigs(have_audio
, have_video
), true);
715 // Starts the appropriate decoder jobs according to |have_audio| and
716 // |have_video|. Then starts seek during decode of EOS or non-EOS according to
717 // |eos_audio| and |eos_video|. Simulates seek completion and verifies that
718 // playback never completed. |eos_{audio,video}| is ignored if the
719 // corresponding |have_{audio,video}| is false.
720 void VerifySeekDuringEOSDecodePreventsPlaybackCompletion(bool have_audio
,
724 DCHECK(have_audio
|| have_video
);
727 CreateNextTextureAndSetVideoSurface();
729 Start(CreateDemuxerConfigs(have_audio
, have_video
), true);
732 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
735 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
737 // Run until more data is requested a number of times equal to the number of
738 // media types configured. Since prefetching may be in progress, we cannot
739 // reliably expect Run() to complete until we have sent demuxer data for all
740 // configured media types, above.
741 WaitForDecodeDone(have_audio
, have_video
);
743 // Simulate seek while decoding EOS or non-EOS for the appropriate
747 player_
.OnDemuxerDataAvailable(CreateEOSAck(true));
749 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
754 player_
.OnDemuxerDataAvailable(CreateEOSAck(false));
756 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
759 player_
.SeekTo(base::TimeDelta());
760 EXPECT_EQ(0, demuxer_
->num_seek_requests());
761 WaitForDecodeDone(have_audio
, have_video
);
762 EXPECT_EQ(1, demuxer_
->num_seek_requests());
764 player_
.OnDemuxerSeekDone(kNoTimestamp());
765 EXPECT_FALSE(manager_
.playback_completed());
768 base::TimeTicks
StartTimeTicks() {
769 return player_
.start_time_ticks_
;
772 base::MessageLoop message_loop_
;
773 MockMediaPlayerManager manager_
;
774 MockDemuxerAndroid
* demuxer_
; // Owned by |player_|.
775 MediaSourcePlayer player_
;
777 // Track whether a possibly async decoder callback test hook has run.
778 bool decoder_callback_hook_executed_
;
780 // We need to keep the surface texture while the decoder is actively decoding.
781 // Otherwise, it may trigger unexpected crashes on some devices. To switch
782 // surfaces, tests need to create a new surface texture without releasing
783 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
784 // between two surface textures, only replacing the N-2 texture. Assumption is
785 // that no more than N-1 texture is in use by decoder when
786 // CreateNextTextureAndSetVideoSurface() is called.
787 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_a_
;
788 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_b_
;
789 bool surface_texture_a_is_next_
;
790 int next_texture_id_
;
792 DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayerTest
);
795 TEST_F(MediaSourcePlayerTest
, StartAudioDecoderWithValidConfig
) {
796 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
798 // Test audio decoder job will be created when codec is successfully started.
799 StartAudioDecoderJob(true);
800 EXPECT_EQ(0, demuxer_
->num_seek_requests());
803 TEST_F(MediaSourcePlayerTest
, StartAudioDecoderWithInvalidConfig
) {
804 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
806 // Test audio decoder job will not be created when failed to start the codec.
807 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
);
808 // Replace with invalid |audio_extra_data|
809 configs
.audio_extra_data
.clear();
810 uint8 invalid_codec_data
[] = { 0x00, 0xff, 0xff, 0xff, 0xff };
811 configs
.audio_extra_data
.insert(configs
.audio_extra_data
.begin(),
812 invalid_codec_data
, invalid_codec_data
+ 4);
813 Start(configs
, false);
814 EXPECT_EQ(0, demuxer_
->num_seek_requests());
817 TEST_F(MediaSourcePlayerTest
, StartVideoCodecWithValidSurface
) {
818 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
820 // Test video decoder job will be created when surface is valid.
821 // Video decoder job will not be created until surface is available.
822 StartVideoDecoderJob(false);
824 // Set both an initial and a later video surface without receiving any
826 CreateNextTextureAndSetVideoSurface();
827 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
828 EXPECT_TRUE(first_job
);
829 CreateNextTextureAndSetVideoSurface();
831 // Setting another surface will not create a new job until any pending
832 // read is satisfied (and job is no longer decoding).
833 EXPECT_EQ(first_job
, GetMediaDecoderJob(false));
835 // No seeks, even on setting surface, should have occurred. (Browser seeks can
836 // occur on setting surface, but only after previously receiving video data.)
837 EXPECT_EQ(0, demuxer_
->num_seek_requests());
839 // Note, the decoder job for the second surface set, above, will be created
840 // only after the pending read is satisfied and decoded, and the resulting
841 // browser seek is done. See BrowserSeek_* tests for this coverage.
844 TEST_F(MediaSourcePlayerTest
, StartVideoCodecWithInvalidSurface
) {
845 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
847 // Test video decoder job will not be created when surface is invalid.
848 scoped_refptr
<gfx::SurfaceTexture
> surface_texture(
849 gfx::SurfaceTexture::Create(0));
850 gfx::ScopedJavaSurface
surface(surface_texture
.get());
851 StartVideoDecoderJob(false);
853 // Release the surface texture.
854 surface_texture
= NULL
;
855 player_
.SetVideoSurface(surface
.Pass());
857 // Player should not seek the demuxer on setting initial surface.
858 EXPECT_EQ(0, demuxer_
->num_seek_requests());
860 EXPECT_FALSE(GetMediaDecoderJob(false));
861 EXPECT_EQ(0, demuxer_
->num_data_requests());
864 TEST_F(MediaSourcePlayerTest
, ReadFromDemuxerAfterSeek
) {
865 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
867 // Test decoder job will resend a ReadFromDemuxer request after seek.
868 StartAudioDecoderJob(true);
869 SeekPlayerWithAbort(true, base::TimeDelta());
872 TEST_F(MediaSourcePlayerTest
, SetSurfaceWhileSeeking
) {
873 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
875 // Test SetVideoSurface() will not cause an extra seek while the player is
876 // waiting for demuxer to indicate seek is done.
877 // Player is still waiting for SetVideoSurface(), so no request is sent.
878 StartVideoDecoderJob(false); // Verifies no data requested.
880 // Initiate a seek. Skip requesting element seek of renderer.
881 // Instead behave as if the renderer has asked us to seek.
882 EXPECT_EQ(0, demuxer_
->num_seek_requests());
883 player_
.SeekTo(base::TimeDelta());
884 EXPECT_EQ(1, demuxer_
->num_seek_requests());
886 CreateNextTextureAndSetVideoSurface();
887 EXPECT_FALSE(GetMediaDecoderJob(false));
888 EXPECT_EQ(1, demuxer_
->num_seek_requests());
890 // Reconfirm player has not yet requested data.
891 EXPECT_EQ(0, demuxer_
->num_data_requests());
893 // Send the seek done notification. The player should start requesting data.
894 player_
.OnDemuxerSeekDone(kNoTimestamp());
895 EXPECT_TRUE(GetMediaDecoderJob(false));
896 EXPECT_EQ(1, demuxer_
->num_data_requests());
898 // Reconfirm exactly 1 seek request has been made of demuxer, and that it
899 // was not a browser seek request.
900 EXPECT_EQ(1, demuxer_
->num_seek_requests());
901 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
904 TEST_F(MediaSourcePlayerTest
, ChangeMultipleSurfaceWhileDecoding
) {
905 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
907 // Test MediaSourcePlayer can switch multiple surfaces during decoding.
908 CreateNextTextureAndSetVideoSurface();
909 StartVideoDecoderJob(true);
910 EXPECT_EQ(0, demuxer_
->num_seek_requests());
912 // Send the first input chunk.
913 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
915 // While the decoder is decoding, change multiple surfaces. Pass an empty
917 gfx::ScopedJavaSurface empty_surface
;
918 player_
.SetVideoSurface(empty_surface
.Pass());
919 // Next, pass a new non-empty surface.
920 CreateNextTextureAndSetVideoSurface();
922 // Wait for the decoder job to finish decoding and be reset pending a browser
924 WaitForVideoDecodeDone();
925 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
927 // Only one browser seek should have been initiated. No further data request
928 // should have been processed on |message_loop_| before surface change event
929 // became pending, above.
930 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
931 EXPECT_EQ(2, demuxer_
->num_data_requests());
933 // Simulate browser seek is done and confirm player requests more data for new
934 // video decoder job.
935 player_
.OnDemuxerSeekDone(player_
.GetCurrentTime());
936 EXPECT_TRUE(GetMediaDecoderJob(false));
937 EXPECT_EQ(3, demuxer_
->num_data_requests());
938 EXPECT_EQ(1, demuxer_
->num_seek_requests());
941 TEST_F(MediaSourcePlayerTest
, SetEmptySurfaceAndStarveWhileDecoding
) {
942 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
944 // Test player pauses if an empty surface is passed.
945 CreateNextTextureAndSetVideoSurface();
946 StartVideoDecoderJob(true);
947 EXPECT_EQ(1, demuxer_
->num_data_requests());
949 // Send the first input chunk.
950 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
952 // While the decoder is decoding, pass an empty surface.
953 gfx::ScopedJavaSurface empty_surface
;
954 player_
.SetVideoSurface(empty_surface
.Pass());
955 // Let the player starve. However, it should not issue any new data request in
957 TriggerPlayerStarvation();
958 // Wait for the decoder job to finish decoding and be reset.
959 while (GetMediaDecoderJob(false))
960 message_loop_
.RunUntilIdle();
962 // No further seek or data requests should have been received since the
964 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
965 EXPECT_EQ(2, demuxer_
->num_data_requests());
966 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
968 // Playback resumes once a non-empty surface is passed.
969 CreateNextTextureAndSetVideoSurface();
970 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
973 TEST_F(MediaSourcePlayerTest
, ReleaseVideoDecoderResourcesWhileDecoding
) {
974 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
976 // Test that if video decoder is released while decoding, the resources will
977 // not be immediately released.
978 CreateNextTextureAndSetVideoSurface();
979 StartVideoDecoderJob(true);
980 EXPECT_EQ(1, manager_
.num_resources_requested());
982 // The resources will be immediately released since the decoder is idle.
983 EXPECT_EQ(1, manager_
.num_resources_released());
984 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
986 // Recreate the video decoder.
987 CreateNextTextureAndSetVideoSurface();
989 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
990 player_
.OnDemuxerSeekDone(base::TimeDelta());
991 EXPECT_EQ(2, manager_
.num_resources_requested());
992 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
994 // The resource is still held by the video decoder until it finishes decoding.
995 EXPECT_EQ(1, manager_
.num_resources_released());
996 // Wait for the decoder job to finish decoding and be reset.
997 while (manager_
.num_resources_released() != 2)
998 message_loop_
.RunUntilIdle();
1001 TEST_F(MediaSourcePlayerTest
, AudioOnlyStartAfterSeekFinish
) {
1002 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1004 // Test audio decoder job will not start until pending seek event is handled.
1005 DemuxerConfigs configs
= CreateAudioDemuxerConfigs(kCodecVorbis
);
1006 player_
.OnDemuxerConfigsAvailable(configs
);
1007 EXPECT_FALSE(GetMediaDecoderJob(true));
1009 // Initiate a seek. Skip requesting element seek of renderer.
1010 // Instead behave as if the renderer has asked us to seek.
1011 player_
.SeekTo(base::TimeDelta());
1012 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1015 EXPECT_FALSE(GetMediaDecoderJob(true));
1016 EXPECT_EQ(0, demuxer_
->num_data_requests());
1018 // Sending back the seek done notification.
1019 player_
.OnDemuxerSeekDone(kNoTimestamp());
1020 EXPECT_TRUE(GetMediaDecoderJob(true));
1021 EXPECT_EQ(1, demuxer_
->num_data_requests());
1023 // Reconfirm exactly 1 seek request has been made of demuxer.
1024 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1027 TEST_F(MediaSourcePlayerTest
, VideoOnlyStartAfterSeekFinish
) {
1028 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1030 // Test video decoder job will not start until pending seek event is handled.
1031 CreateNextTextureAndSetVideoSurface();
1032 DemuxerConfigs configs
= CreateVideoDemuxerConfigs();
1033 player_
.OnDemuxerConfigsAvailable(configs
);
1034 EXPECT_FALSE(GetMediaDecoderJob(false));
1036 // Initiate a seek. Skip requesting element seek of renderer.
1037 // Instead behave as if the renderer has asked us to seek.
1038 player_
.SeekTo(base::TimeDelta());
1039 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1042 EXPECT_FALSE(GetMediaDecoderJob(false));
1043 EXPECT_EQ(0, demuxer_
->num_data_requests());
1045 // Sending back the seek done notification.
1046 player_
.OnDemuxerSeekDone(kNoTimestamp());
1047 EXPECT_TRUE(GetMediaDecoderJob(false));
1048 EXPECT_EQ(1, demuxer_
->num_data_requests());
1050 // Reconfirm exactly 1 seek request has been made of demuxer.
1051 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1054 TEST_F(MediaSourcePlayerTest
, StartImmediatelyAfterPause
) {
1055 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1057 // Test that if the decoding job is not fully stopped after Pause(),
1058 // calling Start() will be a noop.
1059 StartAudioDecoderJob(true);
1061 MediaDecoderJob
* decoder_job
= GetMediaDecoderJob(true);
1062 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
1064 // Sending data to player.
1065 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1066 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1067 EXPECT_EQ(2, demuxer_
->num_data_requests());
1069 // Decoder job will not immediately stop after Pause() since it is
1070 // running on another thread.
1071 player_
.Pause(true);
1072 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1074 // Nothing happens when calling Start() again.
1076 // Verify that Start() will not destroy and recreate the decoder job.
1077 EXPECT_EQ(decoder_job
, GetMediaDecoderJob(true));
1079 while (GetMediaDecoderJob(true)->is_decoding())
1080 message_loop_
.RunUntilIdle();
1081 // The decoder job should finish and wait for data.
1082 EXPECT_EQ(2, demuxer_
->num_data_requests());
1083 EXPECT_TRUE(GetMediaDecoderJob(true)->is_requesting_demuxer_data());
1086 TEST_F(MediaSourcePlayerTest
, DecoderJobsCannotStartWithoutAudio
) {
1087 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1089 // Test that when Start() is called, video decoder jobs will wait for audio
1090 // decoder job before start decoding the data.
1091 CreateNextTextureAndSetVideoSurface();
1092 Start(CreateAudioVideoDemuxerConfigs(), true);
1093 MediaDecoderJob
* audio_decoder_job
= GetMediaDecoderJob(true);
1094 MediaDecoderJob
* video_decoder_job
= GetMediaDecoderJob(false);
1096 EXPECT_FALSE(audio_decoder_job
->is_decoding());
1097 EXPECT_FALSE(video_decoder_job
->is_decoding());
1099 // Sending video data to player, video decoder should not start.
1100 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1101 EXPECT_FALSE(video_decoder_job
->is_decoding());
1103 // Sending audio data to player, both decoders should start now.
1104 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1105 EXPECT_TRUE(audio_decoder_job
->is_decoding());
1106 EXPECT_TRUE(video_decoder_job
->is_decoding());
1108 // No seeks should have occurred.
1109 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1112 TEST_F(MediaSourcePlayerTest
, StartTimeTicksResetAfterDecoderUnderruns
) {
1113 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1115 // Test start time ticks will reset after decoder job underruns.
1116 StartAudioDecoderJob(true);
1118 DecodeAudioDataUntilOutputBecomesAvailable();
1120 // The decoder job should finish and a new request will be sent.
1121 base::TimeTicks previous
= StartTimeTicks();
1122 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1124 // Let the decoder starve.
1125 TriggerPlayerStarvation();
1126 WaitForAudioDecodeDone();
1128 // Verify the start time ticks is cleared at this point because the
1129 // player is prefetching.
1130 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks());
1132 // Send new data to the decoder so it can finish prefetching. This should
1133 // reset the start time ticks.
1134 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1135 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
1137 base::TimeTicks current
= StartTimeTicks();
1138 EXPECT_LE(0, (current
- previous
).InMillisecondsF());
1141 TEST_F(MediaSourcePlayerTest
, V_SecondAccessUnitIsEOSAndResumePlayAfterSeek
) {
1142 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1144 // Test MediaSourcePlayer can replay video after input EOS is reached.
1145 CreateNextTextureAndSetVideoSurface();
1146 StartVideoDecoderJob(true);
1148 // Send the first input chunk.
1149 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1150 WaitForVideoDecodeDone();
1152 VerifyPlaybackCompletesOnEOSDecode(true, false);
1153 VerifyCompletedPlaybackResumesOnSeekPlusStart(false, true);
1156 TEST_F(MediaSourcePlayerTest
, A_FirstAccessUnitIsEOSAndResumePlayAfterSeek
) {
1157 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1159 // Test decode of audio EOS buffer without any prior decode. See also
1160 // http://b/11696552.
1161 // Also tests that seeking+Start() after completing audio playback resumes
1163 Start(CreateAudioDemuxerConfigs(kCodecAAC
), true);
1164 VerifyPlaybackCompletesOnEOSDecode(true, true);
1165 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, false);
1168 TEST_F(MediaSourcePlayerTest
, V_FirstAccessUnitAfterSeekIsEOS
) {
1169 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1171 // Test decode of video EOS buffer, just after seeking, without any prior
1172 // decode (other than the simulated |kAborted| resulting from the seek
1174 CreateNextTextureAndSetVideoSurface();
1175 StartVideoDecoderJob(true);
1176 SeekPlayerWithAbort(false, base::TimeDelta());
1177 VerifyPlaybackCompletesOnEOSDecode(true, false);
1180 TEST_F(MediaSourcePlayerTest
, A_FirstAccessUnitAfterSeekIsEOS
) {
1181 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1183 // Test decode of audio EOS buffer, just after seeking, without any prior
1184 // decode (other than the simulated |kAborted| resulting from the seek
1185 // process.) See also http://b/11696552.
1186 Start(CreateAudioDemuxerConfigs(kCodecAAC
), true);
1187 SeekPlayerWithAbort(true, base::TimeDelta());
1188 VerifyPlaybackCompletesOnEOSDecode(true, true);
1191 TEST_F(MediaSourcePlayerTest
, AV_PlaybackCompletionAcrossConfigChange
) {
1192 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1194 // Test that if one stream (audio) has completed decode of EOS and the other
1195 // stream (video) processes config change, that subsequent video EOS completes
1197 // Also tests that seeking+Start() after completing playback resumes playback.
1198 CreateNextTextureAndSetVideoSurface();
1199 Start(CreateAudioVideoDemuxerConfigs(), true);
1201 player_
.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1202 EXPECT_EQ(0, demuxer_
->num_config_requests());
1203 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1204 false, 0)); // Video |kConfigChanged| as first unit.
1206 WaitForAudioVideoDecodeDone();
1208 EXPECT_EQ(1, demuxer_
->num_config_requests());
1209 EXPECT_EQ(2, demuxer_
->num_data_requests());
1210 player_
.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1211 EXPECT_EQ(3, demuxer_
->num_data_requests());
1213 // At no time after completing audio EOS decode, above, should the
1214 // audio decoder job resume decoding. Send and decode video EOS.
1215 VerifyPlaybackCompletesOnEOSDecode(true, false);
1216 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1219 TEST_F(MediaSourcePlayerTest
, VA_PlaybackCompletionAcrossConfigChange
) {
1220 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1222 // Test that if one stream (video) has completed decode of EOS and the other
1223 // stream (audio) processes config change, that subsequent audio EOS completes
1225 // Also tests that seeking+Start() after completing playback resumes playback.
1226 CreateNextTextureAndSetVideoSurface();
1227 Start(CreateAudioVideoDemuxerConfigs(), true);
1229 player_
.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1230 EXPECT_EQ(0, demuxer_
->num_config_requests());
1231 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1232 true, 0)); // Audio |kConfigChanged| as first unit.
1234 WaitForAudioVideoDecodeDone();
1236 // TODO(wolenetz/qinmin): Prevent redundant demuxer config request and change
1237 // expectation to 1 here. See http://crbug.com/325528.
1238 EXPECT_EQ(2, demuxer_
->num_config_requests());
1239 EXPECT_EQ(2, demuxer_
->num_data_requests());
1240 player_
.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1241 EXPECT_EQ(3, demuxer_
->num_data_requests());
1243 // At no time after completing video EOS decode, above, should the
1244 // video decoder job resume decoding. Send and decode audio EOS.
1245 VerifyPlaybackCompletesOnEOSDecode(true, true);
1246 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1249 TEST_F(MediaSourcePlayerTest
, AV_NoPrefetchForFinishedVideoOnAudioStarvation
) {
1250 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1252 // Test that if one stream (video) has completed decode of EOS, prefetch
1253 // resulting from player starvation occurs only for the other stream (audio),
1254 // and responding to that prefetch with EOS completes A/V playback, even if
1255 // another starvation occurs during the latter EOS's decode.
1256 CreateNextTextureAndSetVideoSurface();
1257 Start(CreateAudioVideoDemuxerConfigs(), true);
1259 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1260 player_
.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1262 // Wait until video EOS is processed and more data (assumed to be audio) is
1264 WaitForAudioVideoDecodeDone();
1265 EXPECT_EQ(3, demuxer_
->num_data_requests());
1267 // Simulate decoder underrun to trigger prefetch while still decoding audio.
1268 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
1269 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding() &&
1270 !GetMediaDecoderJob(false)->is_decoding());
1271 TriggerPlayerStarvation();
1273 // Complete the audio decode that was in progress when simulated player
1274 // starvation was triggered.
1275 WaitForAudioDecodeDone();
1276 EXPECT_EQ(4, demuxer_
->num_data_requests());
1277 player_
.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1278 EXPECT_FALSE(GetMediaDecoderJob(false)->is_decoding());
1279 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1281 // Simulate another decoder underrun to trigger prefetch while decoding EOS.
1282 TriggerPlayerStarvation();
1283 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1286 TEST_F(MediaSourcePlayerTest
, V_StarvationDuringEOSDecode
) {
1287 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1289 // Test that video-only playback completes without further data requested when
1290 // starvation occurs during EOS decode.
1291 CreateNextTextureAndSetVideoSurface();
1292 StartVideoDecoderJob(true);
1293 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1294 WaitForVideoDecodeDone();
1296 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1297 player_
.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1298 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1299 TriggerPlayerStarvation();
1300 VerifyPlaybackCompletesOnEOSDecode(false, false /* ignored */);
1303 TEST_F(MediaSourcePlayerTest
, A_StarvationDuringEOSDecode
) {
1304 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1306 // Test that audio-only playback completes without further data requested when
1307 // starvation occurs during EOS decode.
1308 StartAudioDecoderJob(true);
1309 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1310 WaitForAudioDecodeDone();
1312 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1313 player_
.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1314 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1315 TriggerPlayerStarvation();
1316 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1319 TEST_F(MediaSourcePlayerTest
, AV_SeekDuringEOSDecodePreventsCompletion
) {
1320 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1322 // Test that seek supercedes audio+video playback completion on simultaneous
1323 // audio and video EOS decode, if SeekTo() occurs during these EOS decodes.
1324 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, true);
1327 TEST_F(MediaSourcePlayerTest
, AV_SeekDuringAudioEOSDecodePreventsCompletion
) {
1328 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1330 // Test that seek supercedes audio+video playback completion on simultaneous
1331 // audio EOS and video non-EOS decode, if SeekTo() occurs during these
1333 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, false);
1336 TEST_F(MediaSourcePlayerTest
, AV_SeekDuringVideoEOSDecodePreventsCompletion
) {
1337 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1339 // Test that seek supercedes audio+video playback completion on simultaneous
1340 // audio non-EOS and video EOS decode, if SeekTo() occurs during these
1342 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, false, true);
1345 TEST_F(MediaSourcePlayerTest
, V_SeekDuringEOSDecodePreventsCompletion
) {
1346 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1348 // Test that seek supercedes video-only playback completion on EOS decode, if
1349 // SeekTo() occurs during EOS decode.
1350 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(false, true, false, true);
1353 TEST_F(MediaSourcePlayerTest
, A_SeekDuringEOSDecodePreventsCompletion
) {
1354 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1356 // Test that seek supercedes audio-only playback completion on EOS decode, if
1357 // SeekTo() occurs during EOS decode.
1358 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, false, true, false);
1361 TEST_F(MediaSourcePlayerTest
, NoRequestForDataAfterAbort
) {
1362 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1364 // Test that the decoder will not request new data after receiving an aborted
1366 StartAudioDecoderJob(true);
1368 // Send an aborted access unit.
1369 player_
.OnDemuxerDataAvailable(CreateAbortedAck(true));
1370 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1371 WaitForAudioDecodeDone();
1373 // No request will be sent for new data.
1374 EXPECT_EQ(1, demuxer_
->num_data_requests());
1376 // No seek requests should have occurred.
1377 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1380 TEST_F(MediaSourcePlayerTest
, DemuxerDataArrivesAfterRelease
) {
1381 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1383 // Test that the decoder should not crash if demuxer data arrives after
1385 StartAudioDecoderJob(true);
1388 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1390 // The decoder job should have been released.
1391 EXPECT_FALSE(player_
.IsPlaying());
1393 // No further data should have been requested.
1394 EXPECT_EQ(1, demuxer_
->num_data_requests());
1396 // No seek requests should have occurred.
1397 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1400 TEST_F(MediaSourcePlayerTest
, BrowserSeek_RegularSeekPendsBrowserSeekDone
) {
1401 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1403 // Test that a browser seek, once started, delays a newly arrived regular
1404 // SeekTo() request's demuxer seek until the browser seek is done.
1405 BrowserSeekPlayer(false);
1407 // Simulate renderer requesting a regular seek while browser seek in progress.
1408 player_
.SeekTo(base::TimeDelta());
1409 EXPECT_FALSE(GetMediaDecoderJob(false));
1411 // Simulate browser seek is done. Confirm player requests the regular seek,
1412 // still has no video decoder job configured, and has not requested any
1413 // further data since the surface change event became pending in
1414 // BrowserSeekPlayer().
1415 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1416 player_
.OnDemuxerSeekDone(base::TimeDelta());
1417 EXPECT_FALSE(GetMediaDecoderJob(false));
1418 EXPECT_EQ(2, demuxer_
->num_seek_requests());
1419 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
1421 // Simulate regular seek is done and confirm player requests more data for
1422 // new video decoder job.
1423 player_
.OnDemuxerSeekDone(kNoTimestamp());
1424 EXPECT_TRUE(GetMediaDecoderJob(false));
1425 EXPECT_EQ(3, demuxer_
->num_data_requests());
1426 EXPECT_EQ(2, demuxer_
->num_seek_requests());
1429 TEST_F(MediaSourcePlayerTest
, BrowserSeek_InitialReleaseAndStart
) {
1430 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1432 // Test that browser seek is requested if player Release() + Start() occurs
1433 // prior to receiving any data.
1434 CreateNextTextureAndSetVideoSurface();
1435 StartVideoDecoderJob(true);
1438 // Pass a new non-empty surface.
1439 CreateNextTextureAndSetVideoSurface();
1443 // The new player won't be created until the pending data request is
1445 EXPECT_EQ(1, demuxer_
->num_data_requests());
1446 EXPECT_FALSE(GetMediaDecoderJob(false));
1448 // A browser seek should be requested.
1449 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1450 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
1451 EXPECT_EQ(1, demuxer_
->num_data_requests());
1454 TEST_F(MediaSourcePlayerTest
, BrowserSeek_MidStreamReleaseAndStart
) {
1455 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1457 // Test that one browser seek is requested if player Release() + Start(), with
1458 // video data received between Release() and Start().
1459 BrowserSeekPlayer(true);
1461 // Simulate browser seek is done and confirm player requests more data.
1462 player_
.OnDemuxerSeekDone(base::TimeDelta());
1463 EXPECT_TRUE(GetMediaDecoderJob(false));
1464 EXPECT_EQ(2, demuxer_
->num_data_requests());
1465 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1468 TEST_F(MediaSourcePlayerTest
, PrerollAudioAfterSeek
) {
1469 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1471 // Test decoder job will preroll the media to the seek position.
1472 StartAudioDecoderJob(true);
1474 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1475 EXPECT_TRUE(IsPrerolling(true));
1476 PrerollDecoderToTime(
1477 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1480 TEST_F(MediaSourcePlayerTest
, PrerollVideoAfterSeek
) {
1481 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1483 // Test decoder job will preroll the media to the seek position.
1484 CreateNextTextureAndSetVideoSurface();
1485 StartVideoDecoderJob(true);
1487 SeekPlayerWithAbort(false, base::TimeDelta::FromMilliseconds(100));
1488 EXPECT_TRUE(IsPrerolling(false));
1489 PrerollDecoderToTime(
1490 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1493 TEST_F(MediaSourcePlayerTest
, SeekingAfterCompletingPrerollRestartsPreroll
) {
1494 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1496 // Test decoder job will begin prerolling upon seek, when it was not
1497 // prerolling prior to the seek.
1498 StartAudioDecoderJob(true);
1499 MediaDecoderJob
* decoder_job
= GetMediaDecoderJob(true);
1500 EXPECT_TRUE(IsPrerolling(true));
1502 // Complete the initial preroll by feeding data to the decoder.
1503 DecodeAudioDataUntilOutputBecomesAvailable();
1504 EXPECT_FALSE(IsPrerolling(true));
1506 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500));
1508 // Prerolling should have begun again.
1509 EXPECT_TRUE(IsPrerolling(true));
1510 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF());
1512 // Send data at and after the seek position. Prerolling should complete.
1513 for (int i
= 0; i
< 4; ++i
) {
1514 DemuxerData data
= CreateReadFromDemuxerAckForAudio(i
);
1515 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(
1516 500 + 30 * (i
- 1));
1517 player_
.OnDemuxerDataAvailable(data
);
1518 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1519 WaitForAudioDecodeDone();
1521 EXPECT_LT(500.0, player_
.GetCurrentTime().InMillisecondsF());
1522 EXPECT_FALSE(IsPrerolling(true));
1524 // Throughout this test, we should have not re-created the decoder job, so
1525 // IsPrerolling() transition from false to true was not due to constructor
1526 // initialization. It was due to BeginPrerolling().
1527 EXPECT_EQ(decoder_job
, GetMediaDecoderJob(true));
1530 TEST_F(MediaSourcePlayerTest
, PrerollContinuesAcrossReleaseAndStart
) {
1531 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1533 // Test decoder job will resume media prerolling if interrupted by Release()
1535 StartAudioDecoderJob(true);
1537 base::TimeDelta target_timestamp
= base::TimeDelta::FromMilliseconds(100);
1538 SeekPlayerWithAbort(true, target_timestamp
);
1539 EXPECT_TRUE(IsPrerolling(true));
1540 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1542 // Send some data before the seek position.
1543 // Test uses 'large' number of iterations because decoder job may not get
1544 // MEDIA_CODEC_OK output status until after a few dequeue output attempts.
1545 // This allows decoder status to stabilize prior to AU timestamp reaching
1546 // the preroll target.
1548 for (int i
= 0; i
< 10; ++i
) {
1549 data
= CreateReadFromDemuxerAckForAudio(3);
1550 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(i
* 10);
1552 // While still prerolling, Release() and Start() the player.
1553 // TODO(qinmin): Simulation of multiple in-flight data requests (one from
1554 // before Release(), one from after Start()) is not included here, and
1555 // neither is any data enqueued for later decode if it arrives after
1556 // Release() and before Start(). See http://crbug.com/306314. Assumption
1557 // for this test, to prevent flakiness until the bug is fixed, is the
1558 // first request's data arrives before Start(). Though that data is not
1559 // seen by decoder, this assumption allows preroll continuation
1560 // verification and prevents multiple in-flight data requests.
1562 player_
.OnDemuxerDataAvailable(data
);
1563 WaitForAudioDecodeDone();
1564 EXPECT_FALSE(GetMediaDecoderJob(true));
1565 StartAudioDecoderJob(true);
1567 player_
.OnDemuxerDataAvailable(data
);
1568 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1569 WaitForAudioDecodeDone();
1571 EXPECT_TRUE(IsPrerolling(true));
1573 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1574 EXPECT_TRUE(IsPrerolling(true));
1576 // Send data after the seek position.
1577 PrerollDecoderToTime(true, target_timestamp
, target_timestamp
);
1580 TEST_F(MediaSourcePlayerTest
, PrerollContinuesAcrossConfigChange
) {
1581 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1583 // Test decoder job will resume media prerolling if interrupted by
1584 // |kConfigChanged| and OnDemuxerConfigsAvailable().
1585 StartAudioDecoderJob(true);
1587 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1588 EXPECT_TRUE(IsPrerolling(true));
1589 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1591 // In response to data request, simulate that demuxer signals config change by
1592 // sending an AU with |kConfigChanged|. Player should prepare to reconfigure
1593 // the audio decoder job, and should request new demuxer configs.
1594 DemuxerData data
= CreateReadFromDemuxerAckWithConfigChanged(true, 0);
1595 EXPECT_EQ(0, demuxer_
->num_config_requests());
1596 player_
.OnDemuxerDataAvailable(data
);
1597 EXPECT_EQ(1, demuxer_
->num_config_requests());
1599 // Simulate arrival of new configs.
1600 player_
.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis
));
1602 PrerollDecoderToTime(
1603 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1606 TEST_F(MediaSourcePlayerTest
, SimultaneousAudioVideoConfigChange
) {
1607 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1609 // Test that the player allows simultaneous audio and video config change,
1610 // such as might occur during OnPrefetchDone() if next access unit for both
1611 // audio and video jobs is |kConfigChanged|.
1612 CreateNextTextureAndSetVideoSurface();
1613 Start(CreateAudioVideoDemuxerConfigs(), true);
1614 MediaDecoderJob
* first_audio_job
= GetMediaDecoderJob(true);
1615 MediaDecoderJob
* first_video_job
= GetMediaDecoderJob(false);
1617 // Simulate audio |kConfigChanged| prefetched as standalone access unit.
1618 player_
.OnDemuxerDataAvailable(
1619 CreateReadFromDemuxerAckWithConfigChanged(true, 0));
1620 EXPECT_EQ(0, demuxer_
->num_config_requests()); // No OnPrefetchDone() yet.
1622 // Simulate video |kConfigChanged| prefetched as standalone access unit.
1623 player_
.OnDemuxerDataAvailable(
1624 CreateReadFromDemuxerAckWithConfigChanged(false, 0));
1625 EXPECT_EQ(1, demuxer_
->num_config_requests()); // OnPrefetchDone() occurred.
1626 EXPECT_EQ(2, demuxer_
->num_data_requests()); // No more data requested yet.
1628 // No job re-creation should occur until the requested configs arrive.
1629 EXPECT_EQ(first_audio_job
, GetMediaDecoderJob(true));
1630 EXPECT_EQ(first_video_job
, GetMediaDecoderJob(false));
1632 player_
.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1633 EXPECT_EQ(4, demuxer_
->num_data_requests());
1634 MediaDecoderJob
* second_audio_job
= GetMediaDecoderJob(true);
1635 MediaDecoderJob
* second_video_job
= GetMediaDecoderJob(false);
1636 EXPECT_NE(first_audio_job
, second_audio_job
);
1637 EXPECT_NE(first_video_job
, second_video_job
);
1638 EXPECT_TRUE(second_audio_job
&& second_video_job
);
1640 // Confirm no further demuxer configs requested.
1641 EXPECT_EQ(1, demuxer_
->num_config_requests());
1644 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInPrefetchUnit0
) {
1645 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1647 // Test that the player detects need for and requests demuxer configs if
1648 // the |kConfigChanged| unit is the very first unit in the set of units
1649 // received in OnDemuxerDataAvailable() ostensibly while
1650 // |PREFETCH_DONE_EVENT_PENDING|.
1651 StartConfigChange(true, true, 0);
1654 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInPrefetchUnit1
) {
1655 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1657 // Test that the player detects need for and requests demuxer configs if
1658 // the |kConfigChanged| unit is not the first unit in the set of units
1659 // received in OnDemuxerDataAvailable() ostensibly while
1660 // |PREFETCH_DONE_EVENT_PENDING|.
1661 StartConfigChange(true, true, 1);
1664 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInUnit0AfterPrefetch
) {
1665 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1667 // Test that the player detects need for and requests demuxer configs if
1668 // the |kConfigChanged| unit is the very first unit in the set of units
1669 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1671 StartConfigChange(true, false, 0);
1674 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInUnit1AfterPrefetch
) {
1675 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1677 // Test that the player detects need for and requests demuxer configs if
1678 // the |kConfigChanged| unit is not the first unit in the set of units
1679 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1681 StartConfigChange(true, false, 1);
1684 TEST_F(MediaSourcePlayerTest
, BrowserSeek_PrerollAfterBrowserSeek
) {
1685 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1687 // Test decoder job will preroll the media to the actual seek position
1688 // resulting from a browser seek.
1689 BrowserSeekPlayer(false);
1691 // Simulate browser seek is done, but to a later time than was requested.
1692 EXPECT_LT(player_
.GetCurrentTime().InMillisecondsF(), 100);
1693 player_
.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100));
1694 EXPECT_TRUE(GetMediaDecoderJob(false));
1695 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1696 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1697 EXPECT_EQ(3, demuxer_
->num_data_requests());
1699 PrerollDecoderToTime(
1700 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1703 TEST_F(MediaSourcePlayerTest
, VideoDemuxerConfigChange
) {
1704 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1706 // Test that video config change notification results in request for demuxer
1707 // configuration, and that a video decoder job results without any browser
1708 // seek necessary once the new demuxer config arrives.
1709 StartConfigChange(false, true, 1);
1710 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
1711 EXPECT_TRUE(first_job
);
1712 EXPECT_EQ(1, demuxer_
->num_data_requests());
1713 EXPECT_EQ(1, demuxer_
->num_config_requests());
1715 // Simulate arrival of new configs.
1716 player_
.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1718 // New video decoder job should have been created and configured, without any
1720 MediaDecoderJob
* second_job
= GetMediaDecoderJob(false);
1721 EXPECT_TRUE(second_job
);
1722 EXPECT_NE(first_job
, second_job
);
1723 EXPECT_EQ(2, demuxer_
->num_data_requests());
1724 EXPECT_EQ(1, demuxer_
->num_config_requests());
1725 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1728 TEST_F(MediaSourcePlayerTest
, VideoConfigChangeContinuesAcrossSeek
) {
1729 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1731 // Test if a demuxer config request is pending (due to previously receiving
1732 // |kConfigChanged|), and a seek request arrives prior to demuxer configs,
1733 // then seek is processed first, followed by the decoder config change.
1734 // This assumes the demuxer sends |kConfigChanged| read response prior to
1735 // canceling any reads pending seek; no |kAborted| is involved in this test.
1736 StartConfigChange(false, false, 1);
1737 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
1738 EXPECT_TRUE(first_job
);
1739 EXPECT_EQ(1, demuxer_
->num_config_requests());
1740 EXPECT_EQ(2, demuxer_
->num_data_requests());
1741 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1743 player_
.SeekTo(base::TimeDelta::FromMilliseconds(100));
1745 // Verify that the seek is requested immediately.
1746 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1748 // Simulate unlikely delayed arrival of the demuxer configs, completing the
1750 // TODO(wolenetz): Is it even possible for requested demuxer configs to be
1751 // delayed until after a SeekTo request arrives?
1752 player_
.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1754 MediaDecoderJob
* second_job
= GetMediaDecoderJob(false);
1755 EXPECT_NE(first_job
, second_job
);
1756 EXPECT_TRUE(second_job
);
1758 // Send back the seek done notification. This should finish the seek and
1759 // trigger the player to request more data.
1760 EXPECT_EQ(2, demuxer_
->num_data_requests());
1761 player_
.OnDemuxerSeekDone(kNoTimestamp());
1762 EXPECT_EQ(3, demuxer_
->num_data_requests());
1765 TEST_F(MediaSourcePlayerTest
, NewSurfaceWhileChangingConfigs
) {
1766 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1768 // Test that no seek or duplicated demuxer config request results from a
1769 // SetVideoSurface() that occurs while the player is expecting new demuxer
1770 // configs. This test may be good to keep beyond browser seek hack.
1771 StartConfigChange(false, false, 1);
1772 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
1773 EXPECT_TRUE(first_job
);
1774 EXPECT_EQ(1, demuxer_
->num_config_requests());
1775 EXPECT_EQ(2, demuxer_
->num_data_requests());
1777 CreateNextTextureAndSetVideoSurface();
1779 // Surface change processing (including decoder job re-creation) should
1780 // not occur until the pending video config change is completed.
1781 EXPECT_EQ(first_job
, GetMediaDecoderJob(false));
1783 player_
.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1784 MediaDecoderJob
* second_job
= GetMediaDecoderJob(false);
1785 EXPECT_NE(first_job
, second_job
);
1786 EXPECT_TRUE(second_job
);
1788 EXPECT_EQ(3, demuxer_
->num_data_requests());
1789 EXPECT_EQ(1, demuxer_
->num_config_requests());
1790 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1793 TEST_F(MediaSourcePlayerTest
,
1794 BrowserSeek_DecoderStarvationWhilePendingSurfaceChange
) {
1795 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1797 // Test video decoder starvation while handling a pending surface change
1798 // should not cause any crashes.
1799 CreateNextTextureAndSetVideoSurface();
1800 StartVideoDecoderJob(true);
1801 DemuxerData data
= CreateReadFromDemuxerAckForVideo();
1802 player_
.OnDemuxerDataAvailable(data
);
1804 // Trigger a surface change and decoder starvation.
1805 CreateNextTextureAndSetVideoSurface();
1806 TriggerPlayerStarvation();
1807 WaitForVideoDecodeDone();
1808 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
1810 // Surface change should trigger a seek.
1811 player_
.OnDemuxerDataAvailable(data
);
1812 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
1813 player_
.OnDemuxerSeekDone(base::TimeDelta());
1814 EXPECT_TRUE(GetMediaDecoderJob(false));
1816 // A new data request should be sent.
1817 EXPECT_EQ(3, demuxer_
->num_data_requests());
1820 TEST_F(MediaSourcePlayerTest
, ReleaseWithOnPrefetchDoneAlreadyPosted
) {
1821 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1823 // Test if OnPrefetchDone() had already been posted before and is executed
1824 // after Release(), then player does not DCHECK. This test is fragile to
1825 // change to MediaDecoderJob::Prefetch() implementation; it assumes task
1826 // is posted to run |prefetch_cb| if the job already HasData().
1827 // TODO(wolenetz): Remove MSP::set_decode_callback_for_testing() if this test
1828 // becomes obsolete. See http://crbug.com/304234.
1829 StartAudioDecoderJob(true);
1831 // Escape the original prefetch by decoding a single access unit.
1832 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1833 WaitForAudioDecodeDone();
1835 // Prime the job with a few more access units, so that a later prefetch,
1836 // triggered by starvation to simulate decoder underrun, can trivially
1837 // post task to run OnPrefetchDone().
1838 player_
.OnDemuxerDataAvailable(
1839 CreateReadFromDemuxerAckWithConfigChanged(true, 4));
1840 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1842 // Simulate decoder underrun, so trivial prefetch starts while still decoding.
1843 // The prefetch and posting of OnPrefetchDone() will not occur until next
1844 // MediaDecoderCallBack() occurs.
1845 TriggerPlayerStarvation();
1847 // Upon the next successful decode callback, post a task to call Release() on
1848 // the |player_|, such that the trivial OnPrefetchDone() task posting also
1849 // occurs and should execute after the Release().
1850 OnNextTestDecodeCallbackPostTaskToReleasePlayer();
1852 WaitForAudioDecodeDone();
1853 EXPECT_TRUE(decoder_callback_hook_executed_
);
1854 EXPECT_EQ(2, demuxer_
->num_data_requests());
1856 // Player should have no decoder job until after Start().
1857 StartAudioDecoderJob(true);
1860 TEST_F(MediaSourcePlayerTest
, SeekToThenReleaseThenDemuxerSeekAndDone
) {
1861 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1863 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1864 // has not yet been sent, then the seek request is sent after Release(). Also,
1865 // test if OnDemuxerSeekDone() occurs prior to next Start(), then the player
1866 // will resume correct post-seek preroll upon Start().
1867 StartAudioDecoderJobAndSeekToWhileDecoding(
1868 base::TimeDelta::FromMilliseconds(100));
1870 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1872 player_
.OnDemuxerSeekDone(kNoTimestamp());
1873 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1874 EXPECT_FALSE(GetMediaDecoderJob(true));
1875 EXPECT_FALSE(player_
.IsPlaying());
1877 // Player should begin prefetch and resume preroll upon Start().
1878 EXPECT_EQ(2, demuxer_
->num_data_requests());
1879 StartAudioDecoderJob(true);
1880 EXPECT_TRUE(IsPrerolling(true));
1881 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1883 // No further seek should have been requested since Release(), above.
1884 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1887 TEST_F(MediaSourcePlayerTest
, SeekToThenReleaseThenDemuxerSeekThenStart
) {
1888 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1890 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1891 // has not yet been sent, then the seek request is sent after Release(). Also,
1892 // test if OnDemuxerSeekDone() does not occur until after the next Start(),
1893 // then the player remains pending seek done until (and resumes correct
1894 // post-seek preroll after) OnDemuxerSeekDone().
1895 StartAudioDecoderJobAndSeekToWhileDecoding(
1896 base::TimeDelta::FromMilliseconds(100));
1898 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1900 // Player should not prefetch upon Start() nor create the decoder job, due to
1901 // awaiting DemuxerSeekDone.
1902 EXPECT_EQ(2, demuxer_
->num_data_requests());
1903 StartAudioDecoderJob(false);
1905 player_
.OnDemuxerSeekDone(kNoTimestamp());
1906 EXPECT_TRUE(GetMediaDecoderJob(true));
1907 EXPECT_TRUE(IsPrerolling(true));
1908 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1909 EXPECT_EQ(3, demuxer_
->num_data_requests());
1911 // No further seek should have been requested since Release(), above.
1912 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1915 TEST_F(MediaSourcePlayerTest
, SeekToThenDemuxerSeekThenReleaseThenSeekDone
) {
1916 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1918 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC
1919 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the
1920 // player will resume correct post-seek preroll upon Start().
1921 StartAudioDecoderJobAndSeekToWhileDecoding(
1922 base::TimeDelta::FromMilliseconds(100));
1923 WaitForAudioDecodeDone();
1924 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1927 player_
.OnDemuxerSeekDone(kNoTimestamp());
1928 EXPECT_FALSE(player_
.IsPlaying());
1929 EXPECT_FALSE(GetMediaDecoderJob(true));
1930 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1932 // Player should begin prefetch and resume preroll upon Start().
1933 EXPECT_EQ(2, demuxer_
->num_data_requests());
1934 StartAudioDecoderJob(true);
1935 EXPECT_TRUE(IsPrerolling(true));
1936 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1938 // No further seek should have been requested since before Release(), above.
1939 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1942 TEST_F(MediaSourcePlayerTest
, SeekToThenReleaseThenStart
) {
1943 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1945 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC
1946 // request and OnDemuxerSeekDone() does not occur until after the next
1947 // Start(), then the player remains pending seek done until (and resumes
1948 // correct post-seek preroll after) OnDemuxerSeekDone().
1949 StartAudioDecoderJobAndSeekToWhileDecoding(
1950 base::TimeDelta::FromMilliseconds(100));
1951 WaitForAudioDecodeDone();
1952 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1955 EXPECT_EQ(2, demuxer_
->num_data_requests());
1956 StartAudioDecoderJob(false);
1958 player_
.OnDemuxerSeekDone(kNoTimestamp());
1959 EXPECT_TRUE(GetMediaDecoderJob(true));
1960 EXPECT_TRUE(IsPrerolling(true));
1961 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1962 EXPECT_EQ(3, demuxer_
->num_data_requests());
1964 // No further seek should have been requested since before Release(), above.
1965 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1968 TEST_F(MediaSourcePlayerTest
, ConfigChangedThenReleaseThenConfigsAvailable
) {
1969 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1971 // Test if Release() occurs after |kConfigChanged| detected, new configs
1972 // requested of demuxer, and the requested configs arrive before the next
1973 // Start(), then the player completes the pending config change processing on
1975 StartConfigChange(true, true, 0);
1978 player_
.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis
));
1979 EXPECT_FALSE(GetMediaDecoderJob(true));
1980 EXPECT_FALSE(player_
.IsPlaying());
1981 EXPECT_EQ(1, demuxer_
->num_data_requests());
1983 // Player should resume upon Start(), even without further configs supplied.
1985 EXPECT_TRUE(GetMediaDecoderJob(true));
1986 EXPECT_TRUE(player_
.IsPlaying());
1987 EXPECT_EQ(2, demuxer_
->num_data_requests());
1989 // No further config request should have occurred since StartConfigChange().
1990 EXPECT_EQ(1, demuxer_
->num_config_requests());
1993 TEST_F(MediaSourcePlayerTest
, ConfigChangedThenReleaseThenStart
) {
1994 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1996 // Test if Release() occurs after |kConfigChanged| detected, new configs
1997 // requested of demuxer, and the requested configs arrive after the next
1998 // Start(), then the player pends job creation until the new configs arrive.
1999 StartConfigChange(true, true, 0);
2003 EXPECT_TRUE(player_
.IsPlaying());
2004 EXPECT_FALSE(GetMediaDecoderJob(true));
2005 EXPECT_EQ(1, demuxer_
->num_data_requests());
2007 player_
.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis
));
2008 EXPECT_TRUE(GetMediaDecoderJob(true));
2009 EXPECT_EQ(2, demuxer_
->num_data_requests());
2011 // No further config request should have occurred since StartConfigChange().
2012 EXPECT_EQ(1, demuxer_
->num_config_requests());
2015 TEST_F(MediaSourcePlayerTest
, BrowserSeek_ThenReleaseThenDemuxerSeekDone
) {
2016 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2018 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
2019 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() occurs
2020 // before the next Start()+SetVideoSurface(), then the player will resume
2021 // correct post-seek preroll upon Start()+SetVideoSurface().
2022 BrowserSeekPlayer(false);
2023 base::TimeDelta expected_preroll_timestamp
= player_
.GetCurrentTime();
2026 player_
.OnDemuxerSeekDone(expected_preroll_timestamp
);
2027 EXPECT_FALSE(player_
.IsPlaying());
2028 EXPECT_FALSE(GetMediaDecoderJob(false));
2029 EXPECT_EQ(expected_preroll_timestamp
, GetPrerollTimestamp());
2031 // Player should begin prefetch and resume preroll upon Start().
2032 EXPECT_EQ(2, demuxer_
->num_data_requests());
2033 CreateNextTextureAndSetVideoSurface();
2034 StartVideoDecoderJob(true);
2035 EXPECT_TRUE(IsPrerolling(false));
2036 EXPECT_EQ(expected_preroll_timestamp
, GetPrerollTimestamp());
2037 EXPECT_EQ(expected_preroll_timestamp
, player_
.GetCurrentTime());
2039 // No further seek should have been requested since BrowserSeekPlayer().
2040 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2043 TEST_F(MediaSourcePlayerTest
, BrowserSeek_ThenReleaseThenStart
) {
2044 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2046 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
2047 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
2048 // occur until after the next Start()+SetVideoSurface(), then the player
2049 // remains pending seek done until (and resumes correct post-seek preroll
2050 // after) OnDemuxerSeekDone().
2051 BrowserSeekPlayer(false);
2052 base::TimeDelta expected_preroll_timestamp
= player_
.GetCurrentTime();
2055 EXPECT_EQ(2, demuxer_
->num_data_requests());
2056 CreateNextTextureAndSetVideoSurface();
2057 StartVideoDecoderJob(false);
2059 player_
.OnDemuxerSeekDone(expected_preroll_timestamp
);
2060 EXPECT_TRUE(GetMediaDecoderJob(false));
2061 EXPECT_TRUE(IsPrerolling(false));
2062 EXPECT_EQ(expected_preroll_timestamp
, GetPrerollTimestamp());
2063 EXPECT_EQ(expected_preroll_timestamp
, player_
.GetCurrentTime());
2064 EXPECT_EQ(3, demuxer_
->num_data_requests());
2066 // No further seek should have been requested since BrowserSeekPlayer().
2067 EXPECT_EQ(1, demuxer_
->num_seek_requests());
2070 // TODO(xhwang): Once we add tests to cover DrmBridge, update this test to
2071 // also verify that the job is successfully created if SetDrmBridge(), Start()
2072 // and eventually OnMediaCrypto() occur. This would increase test coverage of
2073 // http://crbug.com/313470 and allow us to remove inspection of internal player
2074 // pending event state. See http://crbug.com/313860.
2075 TEST_F(MediaSourcePlayerTest
, SurfaceChangeClearedEvenIfMediaCryptoAbsent
) {
2076 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2078 // Test that |SURFACE_CHANGE_EVENT_PENDING| is not pending after
2079 // SetVideoSurface() for a player configured for encrypted video, when the
2080 // player has not yet received media crypto.
2081 DemuxerConfigs configs
= CreateVideoDemuxerConfigs();
2082 configs
.is_video_encrypted
= true;
2084 player_
.OnDemuxerConfigsAvailable(configs
);
2085 CreateNextTextureAndSetVideoSurface();
2086 EXPECT_FALSE(IsPendingSurfaceChange());
2087 EXPECT_FALSE(GetMediaDecoderJob(false));
2090 TEST_F(MediaSourcePlayerTest
, CurrentTimeUpdatedWhileDecoderStarved
) {
2091 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2093 // Test that current time is updated while decoder is starved.
2094 StartAudioDecoderJob(true);
2095 DecodeAudioDataUntilOutputBecomesAvailable();
2097 // Trigger starvation while the decoder is decoding.
2098 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
2099 manager_
.ResetTimestampUpdated();
2100 TriggerPlayerStarvation();
2101 WaitForAudioDecodeDone();
2103 // Current time should be updated.
2104 EXPECT_TRUE(manager_
.timestamp_updated());
2107 TEST_F(MediaSourcePlayerTest
, CurrentTimeKeepsIncreasingAfterConfigChange
) {
2108 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2110 // Test current time keep on increasing after audio config change.
2111 // Test that current time is updated while decoder is starved.
2112 StartAudioDecoderJob(true);
2114 DecodeAudioDataUntilOutputBecomesAvailable();
2116 DemuxerData data
= CreateReadFromDemuxerAckWithConfigChanged(true, 0);
2117 player_
.OnDemuxerDataAvailable(data
);
2118 WaitForAudioDecodeDone();
2120 // Simulate arrival of new configs.
2121 player_
.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis
));
2122 DecodeAudioDataUntilOutputBecomesAvailable();
2125 } // namespace media