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/memory/scoped_ptr.h"
9 #include "base/strings/stringprintf.h"
10 #include "media/base/android/media_codec_bridge.h"
11 #include "media/base/android/media_drm_bridge.h"
12 #include "media/base/android/media_player_manager.h"
13 #include "media/base/android/media_source_player.h"
14 #include "media/base/decoder_buffer.h"
15 #include "media/base/test_data_util.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "ui/gl/android/surface_texture.h"
21 // Helper macro to skip the test if MediaCodecBridge isn't available.
22 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
24 if (!MediaCodecBridge::IsAvailable()) { \
25 LOG(INFO) << "Could not run test - not supported on device."; \
30 static const int kDefaultDurationInMs = 10000;
32 static const char kAudioMp4
[] = "audio/mp4";
33 static const char kVideoMp4
[] = "video/mp4";
34 static const char kAudioWebM
[] = "audio/webm";
35 static const char kVideoWebM
[] = "video/webm";
37 // Mock of MediaPlayerManager for testing purpose
38 class MockMediaPlayerManager
: public MediaPlayerManager
{
40 explicit MockMediaPlayerManager(base::MessageLoop
* message_loop
)
41 : message_loop_(message_loop
) {}
42 virtual ~MockMediaPlayerManager() {}
44 // MediaPlayerManager implementation.
45 virtual void RequestMediaResources(int player_id
) OVERRIDE
{}
46 virtual void ReleaseMediaResources(int player_id
) OVERRIDE
{}
47 virtual MediaResourceGetter
* GetMediaResourceGetter() OVERRIDE
{
50 virtual void OnTimeUpdate(int player_id
,
51 base::TimeDelta current_time
) OVERRIDE
{}
52 virtual void OnMediaMetadataChanged(
53 int player_id
, base::TimeDelta duration
, int width
, int height
,
54 bool success
) OVERRIDE
{}
55 virtual void OnPlaybackComplete(int player_id
) OVERRIDE
{
56 if (message_loop_
->is_running())
57 message_loop_
->Quit();
59 virtual void OnMediaInterrupted(int player_id
) OVERRIDE
{}
60 virtual void OnBufferingUpdate(int player_id
, int percentage
) OVERRIDE
{}
61 virtual void OnSeekComplete(int player_id
,
62 const base::TimeDelta
& current_time
) OVERRIDE
{}
63 virtual void OnError(int player_id
, int error
) OVERRIDE
{}
64 virtual void OnVideoSizeChanged(int player_id
, int width
,
65 int height
) OVERRIDE
{}
66 virtual MediaPlayerAndroid
* GetFullscreenPlayer() OVERRIDE
{ return NULL
; }
67 virtual MediaPlayerAndroid
* GetPlayer(int player_id
) OVERRIDE
{ return NULL
; }
68 virtual void DestroyAllMediaPlayers() OVERRIDE
{}
69 virtual MediaDrmBridge
* GetDrmBridge(int media_keys_id
) OVERRIDE
{
72 virtual void OnProtectedSurfaceRequested(int player_id
) OVERRIDE
{}
73 virtual void OnKeyAdded(int key_id
,
74 const std::string
& session_id
) OVERRIDE
{}
75 virtual void OnKeyError(int key_id
,
76 const std::string
& session_id
,
77 MediaKeys::KeyError error_code
,
78 int system_code
) OVERRIDE
{}
79 virtual void OnKeyMessage(int key_id
,
80 const std::string
& session_id
,
81 const std::vector
<uint8
>& message
,
82 const std::string
& destination_url
) OVERRIDE
{}
85 base::MessageLoop
* message_loop_
;
87 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager
);
90 class MockDemuxerAndroid
: public DemuxerAndroid
{
92 explicit MockDemuxerAndroid(base::MessageLoop
* message_loop
)
93 : message_loop_(message_loop
),
94 num_data_requests_(0),
95 num_seek_requests_(0),
96 num_browser_seek_requests_(0),
97 num_config_requests_(0) {}
98 virtual ~MockDemuxerAndroid() {}
100 virtual void Initialize(DemuxerAndroidClient
* client
) OVERRIDE
{}
101 virtual void RequestDemuxerConfigs() OVERRIDE
{
102 num_config_requests_
++;
104 virtual void RequestDemuxerData(DemuxerStream::Type type
) OVERRIDE
{
105 num_data_requests_
++;
106 if (message_loop_
->is_running())
107 message_loop_
->Quit();
109 virtual void RequestDemuxerSeek(const base::TimeDelta
& time_to_seek
,
110 bool is_browser_seek
) OVERRIDE
{
111 num_seek_requests_
++;
113 num_browser_seek_requests_
++;
116 int num_data_requests() const { return num_data_requests_
; }
117 int num_seek_requests() const { return num_seek_requests_
; }
118 int num_browser_seek_requests() const { return num_browser_seek_requests_
; }
119 int num_config_requests() const { return num_config_requests_
; }
122 base::MessageLoop
* message_loop_
;
124 // The number of encoded data requests this object has seen.
125 int num_data_requests_
;
127 // The number of regular and browser seek requests this object has seen.
128 int num_seek_requests_
;
130 // The number of browser seek requests this object has seen.
131 int num_browser_seek_requests_
;
133 // The number of demuxer config requests this object has seen.
134 int num_config_requests_
;
136 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid
);
139 class MediaSourcePlayerTest
: public testing::Test
{
141 MediaSourcePlayerTest()
142 : manager_(&message_loop_
),
143 demuxer_(new MockDemuxerAndroid(&message_loop_
)),
144 player_(0, &manager_
, scoped_ptr
<DemuxerAndroid
>(demuxer_
)),
145 surface_texture_a_is_next_(true) {}
146 virtual ~MediaSourcePlayerTest() {}
149 // Get the decoder job from the MediaSourcePlayer.
150 MediaDecoderJob
* GetMediaDecoderJob(bool is_audio
) {
152 return reinterpret_cast<MediaDecoderJob
*>(
153 player_
.audio_decoder_job_
.get());
155 return reinterpret_cast<MediaDecoderJob
*>(
156 player_
.video_decoder_job_
.get());
159 // Get the per-job prerolling status from the MediaSourcePlayer's job matching
160 // |is_audio|. Caller must guard against NPE if the player's job is NULL.
161 bool IsPrerolling(bool is_audio
) {
162 return GetMediaDecoderJob(is_audio
)->prerolling();
165 // Get the preroll timestamp from the MediaSourcePlayer.
166 base::TimeDelta
GetPrerollTimestamp() {
167 return player_
.preroll_timestamp_
;
170 DemuxerConfigs
CreateAudioDemuxerConfigs() {
171 DemuxerConfigs configs
;
172 configs
.audio_codec
= kCodecVorbis
;
173 configs
.audio_channels
= 2;
174 configs
.audio_sampling_rate
= 44100;
175 configs
.is_audio_encrypted
= false;
176 configs
.duration_ms
= kDefaultDurationInMs
;
177 scoped_refptr
<DecoderBuffer
> buffer
= ReadTestDataFile("vorbis-extradata");
178 configs
.audio_extra_data
= std::vector
<uint8
>(
180 buffer
->data() + buffer
->data_size());
184 // Starts an audio decoder job.
185 void StartAudioDecoderJob() {
186 Start(CreateAudioDemuxerConfigs());
189 DemuxerConfigs
CreateVideoDemuxerConfigs() {
190 DemuxerConfigs configs
;
191 configs
.video_codec
= kCodecVP8
;
192 configs
.video_size
= gfx::Size(320, 240);
193 configs
.is_video_encrypted
= false;
194 configs
.duration_ms
= kDefaultDurationInMs
;
198 DemuxerConfigs
CreateAudioVideoDemuxerConfigs() {
199 DemuxerConfigs configs
= CreateAudioDemuxerConfigs();
200 configs
.video_codec
= kCodecVP8
;
201 configs
.video_size
= gfx::Size(320, 240);
202 configs
.is_video_encrypted
= false;
206 void StartVideoDecoderJob() {
207 Start(CreateVideoDemuxerConfigs());
210 // Starts decoding the data.
211 void Start(const DemuxerConfigs
& configs
) {
212 player_
.OnDemuxerConfigsAvailable(configs
);
214 EXPECT_TRUE(player_
.IsPlaying());
217 AccessUnit
CreateAccessUnitWithData(bool is_audio
, int audio_packet_id
) {
220 unit
.status
= DemuxerStream::kOk
;
221 scoped_refptr
<DecoderBuffer
> buffer
= ReadTestDataFile(
222 is_audio
? base::StringPrintf("vorbis-packet-%d", audio_packet_id
)
223 : "vp8-I-frame-320x240");
224 unit
.data
= std::vector
<uint8
>(
225 buffer
->data(), buffer
->data() + buffer
->data_size());
228 // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
229 // NuMediaExtractor.cpp in Android source code.
230 uint8 padding
[4] = { 0xff , 0xff , 0xff , 0xff };
231 unit
.data
.insert(unit
.data
.end(), padding
, padding
+ 4);
237 DemuxerData
CreateReadFromDemuxerAckForAudio(int packet_id
) {
239 data
.type
= DemuxerStream::AUDIO
;
240 data
.access_units
.resize(1);
241 data
.access_units
[0] = CreateAccessUnitWithData(true, packet_id
);
245 DemuxerData
CreateReadFromDemuxerAckForVideo() {
247 data
.type
= DemuxerStream::VIDEO
;
248 data
.access_units
.resize(1);
249 data
.access_units
[0] = CreateAccessUnitWithData(false, 0);
253 DemuxerData
CreateEOSAck(bool is_audio
) {
255 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
256 data
.access_units
.resize(1);
257 data
.access_units
[0].status
= DemuxerStream::kOk
;
258 data
.access_units
[0].end_of_stream
= true;
262 DemuxerData
CreateAbortedAck(bool is_audio
) {
264 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
265 data
.access_units
.resize(1);
266 data
.access_units
[0].status
= DemuxerStream::kAborted
;
270 // Seek, including simulated receipt of |kAborted| read between SeekTo()
271 // and OnDemuxerSeekDone(). Use this helper method only when the player
272 // already has created the decoder job.
273 void SeekPlayer(bool is_audio
, const base::TimeDelta
& seek_time
) {
274 EXPECT_TRUE(GetMediaDecoderJob(is_audio
));
276 int original_num_seeks
= demuxer_
->num_seek_requests();
277 int original_num_data_requests
= demuxer_
->num_data_requests();
279 // Initiate a seek. Skip the round-trip of requesting seek from renderer.
280 // Instead behave as if the renderer has asked us to seek.
281 player_
.SeekTo(seek_time
);
283 // Verify that the seek does not occur until previously outstanding data
284 // request is satisfied.
285 EXPECT_EQ(original_num_seeks
, demuxer_
->num_seek_requests());
287 // Simulate seeking causes the demuxer to abort the outstanding read caused
289 player_
.OnDemuxerDataAvailable(CreateAbortedAck(is_audio
));
291 // Verify that the seek is requested now that the outstanding read is
292 // completed by aborted access unit.
293 EXPECT_EQ(original_num_seeks
+ 1, demuxer_
->num_seek_requests());
295 // Send back the seek done notification. This should trigger the player to
296 // call OnReadFromDemuxer() again.
297 EXPECT_EQ(original_num_data_requests
, demuxer_
->num_data_requests());
298 player_
.OnDemuxerSeekDone(kNoTimestamp());
299 EXPECT_EQ(original_num_data_requests
+ 1, demuxer_
->num_data_requests());
301 // No other seek should have been requested.
302 EXPECT_EQ(original_num_seeks
+ 1, demuxer_
->num_seek_requests());
305 DemuxerData
CreateReadFromDemuxerAckWithConfigChanged(bool is_audio
,
306 int config_unit_index
) {
308 data
.type
= is_audio
? DemuxerStream::AUDIO
: DemuxerStream::VIDEO
;
309 data
.access_units
.resize(config_unit_index
+ 1);
311 for (int i
= 0; i
< config_unit_index
; ++i
)
312 data
.access_units
[i
] = CreateAccessUnitWithData(is_audio
, i
);
314 data
.access_units
[config_unit_index
].status
= DemuxerStream::kConfigChanged
;
318 // Valid only for video-only player tests. If |trigger_with_release_start| is
319 // true, triggers the browser seek with a Release() + video data received +
320 // Start() with a new surface. If false, triggers the browser seek by
321 // setting a new video surface after beginning decode of received video data.
322 // Such data receipt causes possibility that an I-frame is not next, and
323 // browser seek results once decode completes and surface change processing
325 void BrowserSeekPlayer(bool trigger_with_release_start
) {
326 int expected_num_data_requests
= demuxer_
->num_data_requests();
327 int expected_num_seek_requests
= demuxer_
->num_seek_requests();
328 int expected_num_browser_seek_requests
=
329 demuxer_
->num_browser_seek_requests();
331 EXPECT_FALSE(GetMediaDecoderJob(false));
332 CreateNextTextureAndSetVideoSurface();
333 StartVideoDecoderJob();
334 EXPECT_TRUE(GetMediaDecoderJob(false));
335 expected_num_data_requests
++;
336 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
338 if (trigger_with_release_start
) {
341 // Simulate demuxer's response to the video data request.
342 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
343 EXPECT_FALSE(GetMediaDecoderJob(false));
344 EXPECT_FALSE(player_
.IsPlaying());
345 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
346 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
348 CreateNextTextureAndSetVideoSurface();
351 // Simulate demuxer's response to the video data request.
352 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
354 // While the decoder is decoding, trigger a browser seek by changing
355 // surface. Demuxer does not know of browser seek in advance, so no
356 // |kAborted| data is required (though |kAborted| can certainly occur for
357 // any pending read in reality due to renderer preparing for a regular
359 CreateNextTextureAndSetVideoSurface();
361 // Browser seek should not begin until decoding has completed.
362 EXPECT_TRUE(GetMediaDecoderJob(false));
363 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
364 EXPECT_EQ(expected_num_browser_seek_requests
,
365 demuxer_
->num_browser_seek_requests());
367 // Wait for the decoder job to finish decoding and be reset pending the
369 while (GetMediaDecoderJob(false) &&
370 GetMediaDecoderJob(false)->is_decoding()) {
371 message_loop_
.RunUntilIdle();
375 EXPECT_FALSE(GetMediaDecoderJob(false));
376 EXPECT_TRUE(player_
.IsPlaying());
378 // Only one browser seek should have been initiated, and no further data
379 // should have been requested.
380 expected_num_seek_requests
++;
381 expected_num_browser_seek_requests
++;
382 EXPECT_EQ(expected_num_seek_requests
, demuxer_
->num_seek_requests());
383 EXPECT_EQ(expected_num_browser_seek_requests
,
384 demuxer_
->num_browser_seek_requests());
385 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_seek_requests());
388 // Creates a new decoder job and feeds it data ending with a |kConfigChanged|
389 // access unit. If |config_unit_in_prefetch| is true, sends feeds the config
390 // change AU in response to the job's first read request (prefetch). If
391 // false, regular data is fed and decoded prior to feeding the config change
392 // AU in response to the second data request (after prefetch completed).
393 // |config_unit_index| controls which access unit is |kConfigChanged|.
394 void StartConfigChange(bool is_audio
,
395 bool config_unit_in_prefetch
,
396 int config_unit_index
) {
397 int expected_num_data_requests
= demuxer_
->num_data_requests();
398 int expected_num_config_requests
= demuxer_
->num_config_requests();
400 EXPECT_FALSE(GetMediaDecoderJob(is_audio
));
402 StartAudioDecoderJob();
404 CreateNextTextureAndSetVideoSurface();
405 StartVideoDecoderJob();
407 EXPECT_TRUE(GetMediaDecoderJob(is_audio
));
408 expected_num_data_requests
++;
409 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
410 EXPECT_EQ(expected_num_config_requests
, demuxer_
->num_config_requests());
412 // Feed and decode a standalone access unit so the player exits prefetch.
413 if (!config_unit_in_prefetch
) {
415 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
417 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
421 // We should have completed the prefetch phase at this point.
422 EXPECT_TRUE(GetMediaDecoderJob(is_audio
));
423 expected_num_data_requests
++;
424 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
425 EXPECT_EQ(expected_num_config_requests
, demuxer_
->num_config_requests());
428 // Feed and decode access units with data for any units prior to
429 // |config_unit_index|, and a |kConfigChanged| unit at that index.
430 // Player should prepare to reconfigure the decoder job, and should request
431 // new demuxer configs.
432 player_
.OnDemuxerDataAvailable(
433 CreateReadFromDemuxerAckWithConfigChanged(is_audio
, config_unit_index
));
434 while (GetMediaDecoderJob(is_audio
)->is_decoding())
435 message_loop_
.RunUntilIdle();
437 expected_num_config_requests
++;
438 EXPECT_TRUE(player_
.IsPlaying());
439 EXPECT_TRUE(GetMediaDecoderJob(is_audio
));
440 EXPECT_EQ(expected_num_data_requests
, demuxer_
->num_data_requests());
441 EXPECT_EQ(expected_num_config_requests
, demuxer_
->num_config_requests());
444 void CreateNextTextureAndSetVideoSurface() {
445 gfx::SurfaceTexture
* surface_texture
;
446 if (surface_texture_a_is_next_
) {
447 surface_texture_a_
= new gfx::SurfaceTexture(next_texture_id_
++);
448 surface_texture
= surface_texture_a_
.get();
450 surface_texture_b_
= new gfx::SurfaceTexture(next_texture_id_
++);
451 surface_texture
= surface_texture_b_
.get();
454 surface_texture_a_is_next_
= !surface_texture_a_is_next_
;
455 gfx::ScopedJavaSurface surface
= gfx::ScopedJavaSurface(surface_texture
);
456 player_
.SetVideoSurface(surface
.Pass());
459 base::TimeTicks
StartTimeTicks() {
460 return player_
.start_time_ticks_
;
463 bool IsTypeSupported(const std::vector
<uint8
>& scheme_uuid
,
464 const std::string
& security_level
,
465 const std::string
& container
,
466 const std::vector
<std::string
>& codecs
) {
467 return MediaSourcePlayer::IsTypeSupported(
468 scheme_uuid
, security_level
, container
, codecs
);
472 base::MessageLoop message_loop_
;
473 MockMediaPlayerManager manager_
;
474 MockDemuxerAndroid
* demuxer_
; // Owned by |player_|.
475 MediaSourcePlayer player_
;
477 // We need to keep the surface texture while the decoder is actively decoding.
478 // Otherwise, it may trigger unexpected crashes on some devices. To switch
479 // surfaces, tests need to create a new surface texture without releasing
480 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
481 // between two surface textures, only replacing the N-2 texture. Assumption is
482 // that no more than N-1 texture is in use by decoder when
483 // CreateNextTextureAndSetVideoSurface() is called.
484 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_a_
;
485 scoped_refptr
<gfx::SurfaceTexture
> surface_texture_b_
;
486 bool surface_texture_a_is_next_
;
487 int next_texture_id_
;
489 DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayerTest
);
492 TEST_F(MediaSourcePlayerTest
, StartAudioDecoderWithValidConfig
) {
493 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
495 // Test audio decoder job will be created when codec is successfully started.
496 StartAudioDecoderJob();
497 EXPECT_TRUE(GetMediaDecoderJob(true));
498 EXPECT_EQ(1, demuxer_
->num_data_requests());
499 EXPECT_EQ(0, demuxer_
->num_seek_requests());
502 TEST_F(MediaSourcePlayerTest
, StartAudioDecoderWithInvalidConfig
) {
503 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
505 // Test audio decoder job will not be created when failed to start the codec.
506 DemuxerConfigs configs
= CreateAudioDemuxerConfigs();
507 // Replace with invalid |audio_extra_data|
508 configs
.audio_extra_data
.clear();
509 uint8 invalid_codec_data
[] = { 0x00, 0xff, 0xff, 0xff, 0xff };
510 configs
.audio_extra_data
.insert(configs
.audio_extra_data
.begin(),
511 invalid_codec_data
, invalid_codec_data
+ 4);
513 EXPECT_FALSE(GetMediaDecoderJob(true));
514 EXPECT_EQ(0, demuxer_
->num_data_requests());
515 EXPECT_EQ(0, demuxer_
->num_seek_requests());
518 TEST_F(MediaSourcePlayerTest
, StartVideoCodecWithValidSurface
) {
519 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
521 // Test video decoder job will be created when surface is valid.
522 StartVideoDecoderJob();
523 // Video decoder job will not be created until surface is available.
524 EXPECT_FALSE(GetMediaDecoderJob(false));
525 EXPECT_EQ(0, demuxer_
->num_data_requests());
527 // Set both an initial and a later video surface without receiving any
529 CreateNextTextureAndSetVideoSurface();
530 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
531 EXPECT_TRUE(first_job
);
532 CreateNextTextureAndSetVideoSurface();
534 // Setting another surface will not create a new job until any pending
535 // read is satisfied (and job is no longer decoding).
536 EXPECT_EQ(first_job
, GetMediaDecoderJob(false));
538 // No seeks, even on setting surface, should have occurred. (Browser seeks can
539 // occur on setting surface, but only after previously receiving video data.)
540 EXPECT_EQ(0, demuxer_
->num_seek_requests());
542 // Note, the decoder job for the second surface set, above, will be created
543 // only after the pending read is satisfied and decoded, and the resulting
544 // browser seek is done. See BrowserSeek_* tests for this coverage.
547 TEST_F(MediaSourcePlayerTest
, StartVideoCodecWithInvalidSurface
) {
548 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
550 // Test video decoder job will be created when surface is valid.
551 scoped_refptr
<gfx::SurfaceTexture
> surface_texture(
552 new gfx::SurfaceTexture(0));
553 gfx::ScopedJavaSurface
surface(surface_texture
.get());
554 StartVideoDecoderJob();
555 // Video decoder job will not be created until surface is available.
556 EXPECT_FALSE(GetMediaDecoderJob(false));
557 EXPECT_EQ(0, demuxer_
->num_data_requests());
559 // Release the surface texture.
560 surface_texture
= NULL
;
561 player_
.SetVideoSurface(surface
.Pass());
563 // Player should not seek the demuxer on setting initial surface.
564 EXPECT_EQ(0, demuxer_
->num_seek_requests());
566 EXPECT_FALSE(GetMediaDecoderJob(false));
567 EXPECT_EQ(0, demuxer_
->num_data_requests());
570 TEST_F(MediaSourcePlayerTest
, ReadFromDemuxerAfterSeek
) {
571 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
573 // Test decoder job will resend a ReadFromDemuxer request after seek.
574 StartAudioDecoderJob();
575 EXPECT_TRUE(GetMediaDecoderJob(true));
576 EXPECT_EQ(1, demuxer_
->num_data_requests());
577 SeekPlayer(true, base::TimeDelta());
578 EXPECT_EQ(2, demuxer_
->num_data_requests());
581 TEST_F(MediaSourcePlayerTest
, SetSurfaceWhileSeeking
) {
582 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
584 // Test SetVideoSurface() will not cause an extra seek while the player is
585 // waiting for demuxer to indicate seek is done.
586 StartVideoDecoderJob();
587 // Player is still waiting for SetVideoSurface(), so no request is sent.
588 EXPECT_EQ(0, demuxer_
->num_data_requests());
590 // Initiate a seek. Skip requesting element seek of renderer.
591 // Instead behave as if the renderer has asked us to seek.
592 EXPECT_EQ(0, demuxer_
->num_seek_requests());
593 player_
.SeekTo(base::TimeDelta());
594 EXPECT_EQ(1, demuxer_
->num_seek_requests());
596 CreateNextTextureAndSetVideoSurface();
597 EXPECT_FALSE(GetMediaDecoderJob(false));
598 EXPECT_EQ(1, demuxer_
->num_seek_requests());
600 // Reconfirm player has not yet requested data.
601 EXPECT_EQ(0, demuxer_
->num_data_requests());
603 // Send the seek done notification. The player should start requesting data.
604 player_
.OnDemuxerSeekDone(kNoTimestamp());
605 EXPECT_TRUE(GetMediaDecoderJob(false));
606 EXPECT_EQ(1, demuxer_
->num_data_requests());
608 // Reconfirm exactly 1 seek request has been made of demuxer, and that it
609 // was not a browser seek request.
610 EXPECT_EQ(1, demuxer_
->num_seek_requests());
611 EXPECT_EQ(0, demuxer_
->num_browser_seek_requests());
614 TEST_F(MediaSourcePlayerTest
, ChangeMultipleSurfaceWhileDecoding
) {
615 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
617 // Test MediaSourcePlayer can switch multiple surfaces during decoding.
618 CreateNextTextureAndSetVideoSurface();
619 StartVideoDecoderJob();
620 EXPECT_EQ(1, demuxer_
->num_data_requests());
621 EXPECT_EQ(0, demuxer_
->num_seek_requests());
622 EXPECT_TRUE(GetMediaDecoderJob(false));
624 // Send the first input chunk.
625 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
627 // While the decoder is decoding, change multiple surfaces. Pass an empty
629 gfx::ScopedJavaSurface empty_surface
;
630 player_
.SetVideoSurface(empty_surface
.Pass());
631 // Next, pass a new non-empty surface.
632 CreateNextTextureAndSetVideoSurface();
634 // Wait for the decoder job to finish decoding and be reset pending a browser
636 while (GetMediaDecoderJob(false) && GetMediaDecoderJob(false)->is_decoding())
637 message_loop_
.RunUntilIdle();
638 EXPECT_FALSE(GetMediaDecoderJob(false));
640 // Only one browser seek should have been initiated. No further data request
641 // should have been processed on |message_loop_| before surface change event
642 // became pending, above.
643 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
644 EXPECT_EQ(1, demuxer_
->num_data_requests());
646 // Simulate browser seek is done and confirm player requests more data for new
647 // video decoder job.
648 player_
.OnDemuxerSeekDone(player_
.GetCurrentTime());
649 EXPECT_TRUE(GetMediaDecoderJob(false));
650 EXPECT_EQ(2, demuxer_
->num_data_requests());
651 EXPECT_EQ(1, demuxer_
->num_seek_requests());
654 TEST_F(MediaSourcePlayerTest
, AudioOnlyStartAfterSeekFinish
) {
655 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
657 // Test audio decoder job will not start until pending seek event is handled.
658 DemuxerConfigs configs
= CreateAudioDemuxerConfigs();
659 player_
.OnDemuxerConfigsAvailable(configs
);
660 EXPECT_FALSE(GetMediaDecoderJob(true));
661 EXPECT_EQ(0, demuxer_
->num_data_requests());
663 // Initiate a seek. Skip requesting element seek of renderer.
664 // Instead behave as if the renderer has asked us to seek.
665 player_
.SeekTo(base::TimeDelta());
666 EXPECT_EQ(1, demuxer_
->num_seek_requests());
669 EXPECT_FALSE(GetMediaDecoderJob(true));
670 EXPECT_EQ(0, demuxer_
->num_data_requests());
672 // Sending back the seek done notification.
673 player_
.OnDemuxerSeekDone(kNoTimestamp());
674 EXPECT_TRUE(GetMediaDecoderJob(true));
675 EXPECT_EQ(1, demuxer_
->num_data_requests());
677 // Reconfirm exactly 1 seek request has been made of demuxer.
678 EXPECT_EQ(1, demuxer_
->num_seek_requests());
681 TEST_F(MediaSourcePlayerTest
, VideoOnlyStartAfterSeekFinish
) {
682 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
684 // Test video decoder job will not start until pending seek event is handled.
685 CreateNextTextureAndSetVideoSurface();
686 DemuxerConfigs configs
= CreateVideoDemuxerConfigs();
687 player_
.OnDemuxerConfigsAvailable(configs
);
688 EXPECT_FALSE(GetMediaDecoderJob(false));
690 // Initiate a seek. Skip requesting element seek of renderer.
691 // Instead behave as if the renderer has asked us to seek.
692 player_
.SeekTo(base::TimeDelta());
693 EXPECT_EQ(1, demuxer_
->num_seek_requests());
696 EXPECT_FALSE(GetMediaDecoderJob(false));
697 EXPECT_EQ(0, demuxer_
->num_data_requests());
699 // Sending back the seek done notification.
700 player_
.OnDemuxerSeekDone(kNoTimestamp());
701 EXPECT_TRUE(GetMediaDecoderJob(false));
702 EXPECT_EQ(1, demuxer_
->num_data_requests());
704 // Reconfirm exactly 1 seek request has been made of demuxer.
705 EXPECT_EQ(1, demuxer_
->num_seek_requests());
708 TEST_F(MediaSourcePlayerTest
, StartImmediatelyAfterPause
) {
709 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
711 // Test that if the decoding job is not fully stopped after Pause(),
712 // calling Start() will be a noop.
713 StartAudioDecoderJob();
715 MediaDecoderJob
* decoder_job
= GetMediaDecoderJob(true);
716 EXPECT_TRUE(decoder_job
);
717 EXPECT_EQ(1, demuxer_
->num_data_requests());
718 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
720 // Sending data to player.
721 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
722 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
724 // Decoder job will not immediately stop after Pause() since it is
725 // running on another thread.
727 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
729 // Nothing happens when calling Start() again.
731 // Verify that Start() will not destroy and recreate the decoder job.
732 EXPECT_EQ(decoder_job
, GetMediaDecoderJob(true));
733 EXPECT_EQ(1, demuxer_
->num_data_requests());
734 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
736 // The decoder job should finish and a new request will be sent.
737 EXPECT_EQ(2, demuxer_
->num_data_requests());
738 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
741 TEST_F(MediaSourcePlayerTest
, DecoderJobsCannotStartWithoutAudio
) {
742 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
744 // Test that when Start() is called, video decoder jobs will wait for audio
745 // decoder job before start decoding the data.
746 DemuxerConfigs configs
= CreateAudioVideoDemuxerConfigs();
748 EXPECT_EQ(0, demuxer_
->num_data_requests());
750 CreateNextTextureAndSetVideoSurface();
752 // Player should not seek the demuxer on setting initial surface.
753 EXPECT_EQ(0, demuxer_
->num_seek_requests());
755 MediaDecoderJob
* audio_decoder_job
= GetMediaDecoderJob(true);
756 MediaDecoderJob
* video_decoder_job
= GetMediaDecoderJob(false);
757 EXPECT_EQ(2, demuxer_
->num_data_requests());
758 EXPECT_FALSE(audio_decoder_job
->is_decoding());
759 EXPECT_FALSE(video_decoder_job
->is_decoding());
761 // Sending video data to player, audio decoder should not start.
762 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
763 EXPECT_FALSE(video_decoder_job
->is_decoding());
765 // Sending audio data to player, both decoders should start now.
766 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
767 EXPECT_TRUE(audio_decoder_job
->is_decoding());
768 EXPECT_TRUE(video_decoder_job
->is_decoding());
770 // Reconfirm no seek occurred.
771 EXPECT_EQ(0, demuxer_
->num_seek_requests());
774 TEST_F(MediaSourcePlayerTest
, StartTimeTicksResetAfterDecoderUnderruns
) {
775 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
777 // Test start time ticks will reset after decoder job underruns.
778 StartAudioDecoderJob();
779 EXPECT_TRUE(GetMediaDecoderJob(true));
780 EXPECT_EQ(1, demuxer_
->num_data_requests());
781 // For the first couple chunks, the decoder job may return
782 // DECODE_FORMAT_CHANGED status instead of DECODE_SUCCEEDED status. Decode
783 // more frames to guarantee that DECODE_SUCCEEDED will be returned.
784 for (int i
= 0; i
< 4; ++i
) {
785 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i
));
786 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
790 // The decoder job should finish and a new request will be sent.
791 EXPECT_EQ(5, demuxer_
->num_data_requests());
792 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
793 base::TimeTicks previous
= StartTimeTicks();
795 // Let the decoder timeout and execute the OnDecoderStarved() callback.
796 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
798 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
799 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
800 message_loop_
.RunUntilIdle();
802 // Send new data to the decoder so it can finish the currently
804 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
805 while (GetMediaDecoderJob(true)->is_decoding())
806 message_loop_
.RunUntilIdle();
808 // Verify the start time ticks is cleared at this point because the
809 // player is prefetching.
810 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks());
812 // Send new data to the decoder so it can finish prefetching. This should
813 // reset the start time ticks.
814 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
815 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
817 base::TimeTicks current
= StartTimeTicks();
818 EXPECT_LE(100.0, (current
- previous
).InMillisecondsF());
821 TEST_F(MediaSourcePlayerTest
, NoRequestForDataAfterInputEOS
) {
822 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
824 // Test MediaSourcePlayer will not request for new data after input EOS is
826 CreateNextTextureAndSetVideoSurface();
827 StartVideoDecoderJob();
828 // Player should not seek the demuxer on setting initial surface.
829 EXPECT_EQ(0, demuxer_
->num_seek_requests());
831 EXPECT_EQ(1, demuxer_
->num_data_requests());
832 // Send the first input chunk.
833 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
835 EXPECT_EQ(2, demuxer_
->num_data_requests());
838 player_
.OnDemuxerDataAvailable(CreateEOSAck(false));
840 // No more request for data should be made.
841 EXPECT_EQ(2, demuxer_
->num_data_requests());
843 // Reconfirm no seek request has occurred.
844 EXPECT_EQ(0, demuxer_
->num_seek_requests());
847 TEST_F(MediaSourcePlayerTest
, ReplayAfterInputEOS
) {
848 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
850 // Test MediaSourcePlayer can replay after input EOS is
852 CreateNextTextureAndSetVideoSurface();
853 StartVideoDecoderJob();
855 // Player should not seek the demuxer on setting initial surface.
856 EXPECT_EQ(0, demuxer_
->num_seek_requests());
858 EXPECT_EQ(1, demuxer_
->num_data_requests());
859 // Send the first input chunk.
860 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
862 EXPECT_EQ(2, demuxer_
->num_data_requests());
865 player_
.OnDemuxerDataAvailable(CreateEOSAck(false));
867 // No more request for data should be made.
868 EXPECT_EQ(2, demuxer_
->num_data_requests());
870 // Initiate a seek. Skip requesting element seek of renderer.
871 // Instead behave as if the renderer has asked us to seek.
872 player_
.SeekTo(base::TimeDelta());
873 StartVideoDecoderJob();
874 EXPECT_EQ(1, demuxer_
->num_seek_requests());
875 player_
.OnDemuxerSeekDone(kNoTimestamp());
876 // Seek/Play after EOS should request more data.
877 EXPECT_EQ(3, demuxer_
->num_data_requests());
879 // Reconfirm only 1 seek request has occurred.
880 EXPECT_EQ(1, demuxer_
->num_seek_requests());
883 TEST_F(MediaSourcePlayerTest
, NoRequestForDataAfterAbort
) {
884 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
886 // Test that the decoder will not request new data after receiving an aborted
888 StartAudioDecoderJob();
889 EXPECT_EQ(1, demuxer_
->num_data_requests());
891 // Send an aborted access unit.
892 player_
.OnDemuxerDataAvailable(CreateAbortedAck(true));
894 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
895 // Wait for the decoder job to finish decoding.
896 while (GetMediaDecoderJob(true)->is_decoding())
897 message_loop_
.RunUntilIdle();
899 // No request will be sent for new data.
900 EXPECT_EQ(1, demuxer_
->num_data_requests());
902 // No seek requests should have occurred.
903 EXPECT_EQ(0, demuxer_
->num_seek_requests());
906 TEST_F(MediaSourcePlayerTest
, DemuxerDataArrivesAfterRelease
) {
907 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
909 // Test that the decoder should not crash if demuxer data arrives after
911 StartAudioDecoderJob();
912 EXPECT_EQ(1, demuxer_
->num_data_requests());
913 EXPECT_TRUE(GetMediaDecoderJob(true));
916 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
918 // The decoder job should have been released.
919 EXPECT_FALSE(player_
.IsPlaying());
920 EXPECT_EQ(1, demuxer_
->num_data_requests());
922 // No seek requests should have occurred.
923 EXPECT_EQ(0, demuxer_
->num_seek_requests());
926 TEST_F(MediaSourcePlayerTest
, BrowserSeek_RegularSeekPendsBrowserSeekDone
) {
927 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
929 // Test that a browser seek, once started, delays a newly arrived regular
930 // SeekTo() request's demuxer seek until the browser seek is done.
931 BrowserSeekPlayer(false);
932 EXPECT_EQ(1, demuxer_
->num_data_requests());
934 // Simulate renderer requesting a regular seek while browser seek in progress.
935 player_
.SeekTo(base::TimeDelta());
936 EXPECT_FALSE(GetMediaDecoderJob(false));
938 // Simulate browser seek is done. Confirm player requests the regular seek,
939 // still has no video decoder job configured, and has not requested any
940 // further data since the surface change event became pending in
941 // BrowserSeekPlayer().
942 EXPECT_EQ(1, demuxer_
->num_seek_requests());
943 player_
.OnDemuxerSeekDone(base::TimeDelta());
944 EXPECT_FALSE(GetMediaDecoderJob(false));
945 EXPECT_EQ(2, demuxer_
->num_seek_requests());
946 EXPECT_EQ(1, demuxer_
->num_browser_seek_requests());
947 EXPECT_EQ(1, demuxer_
->num_data_requests());
949 // Simulate regular seek is done and confirm player requests more data for
950 // new video decoder job.
951 player_
.OnDemuxerSeekDone(kNoTimestamp());
952 EXPECT_TRUE(GetMediaDecoderJob(false));
953 EXPECT_EQ(2, demuxer_
->num_data_requests());
954 EXPECT_EQ(2, demuxer_
->num_seek_requests());
957 TEST_F(MediaSourcePlayerTest
, NoSeekForInitialReleaseAndStart
) {
958 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
960 // Test that no seek is requested if player Release() + Start() occurs prior
961 // to receiving any data.
962 CreateNextTextureAndSetVideoSurface();
963 StartVideoDecoderJob();
964 EXPECT_EQ(1, demuxer_
->num_data_requests());
965 EXPECT_TRUE(GetMediaDecoderJob(false));
968 EXPECT_FALSE(player_
.IsPlaying());
970 // Pass a new non-empty surface.
971 CreateNextTextureAndSetVideoSurface();
975 // TODO(wolenetz/qinmin): Multiple in-flight data requests for same stream
976 // should be prevented. See http://crbug.com/306314.
977 EXPECT_EQ(2, demuxer_
->num_data_requests());
979 EXPECT_EQ(0, demuxer_
->num_seek_requests());
980 EXPECT_TRUE(GetMediaDecoderJob(false));
983 TEST_F(MediaSourcePlayerTest
, BrowserSeek_MidStreamReleaseAndStart
) {
984 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
986 // Test that one browser seek is requested if player Release() + Start(), with
987 // video data received between Release() and Start().
988 BrowserSeekPlayer(true);
989 EXPECT_FALSE(GetMediaDecoderJob(false));
990 EXPECT_EQ(1, demuxer_
->num_data_requests());
992 // Simulate browser seek is done and confirm player requests more data.
993 player_
.OnDemuxerSeekDone(base::TimeDelta());
994 EXPECT_TRUE(GetMediaDecoderJob(false));
995 EXPECT_EQ(2, demuxer_
->num_data_requests());
996 EXPECT_EQ(1, demuxer_
->num_seek_requests());
999 TEST_F(MediaSourcePlayerTest
, PrerollAudioAfterSeek
) {
1000 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1002 // Test decoder job will preroll the media to the seek position.
1003 StartAudioDecoderJob();
1004 EXPECT_TRUE(GetMediaDecoderJob(true));
1005 EXPECT_EQ(1, demuxer_
->num_data_requests());
1007 SeekPlayer(true, base::TimeDelta::FromMilliseconds(100));
1008 EXPECT_TRUE(IsPrerolling(true));
1009 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1011 // Send some data before the seek position.
1012 for (int i
= 1; i
< 4; ++i
) {
1013 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i
));
1014 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1015 message_loop_
.Run();
1017 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1018 EXPECT_TRUE(IsPrerolling(true));
1020 // Send data after the seek position.
1021 DemuxerData data
= CreateReadFromDemuxerAckForAudio(3);
1022 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(100);
1023 player_
.OnDemuxerDataAvailable(data
);
1024 message_loop_
.Run();
1025 EXPECT_LT(100.0, player_
.GetCurrentTime().InMillisecondsF());
1026 EXPECT_FALSE(IsPrerolling(true));
1029 TEST_F(MediaSourcePlayerTest
, PrerollVideoAfterSeek
) {
1030 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1032 // Test decoder job will preroll the media to the seek position.
1033 CreateNextTextureAndSetVideoSurface();
1034 StartVideoDecoderJob();
1035 EXPECT_TRUE(GetMediaDecoderJob(false));
1036 EXPECT_EQ(1, demuxer_
->num_data_requests());
1038 SeekPlayer(false, base::TimeDelta::FromMilliseconds(100));
1039 EXPECT_TRUE(IsPrerolling(false));
1040 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1042 // Send some data before the seek position.
1044 for (int i
= 1; i
< 4; ++i
) {
1045 data
= CreateReadFromDemuxerAckForVideo();
1046 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(i
* 30);
1047 player_
.OnDemuxerDataAvailable(data
);
1048 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1049 message_loop_
.Run();
1051 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1052 EXPECT_TRUE(IsPrerolling(false));
1054 // Send data at the seek position.
1055 data
= CreateReadFromDemuxerAckForVideo();
1056 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(100);
1057 player_
.OnDemuxerDataAvailable(data
);
1058 message_loop_
.Run();
1060 // TODO(wolenetz/qinmin): Player's maintenance of current time for video-only
1061 // streams depends on decoder output, which may be initially inaccurate, and
1062 // encoded video test data may also need updating. Verify at least that AU
1063 // timestamp-based preroll logic has determined video preroll has completed.
1064 EXPECT_FALSE(IsPrerolling(false));
1067 TEST_F(MediaSourcePlayerTest
, SeekingAfterCompletingPrerollRestartsPreroll
) {
1068 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1070 // Test decoder job will begin prerolling upon seek, when it was not
1071 // prerolling prior to the seek.
1072 StartAudioDecoderJob();
1073 MediaDecoderJob
* decoder_job
= GetMediaDecoderJob(true);
1074 EXPECT_TRUE(decoder_job
);
1075 EXPECT_EQ(1, demuxer_
->num_data_requests());
1076 EXPECT_TRUE(IsPrerolling(true));
1078 // Complete the initial preroll by feeding data to the decoder.
1079 for (int i
= 0; i
< 4; ++i
) {
1080 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i
));
1081 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1082 message_loop_
.Run();
1084 EXPECT_LT(0.0, player_
.GetCurrentTime().InMillisecondsF());
1085 EXPECT_FALSE(IsPrerolling(true));
1087 SeekPlayer(true, base::TimeDelta::FromMilliseconds(500));
1089 // Prerolling should have begun again.
1090 EXPECT_TRUE(IsPrerolling(true));
1091 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF());
1093 // Send data at and after the seek position. Prerolling should complete.
1094 for (int i
= 0; i
< 4; ++i
) {
1095 DemuxerData data
= CreateReadFromDemuxerAckForAudio(i
);
1096 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(
1097 500 + 30 * (i
- 1));
1098 player_
.OnDemuxerDataAvailable(data
);
1099 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1100 message_loop_
.Run();
1102 EXPECT_LT(500.0, player_
.GetCurrentTime().InMillisecondsF());
1103 EXPECT_FALSE(IsPrerolling(true));
1105 // Throughout this test, we should have not re-created the decoder job, so
1106 // IsPrerolling() transition from false to true was not due to constructor
1107 // initialization. It was due to BeginPrerolling().
1108 EXPECT_EQ(decoder_job
, GetMediaDecoderJob(true));
1111 TEST_F(MediaSourcePlayerTest
, PrerollContinuesAcrossReleaseAndStart
) {
1112 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1114 // Test decoder job will resume media prerolling if interrupted by Release()
1116 StartAudioDecoderJob();
1117 EXPECT_TRUE(GetMediaDecoderJob(true));
1118 EXPECT_EQ(1, demuxer_
->num_data_requests());
1120 SeekPlayer(true, base::TimeDelta::FromMilliseconds(100));
1121 EXPECT_TRUE(IsPrerolling(true));
1122 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1124 // Send some data before the seek position.
1125 // Test uses 'large' number of iterations because decoder job may not get
1126 // MEDIA_CODEC_OK output status until after a few dequeue output attempts.
1127 // This allows decoder status to stabilize prior to AU timestamp reaching
1128 // the preroll target.
1130 for (int i
= 0; i
< 10; ++i
) {
1131 data
= CreateReadFromDemuxerAckForAudio(3);
1132 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(i
* 10);
1134 // While still prerolling, Release() and Start() the player.
1135 // TODO(qinmin): Simulation of multiple in-flight data requests (one from
1136 // before Release(), one from after Start()) is not included here, and
1137 // neither is any data enqueued for later decode if it arrives after
1138 // Release() and before Start(). See http://crbug.com/306314. Assumption
1139 // for this test, to prevent flakiness until the bug is fixed, is the
1140 // first request's data arrives before Start(). Though that data is not
1141 // seen by decoder, this assumption allows preroll continuation
1142 // verification and prevents multiple in-flight data requests.
1144 player_
.OnDemuxerDataAvailable(data
);
1145 message_loop_
.RunUntilIdle();
1146 EXPECT_FALSE(GetMediaDecoderJob(true));
1147 StartAudioDecoderJob();
1148 EXPECT_TRUE(GetMediaDecoderJob(true));
1150 player_
.OnDemuxerDataAvailable(data
);
1151 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1152 message_loop_
.Run();
1154 EXPECT_TRUE(IsPrerolling(true));
1156 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1157 EXPECT_TRUE(IsPrerolling(true));
1159 // Send data after the seek position.
1160 data
= CreateReadFromDemuxerAckForAudio(3);
1161 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(100);
1162 player_
.OnDemuxerDataAvailable(data
);
1163 message_loop_
.Run();
1164 EXPECT_LT(100.0, player_
.GetCurrentTime().InMillisecondsF());
1165 EXPECT_FALSE(IsPrerolling(true));
1168 TEST_F(MediaSourcePlayerTest
, PrerollContinuesAcrossConfigChange
) {
1169 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1171 // Test decoder job will resume media prerolling if interrupted by
1172 // |kConfigChanged| and OnDemuxerConfigsAvailable().
1173 StartAudioDecoderJob();
1174 EXPECT_TRUE(GetMediaDecoderJob(true));
1175 EXPECT_EQ(1, demuxer_
->num_data_requests());
1177 SeekPlayer(true, base::TimeDelta::FromMilliseconds(100));
1178 EXPECT_TRUE(IsPrerolling(true));
1179 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1181 // In response to data request, simulate that demuxer signals config change by
1182 // sending an AU with |kConfigChanged|. Player should prepare to reconfigure
1183 // the audio decoder job, and should request new demuxer configs.
1184 DemuxerData data
= CreateReadFromDemuxerAckWithConfigChanged(true, 0);
1185 EXPECT_EQ(0, demuxer_
->num_config_requests());
1186 player_
.OnDemuxerDataAvailable(data
);
1187 EXPECT_EQ(1, demuxer_
->num_config_requests());
1189 // Simulate arrival of new configs.
1190 player_
.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs());
1192 // Send some data before the seek position.
1193 for (int i
= 1; i
< 4; ++i
) {
1194 player_
.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i
));
1195 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1196 message_loop_
.Run();
1198 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1199 EXPECT_TRUE(IsPrerolling(true));
1201 // Send data after the seek position.
1202 data
= CreateReadFromDemuxerAckForAudio(3);
1203 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(100);
1204 player_
.OnDemuxerDataAvailable(data
);
1205 message_loop_
.Run();
1206 EXPECT_LT(100.0, player_
.GetCurrentTime().InMillisecondsF());
1207 EXPECT_FALSE(IsPrerolling(true));
1210 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInPrefetchUnit0
) {
1211 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1213 // Test that the player detects need for and requests demuxer configs if
1214 // the |kConfigChanged| unit is the very first unit in the set of units
1215 // received in OnDemuxerDataAvailable() ostensibly while
1216 // |PREFETCH_DONE_EVENT_PENDING|.
1217 StartConfigChange(true, true, 0);
1220 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInPrefetchUnit1
) {
1221 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1223 // Test that the player detects need for and requests demuxer configs if
1224 // the |kConfigChanged| unit is not the first unit in the set of units
1225 // received in OnDemuxerDataAvailable() ostensibly while
1226 // |PREFETCH_DONE_EVENT_PENDING|.
1227 StartConfigChange(true, true, 1);
1230 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInUnit0AfterPrefetch
) {
1231 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1233 // Test that the player detects need for and requests demuxer configs if
1234 // the |kConfigChanged| unit is the very first unit in the set of units
1235 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1237 StartConfigChange(true, false, 0);
1240 TEST_F(MediaSourcePlayerTest
, DemuxerConfigRequestedIfInUnit1AfterPrefetch
) {
1241 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1243 // Test that the player detects need for and requests demuxer configs if
1244 // the |kConfigChanged| unit is not the first unit in the set of units
1245 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1247 StartConfigChange(true, false, 1);
1250 TEST_F(MediaSourcePlayerTest
, BrowserSeek_PrerollAfterBrowserSeek
) {
1251 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1253 // Test decoder job will preroll the media to the actual seek position
1254 // resulting from a browser seek.
1255 BrowserSeekPlayer(false);
1257 // Simulate browser seek is done, but to a later time than was requested.
1258 EXPECT_LT(player_
.GetCurrentTime().InMillisecondsF(), 100);
1259 player_
.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100));
1260 EXPECT_TRUE(GetMediaDecoderJob(false));
1261 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1262 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1263 EXPECT_EQ(2, demuxer_
->num_data_requests());
1265 // Send some data with access unit timestamps before the actual browser seek
1266 // position. This is a bit unrealistic in this case where the browser seek
1267 // jumped forward and next data from demuxer would normally begin at this
1268 // browser seek position, immediately completing preroll. For simplicity and
1269 // coverage, this test simulates the more common condition that AUs received
1270 // after browser seek begin with timestamps before the seek target, and don't
1271 // immediately complete preroll.
1273 for (int i
= 1; i
< 4; ++i
) {
1274 data
= CreateReadFromDemuxerAckForVideo();
1275 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(i
* 30);
1276 player_
.OnDemuxerDataAvailable(data
);
1277 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1278 message_loop_
.Run();
1279 EXPECT_TRUE(IsPrerolling(false));
1282 EXPECT_EQ(100.0, player_
.GetCurrentTime().InMillisecondsF());
1284 // Send data after the browser seek position.
1285 data
= CreateReadFromDemuxerAckForVideo();
1286 data
.access_units
[0].timestamp
= base::TimeDelta::FromMilliseconds(120);
1287 player_
.OnDemuxerDataAvailable(data
);
1288 message_loop_
.Run();
1289 EXPECT_FALSE(IsPrerolling(false));
1292 TEST_F(MediaSourcePlayerTest
, VideoDemuxerConfigChange
) {
1293 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1295 // Test that video config change notification results in request for demuxer
1296 // configuration, and that a video decoder job results without any browser
1297 // seek necessary once the new demuxer config arrives.
1298 StartConfigChange(false, true, 1);
1299 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
1300 EXPECT_TRUE(first_job
);
1301 EXPECT_EQ(1, demuxer_
->num_data_requests());
1302 EXPECT_EQ(1, demuxer_
->num_config_requests());
1304 // Simulate arrival of new configs.
1305 player_
.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1307 // New video decoder job should have been created and configured, without any
1309 MediaDecoderJob
* second_job
= GetMediaDecoderJob(false);
1310 EXPECT_TRUE(second_job
);
1311 EXPECT_NE(first_job
, second_job
);
1312 EXPECT_EQ(2, demuxer_
->num_data_requests());
1313 EXPECT_EQ(1, demuxer_
->num_config_requests());
1314 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1317 TEST_F(MediaSourcePlayerTest
, VideoConfigChangeContinuesAcrossSeek
) {
1318 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1320 // Test if a demuxer config request is pending (due to previously receiving
1321 // |kConfigChanged|), and a seek request arrives prior to demuxer configs,
1322 // then seek is processed first, followed by the decoder config change.
1323 // This assumes the demuxer sends |kConfigChanged| read response prior to
1324 // canceling any reads pending seek; no |kAborted| is involved in this test.
1325 StartConfigChange(false, false, 1);
1326 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
1327 EXPECT_TRUE(first_job
);
1328 EXPECT_EQ(1, demuxer_
->num_config_requests());
1329 EXPECT_EQ(2, demuxer_
->num_data_requests());
1330 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1332 player_
.SeekTo(base::TimeDelta::FromMilliseconds(100));
1334 // Verify that the seek is requested immediately.
1335 EXPECT_EQ(1, demuxer_
->num_seek_requests());
1337 // Simulate unlikely delayed arrival of the demuxer configs, completing the
1339 // TODO(wolenetz): Is it even possible for requested demuxer configs to be
1340 // delayed until after a SeekTo request arrives?
1341 player_
.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1343 MediaDecoderJob
* second_job
= GetMediaDecoderJob(false);
1344 EXPECT_NE(first_job
, second_job
);
1345 EXPECT_TRUE(second_job
);
1347 // Send back the seek done notification. This should finish the seek and
1348 // trigger the player to request more data.
1349 EXPECT_EQ(2, demuxer_
->num_data_requests());
1350 player_
.OnDemuxerSeekDone(kNoTimestamp());
1351 EXPECT_EQ(3, demuxer_
->num_data_requests());
1354 TEST_F(MediaSourcePlayerTest
, NewSurfaceWhileChangingConfigs
) {
1355 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1357 // Test that no seek or duplicated demuxer config request results from a
1358 // SetVideoSurface() that occurs while the player is expecting new demuxer
1359 // configs. This test may be good to keep beyond browser seek hack.
1360 StartConfigChange(false, false, 1);
1361 MediaDecoderJob
* first_job
= GetMediaDecoderJob(false);
1362 EXPECT_TRUE(first_job
);
1363 EXPECT_EQ(1, demuxer_
->num_config_requests());
1364 EXPECT_EQ(2, demuxer_
->num_data_requests());
1366 CreateNextTextureAndSetVideoSurface();
1368 // Surface change processing (including decoder job re-creation) should
1369 // not occur until the pending video config change is completed.
1370 EXPECT_EQ(first_job
, GetMediaDecoderJob(false));
1372 player_
.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1373 MediaDecoderJob
* second_job
= GetMediaDecoderJob(false);
1374 EXPECT_NE(first_job
, second_job
);
1375 EXPECT_TRUE(second_job
);
1377 EXPECT_EQ(3, demuxer_
->num_data_requests());
1378 EXPECT_EQ(1, demuxer_
->num_config_requests());
1379 EXPECT_EQ(0, demuxer_
->num_seek_requests());
1382 // TODO(xhwang): Enable this test when the test devices are updated.
1383 TEST_F(MediaSourcePlayerTest
, DISABLED_IsTypeSupported_Widevine
) {
1384 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
1385 LOG(INFO
) << "Could not run test - not supported on device.";
1389 uint8 kWidevineUUID
[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,
1390 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED };
1392 std::vector
<uint8
> widevine_uuid(kWidevineUUID
,
1393 kWidevineUUID
+ arraysize(kWidevineUUID
));
1395 // We test "L3" fully. But for "L1" we don't check the result as it depend on
1396 // whether the test device supports "L1" decoding.
1398 std::vector
<std::string
> codec_avc(1, "avc1");
1399 std::vector
<std::string
> codec_aac(1, "mp4a");
1400 std::vector
<std::string
> codec_avc_aac(1, "avc1");
1401 codec_avc_aac
.push_back("mp4a");
1403 EXPECT_TRUE(IsTypeSupported(widevine_uuid
, "L3", kVideoMp4
, codec_avc
));
1404 IsTypeSupported(widevine_uuid
, "L1", kVideoMp4
, codec_avc
);
1406 // TODO(xhwang): L1/L3 doesn't apply to audio, so the result is messy.
1407 // Clean this up after we have a solution to specifying decoding mode.
1408 EXPECT_TRUE(IsTypeSupported(widevine_uuid
, "L3", kAudioMp4
, codec_aac
));
1409 IsTypeSupported(widevine_uuid
, "L1", kAudioMp4
, codec_aac
);
1411 EXPECT_TRUE(IsTypeSupported(widevine_uuid
, "L3", kVideoMp4
, codec_avc_aac
));
1412 IsTypeSupported(widevine_uuid
, "L1", kVideoMp4
, codec_avc_aac
);
1414 std::vector
<std::string
> codec_vp8(1, "vp8");
1415 std::vector
<std::string
> codec_vorbis(1, "vorbis");
1416 std::vector
<std::string
> codec_vp8_vorbis(1, "vp8");
1417 codec_vp8_vorbis
.push_back("vorbis");
1419 // TODO(xhwang): WebM is actually not supported but currently
1420 // MediaDrmBridge.isCryptoSchemeSupported() doesn't check the container type.
1421 // Fix isCryptoSchemeSupported() and update this test as necessary.
1422 EXPECT_TRUE(IsTypeSupported(widevine_uuid
, "L3", kVideoWebM
, codec_vp8
));
1423 IsTypeSupported(widevine_uuid
, "L1", kVideoWebM
, codec_vp8
);
1425 // TODO(xhwang): L1/L3 doesn't apply to audio, so the result is messy.
1426 // Clean this up after we have a solution to specifying decoding mode.
1427 EXPECT_TRUE(IsTypeSupported(widevine_uuid
, "L3", kAudioWebM
, codec_vorbis
));
1428 IsTypeSupported(widevine_uuid
, "L1", kAudioWebM
, codec_vorbis
);
1431 IsTypeSupported(widevine_uuid
, "L3", kVideoWebM
, codec_vp8_vorbis
));
1432 IsTypeSupported(widevine_uuid
, "L1", kVideoWebM
, codec_vp8_vorbis
);
1435 TEST_F(MediaSourcePlayerTest
, IsTypeSupported_InvalidUUID
) {
1436 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
1437 LOG(INFO
) << "Could not run test - not supported on device.";
1441 uint8 kInvalidUUID
[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
1442 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
1444 std::vector
<uint8
> invalid_uuid(kInvalidUUID
,
1445 kInvalidUUID
+ arraysize(kInvalidUUID
));
1447 std::vector
<std::string
> codec_avc(1, "avc1");
1448 EXPECT_FALSE(IsTypeSupported(invalid_uuid
, "L3", kVideoMp4
, codec_avc
));
1449 EXPECT_FALSE(IsTypeSupported(invalid_uuid
, "L1", kVideoMp4
, codec_avc
));
1452 // TODO(xhwang): Are these IsTypeSupported tests device specific?
1453 // TODO(xhwang): Add more IsTypeSupported tests.
1455 } // namespace media