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.
4
5 #include <string>
6
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/bind_to_loop.h"
15 #include "media/base/decoder_buffer.h"
16 #include "media/base/test_data_util.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "ui/gl/android/surface_texture.h"
19
20 namespace media {
21
22 // Helper macro to skip the test if MediaCodecBridge isn't available.
23 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
24 do { \
25 if (!MediaCodecBridge::IsAvailable()) { \
26 VLOG(0) << "Could not run test - not supported on device."; \
27 return; \
28 } \
29 } while (0)
30
31 static const int kDefaultDurationInMs = 10000;
32
33 static const char kAudioMp4[] = "audio/mp4";
34 static const char kVideoMp4[] = "video/mp4";
35 static const char kAudioWebM[] = "audio/webm";
36 static const char kVideoWebM[] = "video/webm";
37
38 // TODO(wolenetz/qinmin): Simplify tests with more effective mock usage, and
39 // fix flaky pointer-based MDJ inequality testing. See http://crbug.com/327839.
40
41 // Mock of MediaPlayerManager for testing purpose
42 class MockMediaPlayerManager : public MediaPlayerManager {
43 public:
MockMediaPlayerManager(base::MessageLoop * message_loop)44 explicit MockMediaPlayerManager(base::MessageLoop* message_loop)
45 : message_loop_(message_loop),
46 playback_completed_(false) {}
~MockMediaPlayerManager()47 virtual ~MockMediaPlayerManager() {}
48
49 // MediaPlayerManager implementation.
RequestMediaResources(int player_id)50 virtual void RequestMediaResources(int player_id) OVERRIDE {}
ReleaseMediaResources(int player_id)51 virtual void ReleaseMediaResources(int player_id) OVERRIDE {}
GetMediaResourceGetter()52 virtual MediaResourceGetter* GetMediaResourceGetter() OVERRIDE {
53 return NULL;
54 }
OnTimeUpdate(int player_id,base::TimeDelta current_time)55 virtual void OnTimeUpdate(int player_id,
56 base::TimeDelta current_time) OVERRIDE {}
OnMediaMetadataChanged(int player_id,base::TimeDelta duration,int width,int height,bool success)57 virtual void OnMediaMetadataChanged(
58 int player_id, base::TimeDelta duration, int width, int height,
59 bool success) OVERRIDE {}
OnPlaybackComplete(int player_id)60 virtual void OnPlaybackComplete(int player_id) OVERRIDE {
61 playback_completed_ = true;
62 if (message_loop_->is_running())
63 message_loop_->Quit();
64 }
OnMediaInterrupted(int player_id)65 virtual void OnMediaInterrupted(int player_id) OVERRIDE {}
OnBufferingUpdate(int player_id,int percentage)66 virtual void OnBufferingUpdate(int player_id, int percentage) OVERRIDE {}
OnSeekComplete(int player_id,const base::TimeDelta & current_time)67 virtual void OnSeekComplete(int player_id,
68 const base::TimeDelta& current_time) OVERRIDE {}
OnError(int player_id,int error)69 virtual void OnError(int player_id, int error) OVERRIDE {}
OnVideoSizeChanged(int player_id,int width,int height)70 virtual void OnVideoSizeChanged(int player_id, int width,
71 int height) OVERRIDE {}
GetFullscreenPlayer()72 virtual MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE { return NULL; }
GetPlayer(int player_id)73 virtual MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE { return NULL; }
DestroyAllMediaPlayers()74 virtual void DestroyAllMediaPlayers() OVERRIDE {}
GetDrmBridge(int media_keys_id)75 virtual MediaDrmBridge* GetDrmBridge(int media_keys_id) OVERRIDE {
76 return NULL;
77 }
OnProtectedSurfaceRequested(int player_id)78 virtual void OnProtectedSurfaceRequested(int player_id) OVERRIDE {}
OnSessionCreated(int media_keys_id,uint32 session_id,const std::string & web_session_id)79 virtual void OnSessionCreated(int media_keys_id,
80 uint32 session_id,
81 const std::string& web_session_id) OVERRIDE {}
OnSessionMessage(int media_keys_id,uint32 session_id,const std::vector<uint8> & message,const std::string & destination_url)82 virtual void OnSessionMessage(int media_keys_id,
83 uint32 session_id,
84 const std::vector<uint8>& message,
85 const std::string& destination_url) OVERRIDE {}
OnSessionReady(int media_keys_id,uint32 session_id)86 virtual void OnSessionReady(int media_keys_id, uint32 session_id) OVERRIDE {}
OnSessionClosed(int media_keys_id,uint32 session_id)87 virtual void OnSessionClosed(int media_keys_id, uint32 session_id) OVERRIDE {}
OnSessionError(int media_keys_id,uint32 session_id,media::MediaKeys::KeyError error_code,int system_code)88 virtual void OnSessionError(int media_keys_id,
89 uint32 session_id,
90 media::MediaKeys::KeyError error_code,
91 int system_code) OVERRIDE {}
92
playback_completed() const93 bool playback_completed() const {
94 return playback_completed_;
95 }
96
97 private:
98 base::MessageLoop* message_loop_;
99 bool playback_completed_;
100
101 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager);
102 };
103
104 class MockDemuxerAndroid : public DemuxerAndroid {
105 public:
MockDemuxerAndroid(base::MessageLoop * message_loop)106 explicit MockDemuxerAndroid(base::MessageLoop* message_loop)
107 : message_loop_(message_loop),
108 num_data_requests_(0),
109 num_seek_requests_(0),
110 num_browser_seek_requests_(0),
111 num_config_requests_(0) {}
~MockDemuxerAndroid()112 virtual ~MockDemuxerAndroid() {}
113
Initialize(DemuxerAndroidClient * client)114 virtual void Initialize(DemuxerAndroidClient* client) OVERRIDE {}
RequestDemuxerConfigs()115 virtual void RequestDemuxerConfigs() OVERRIDE {
116 num_config_requests_++;
117 }
RequestDemuxerData(DemuxerStream::Type type)118 virtual void RequestDemuxerData(DemuxerStream::Type type) OVERRIDE {
119 num_data_requests_++;
120 if (message_loop_->is_running())
121 message_loop_->Quit();
122 }
RequestDemuxerSeek(const base::TimeDelta & time_to_seek,bool is_browser_seek)123 virtual void RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
124 bool is_browser_seek) OVERRIDE {
125 num_seek_requests_++;
126 if (is_browser_seek)
127 num_browser_seek_requests_++;
128 }
129
num_data_requests() const130 int num_data_requests() const { return num_data_requests_; }
num_seek_requests() const131 int num_seek_requests() const { return num_seek_requests_; }
num_browser_seek_requests() const132 int num_browser_seek_requests() const { return num_browser_seek_requests_; }
num_config_requests() const133 int num_config_requests() const { return num_config_requests_; }
134
135 private:
136 base::MessageLoop* message_loop_;
137
138 // The number of encoded data requests this object has seen.
139 int num_data_requests_;
140
141 // The number of regular and browser seek requests this object has seen.
142 int num_seek_requests_;
143
144 // The number of browser seek requests this object has seen.
145 int num_browser_seek_requests_;
146
147 // The number of demuxer config requests this object has seen.
148 int num_config_requests_;
149
150 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
151 };
152
153 class MediaSourcePlayerTest : public testing::Test {
154 public:
MediaSourcePlayerTest()155 MediaSourcePlayerTest()
156 : manager_(&message_loop_),
157 demuxer_(new MockDemuxerAndroid(&message_loop_)),
158 player_(0, &manager_, scoped_ptr<DemuxerAndroid>(demuxer_)),
159 decoder_callback_hook_executed_(false),
160 surface_texture_a_is_next_(true) {}
~MediaSourcePlayerTest()161 virtual ~MediaSourcePlayerTest() {}
162
163 protected:
164 // Get the decoder job from the MediaSourcePlayer.
GetMediaDecoderJob(bool is_audio)165 MediaDecoderJob* GetMediaDecoderJob(bool is_audio) {
166 if (is_audio) {
167 return reinterpret_cast<MediaDecoderJob*>(
168 player_.audio_decoder_job_.get());
169 }
170 return reinterpret_cast<MediaDecoderJob*>(
171 player_.video_decoder_job_.get());
172 }
173
174 // Get the per-job prerolling status from the MediaSourcePlayer's job matching
175 // |is_audio|. Caller must guard against NPE if the player's job is NULL.
IsPrerolling(bool is_audio)176 bool IsPrerolling(bool is_audio) {
177 return GetMediaDecoderJob(is_audio)->prerolling();
178 }
179
180 // Get the preroll timestamp from the MediaSourcePlayer.
GetPrerollTimestamp()181 base::TimeDelta GetPrerollTimestamp() {
182 return player_.preroll_timestamp_;
183 }
184
185 // Simulate player has reached starvation timeout.
TriggerPlayerStarvation()186 void TriggerPlayerStarvation() {
187 player_.decoder_starvation_callback_.Cancel();
188 player_.OnDecoderStarved();
189 }
190
191 // Release() the player.
ReleasePlayer()192 void ReleasePlayer() {
193 EXPECT_TRUE(player_.IsPlaying());
194 player_.Release();
195 EXPECT_FALSE(player_.IsPlaying());
196 EXPECT_FALSE(GetMediaDecoderJob(true));
197 EXPECT_FALSE(GetMediaDecoderJob(false));
198 }
199
200 // Upon the next successful decode callback, post a task to call Release()
201 // on the |player_|. TEST_F's do not have access to the private player
202 // members, hence this helper method.
203 // Prevent usage creep of MSP::set_decode_callback_for_testing() by
204 // only using it for the ReleaseWithOnPrefetchDoneAlreadyPosted test.
OnNextTestDecodeCallbackPostTaskToReleasePlayer()205 void OnNextTestDecodeCallbackPostTaskToReleasePlayer() {
206 player_.set_decode_callback_for_testing(media::BindToLoop(
207 message_loop_.message_loop_proxy(),
208 base::Bind(
209 &MediaSourcePlayerTest::ReleaseWithPendingPrefetchDoneVerification,
210 base::Unretained(this))));
211 }
212
213 // Asynch test callback posted upon decode completion to verify that a pending
214 // prefetch done event is cleared across |player_|'s Release(). This helps
215 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
ReleaseWithPendingPrefetchDoneVerification()216 void ReleaseWithPendingPrefetchDoneVerification() {
217 EXPECT_TRUE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
218 ReleasePlayer();
219 EXPECT_FALSE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
220 EXPECT_FALSE(decoder_callback_hook_executed_);
221 decoder_callback_hook_executed_ = true;
222 }
223
224 // Inspect internal pending_event_ state of |player_|. This is for infrequent
225 // use by tests, only where required.
IsPendingSurfaceChange()226 bool IsPendingSurfaceChange() {
227 return player_.IsEventPending(player_.SURFACE_CHANGE_EVENT_PENDING);
228 }
229
CreateAudioDemuxerConfigs(AudioCodec audio_codec)230 DemuxerConfigs CreateAudioDemuxerConfigs(AudioCodec audio_codec) {
231 DemuxerConfigs configs;
232 configs.audio_codec = audio_codec;
233 configs.audio_channels = 2;
234 configs.is_audio_encrypted = false;
235 configs.duration_ms = kDefaultDurationInMs;
236
237 if (audio_codec == kCodecVorbis) {
238 configs.audio_sampling_rate = 44100;
239 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(
240 "vorbis-extradata");
241 configs.audio_extra_data = std::vector<uint8>(
242 buffer->data(),
243 buffer->data() + buffer->data_size());
244 return configs;
245 }
246
247 // Other codecs are not yet supported by this helper.
248 EXPECT_EQ(audio_codec, kCodecAAC);
249
250 configs.audio_sampling_rate = 48000;
251 uint8 aac_extra_data[] = { 0x13, 0x10 };
252 configs.audio_extra_data = std::vector<uint8>(
253 aac_extra_data,
254 aac_extra_data + 2);
255 return configs;
256 }
257
CreateVideoDemuxerConfigs()258 DemuxerConfigs CreateVideoDemuxerConfigs() {
259 DemuxerConfigs configs;
260 configs.video_codec = kCodecVP8;
261 configs.video_size = gfx::Size(320, 240);
262 configs.is_video_encrypted = false;
263 configs.duration_ms = kDefaultDurationInMs;
264 return configs;
265 }
266
CreateAudioVideoDemuxerConfigs()267 DemuxerConfigs CreateAudioVideoDemuxerConfigs() {
268 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis);
269 configs.video_codec = kCodecVP8;
270 configs.video_size = gfx::Size(320, 240);
271 configs.is_video_encrypted = false;
272 return configs;
273 }
274
CreateDemuxerConfigs(bool have_audio,bool have_video)275 DemuxerConfigs CreateDemuxerConfigs(bool have_audio, bool have_video) {
276 DCHECK(have_audio || have_video);
277
278 if (have_audio && !have_video)
279 return CreateAudioDemuxerConfigs(kCodecVorbis);
280
281 if (have_video && !have_audio)
282 return CreateVideoDemuxerConfigs();
283
284 return CreateAudioVideoDemuxerConfigs();
285 }
286
287 // Starts an audio decoder job. Verifies player behavior relative to
288 // |expect_player_requests_data|.
StartAudioDecoderJob(bool expect_player_requests_data)289 void StartAudioDecoderJob(bool expect_player_requests_data) {
290 Start(CreateAudioDemuxerConfigs(kCodecVorbis), expect_player_requests_data);
291 }
292
293 // Starts a video decoder job. Verifies player behavior relative to
294 // |expect_player_requests_data|.
StartVideoDecoderJob(bool expect_player_requests_data)295 void StartVideoDecoderJob(bool expect_player_requests_data) {
296 Start(CreateVideoDemuxerConfigs(), expect_player_requests_data);
297 }
298
299 // Starts decoding the data. Verifies player behavior relative to
300 // |expect_player_requests_data|.
Start(const DemuxerConfigs & configs,bool expect_player_requests_data)301 void Start(const DemuxerConfigs& configs, bool expect_player_requests_data) {
302 bool has_audio = configs.audio_codec != kUnknownAudioCodec;
303 bool has_video = configs.video_codec != kUnknownVideoCodec;
304 int original_num_data_requests = demuxer_->num_data_requests();
305 int expected_request_delta = expect_player_requests_data ?
306 ((has_audio ? 1 : 0) + (has_video ? 1 : 0)) : 0;
307
308 player_.OnDemuxerConfigsAvailable(configs);
309 player_.Start();
310
311 EXPECT_TRUE(player_.IsPlaying());
312 EXPECT_EQ(original_num_data_requests + expected_request_delta,
313 demuxer_->num_data_requests());
314
315 // Verify player has decoder job iff the config included the media type for
316 // the job and the player is expected to request data due to Start(), above.
317 EXPECT_EQ(expect_player_requests_data && has_audio,
318 GetMediaDecoderJob(true) != NULL);
319 EXPECT_EQ(expect_player_requests_data && has_video,
320 GetMediaDecoderJob(false) != NULL);
321 }
322
CreateAccessUnitWithData(bool is_audio,int audio_packet_id)323 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) {
324 AccessUnit unit;
325
326 unit.status = DemuxerStream::kOk;
327 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(
328 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id)
329 : "vp8-I-frame-320x240");
330 unit.data = std::vector<uint8>(
331 buffer->data(), buffer->data() + buffer->data_size());
332
333 if (is_audio) {
334 // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
335 // NuMediaExtractor.cpp in Android source code.
336 uint8 padding[4] = { 0xff , 0xff , 0xff , 0xff };
337 unit.data.insert(unit.data.end(), padding, padding + 4);
338 }
339
340 return unit;
341 }
342
CreateReadFromDemuxerAckForAudio(int packet_id)343 DemuxerData CreateReadFromDemuxerAckForAudio(int packet_id) {
344 DemuxerData data;
345 data.type = DemuxerStream::AUDIO;
346 data.access_units.resize(1);
347 data.access_units[0] = CreateAccessUnitWithData(true, packet_id);
348 return data;
349 }
350
CreateReadFromDemuxerAckForVideo()351 DemuxerData CreateReadFromDemuxerAckForVideo() {
352 DemuxerData data;
353 data.type = DemuxerStream::VIDEO;
354 data.access_units.resize(1);
355 data.access_units[0] = CreateAccessUnitWithData(false, 0);
356 return data;
357 }
358
CreateEOSAck(bool is_audio)359 DemuxerData CreateEOSAck(bool is_audio) {
360 DemuxerData data;
361 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
362 data.access_units.resize(1);
363 data.access_units[0].status = DemuxerStream::kOk;
364 data.access_units[0].end_of_stream = true;
365 return data;
366 }
367
CreateAbortedAck(bool is_audio)368 DemuxerData CreateAbortedAck(bool is_audio) {
369 DemuxerData data;
370 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
371 data.access_units.resize(1);
372 data.access_units[0].status = DemuxerStream::kAborted;
373 return data;
374 }
375
376 // Helper method for use at test start. It starts an audio decoder job and
377 // immediately feeds it some data to decode. Then, without letting the decoder
378 // job complete a decode cycle, it also starts player SeekTo(). Upon return,
379 // the player should not yet have sent the DemuxerSeek IPC request, though
380 // seek event should be pending. The audio decoder job will also still be
381 // decoding.
StartAudioDecoderJobAndSeekToWhileDecoding(const base::TimeDelta & seek_time)382 void StartAudioDecoderJobAndSeekToWhileDecoding(
383 const base::TimeDelta& seek_time) {
384 EXPECT_FALSE(GetMediaDecoderJob(true));
385 EXPECT_FALSE(player_.IsPlaying());
386 EXPECT_EQ(0, demuxer_->num_data_requests());
387 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
388 EXPECT_EQ(player_.GetCurrentTime(), GetPrerollTimestamp());
389 StartAudioDecoderJob(true);
390 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
391 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
392 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
393 player_.SeekTo(seek_time);
394 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
395 EXPECT_EQ(0, demuxer_->num_seek_requests());
396 }
397
398 // Seek, including simulated receipt of |kAborted| read between SeekTo() and
399 // OnDemuxerSeekDone(). Use this helper method only when the player already
400 // has created the decoder job. Exactly one request for more data is expected
401 // following the seek, so use this helper for players with only audio or only
402 // video.
SeekPlayerWithAbort(bool is_audio,const base::TimeDelta & seek_time)403 void SeekPlayerWithAbort(bool is_audio, const base::TimeDelta& seek_time) {
404 int original_num_seeks = demuxer_->num_seek_requests();
405 int original_num_data_requests = demuxer_->num_data_requests();
406
407 // Initiate a seek. Skip the round-trip of requesting seek from renderer.
408 // Instead behave as if the renderer has asked us to seek.
409 player_.SeekTo(seek_time);
410
411 // Verify that the seek does not occur until previously outstanding data
412 // request is satisfied.
413 EXPECT_EQ(original_num_seeks, demuxer_->num_seek_requests());
414
415 // Simulate seeking causes the demuxer to abort the outstanding read
416 // caused by the seek.
417 player_.OnDemuxerDataAvailable(CreateAbortedAck(is_audio));
418
419 // Verify that the seek is requested.
420 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests());
421
422 // Send back the seek done notification. This should trigger the player to
423 // call OnReadFromDemuxer() again.
424 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests());
425 player_.OnDemuxerSeekDone(kNoTimestamp());
426 EXPECT_EQ(original_num_data_requests + 1, demuxer_->num_data_requests());
427
428 // No other seek should have been requested.
429 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests());
430 }
431
CreateReadFromDemuxerAckWithConfigChanged(bool is_audio,int config_unit_index)432 DemuxerData CreateReadFromDemuxerAckWithConfigChanged(bool is_audio,
433 int config_unit_index) {
434 DemuxerData data;
435 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
436 data.access_units.resize(config_unit_index + 1);
437
438 for (int i = 0; i < config_unit_index; ++i)
439 data.access_units[i] = CreateAccessUnitWithData(is_audio, i);
440
441 data.access_units[config_unit_index].status = DemuxerStream::kConfigChanged;
442 return data;
443 }
444
445 // Valid only for video-only player tests. If |trigger_with_release_start| is
446 // true, triggers the browser seek with a Release() + video data received +
447 // Start() with a new surface. If false, triggers the browser seek by
448 // setting a new video surface after beginning decode of received video data.
449 // Such data receipt causes possibility that an I-frame is not next, and
450 // browser seek results once decode completes and surface change processing
451 // begins.
BrowserSeekPlayer(bool trigger_with_release_start)452 void BrowserSeekPlayer(bool trigger_with_release_start) {
453 int expected_num_data_requests = demuxer_->num_data_requests() + 1;
454 int expected_num_seek_requests = demuxer_->num_seek_requests();
455 int expected_num_browser_seek_requests =
456 demuxer_->num_browser_seek_requests();
457
458 EXPECT_FALSE(GetMediaDecoderJob(false));
459 CreateNextTextureAndSetVideoSurface();
460 StartVideoDecoderJob(true);
461
462 if (trigger_with_release_start) {
463 ReleasePlayer();
464
465 // Simulate demuxer's response to the video data request.
466 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
467 EXPECT_FALSE(GetMediaDecoderJob(false));
468 EXPECT_FALSE(player_.IsPlaying());
469 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
470
471 CreateNextTextureAndSetVideoSurface();
472 StartVideoDecoderJob(false);
473 } else {
474 // Simulate demuxer's response to the video data request.
475 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
476
477 // While the decoder is decoding, trigger a browser seek by changing
478 // surface. Demuxer does not know of browser seek in advance, so no
479 // |kAborted| data is required (though |kAborted| can certainly occur for
480 // any pending read in reality due to renderer preparing for a regular
481 // seek).
482 CreateNextTextureAndSetVideoSurface();
483
484 // Browser seek should not begin until decoding has completed.
485 EXPECT_TRUE(GetMediaDecoderJob(false));
486 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
487
488 // Wait for the decoder job to finish decoding and be reset pending the
489 // browser seek.
490 while (GetMediaDecoderJob(false))
491 message_loop_.RunUntilIdle();
492 }
493
494 // Only one browser seek should have been initiated, and no further data
495 // should have been requested.
496 expected_num_seek_requests++;
497 expected_num_browser_seek_requests++;
498 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
499 EXPECT_EQ(expected_num_browser_seek_requests,
500 demuxer_->num_browser_seek_requests());
501 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
502 }
503
504 // Creates a new decoder job and feeds it data ending with a |kConfigChanged|
505 // access unit. If |config_unit_in_prefetch| is true, sends feeds the config
506 // change AU in response to the job's first read request (prefetch). If
507 // false, regular data is fed and decoded prior to feeding the config change
508 // AU in response to the second data request (after prefetch completed).
509 // |config_unit_index| controls which access unit is |kConfigChanged|.
StartConfigChange(bool is_audio,bool config_unit_in_prefetch,int config_unit_index)510 void StartConfigChange(bool is_audio,
511 bool config_unit_in_prefetch,
512 int config_unit_index) {
513 int expected_num_config_requests = demuxer_->num_config_requests();
514
515 EXPECT_FALSE(GetMediaDecoderJob(is_audio));
516 if (is_audio) {
517 StartAudioDecoderJob(true);
518 } else {
519 CreateNextTextureAndSetVideoSurface();
520 StartVideoDecoderJob(true);
521 }
522
523 int expected_num_data_requests = demuxer_->num_data_requests();
524
525 // Feed and decode a standalone access unit so the player exits prefetch.
526 if (!config_unit_in_prefetch) {
527 if (is_audio)
528 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
529 else
530 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
531
532 message_loop_.Run();
533
534 // We should have completed the prefetch phase at this point.
535 expected_num_data_requests++;
536 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
537 }
538
539 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests());
540
541 // Feed and decode access units with data for any units prior to
542 // |config_unit_index|, and a |kConfigChanged| unit at that index.
543 // Player should prepare to reconfigure the decoder job, and should request
544 // new demuxer configs.
545 player_.OnDemuxerDataAvailable(
546 CreateReadFromDemuxerAckWithConfigChanged(is_audio, config_unit_index));
547 WaitForDecodeDone(is_audio, !is_audio);
548
549 expected_num_config_requests++;
550 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
551 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests());
552 }
553
CreateNextTextureAndSetVideoSurface()554 void CreateNextTextureAndSetVideoSurface() {
555 gfx::SurfaceTexture* surface_texture;
556 if (surface_texture_a_is_next_) {
557 surface_texture_a_ = new gfx::SurfaceTexture(next_texture_id_++);
558 surface_texture = surface_texture_a_.get();
559 } else {
560 surface_texture_b_ = new gfx::SurfaceTexture(next_texture_id_++);
561 surface_texture = surface_texture_b_.get();
562 }
563
564 surface_texture_a_is_next_ = !surface_texture_a_is_next_;
565 gfx::ScopedJavaSurface surface = gfx::ScopedJavaSurface(surface_texture);
566 player_.SetVideoSurface(surface.Pass());
567 }
568
569 // Wait for one or both of the jobs to complete decoding. Decoder jobs are
570 // assumed to exist for any stream whose decode completion is awaited.
WaitForDecodeDone(bool wait_for_audio,bool wait_for_video)571 void WaitForDecodeDone(bool wait_for_audio, bool wait_for_video) {
572 DCHECK(wait_for_audio || wait_for_video);
573
574 while ((wait_for_audio && GetMediaDecoderJob(true) &&
575 GetMediaDecoderJob(true)->is_decoding()) ||
576 (wait_for_video && GetMediaDecoderJob(false) &&
577 GetMediaDecoderJob(false)->is_decoding())) {
578 message_loop_.RunUntilIdle();
579 }
580 }
581
WaitForAudioDecodeDone()582 void WaitForAudioDecodeDone() {
583 WaitForDecodeDone(true, false);
584 }
585
WaitForVideoDecodeDone()586 void WaitForVideoDecodeDone() {
587 WaitForDecodeDone(false, true);
588 }
589
WaitForAudioVideoDecodeDone()590 void WaitForAudioVideoDecodeDone() {
591 WaitForDecodeDone(true, true);
592 }
593
594 // If |send_eos| is true, generates EOS for the stream corresponding to
595 // |eos_for_audio|. Verifies that playback completes and no further data
596 // is requested.
597 // If |send_eos| is false, then it is assumed that caller previously arranged
598 // for player to receive EOS for each stream, but the player has not yet
599 // decoded all of them. In this case, |eos_for_audio| is ignored.
VerifyPlaybackCompletesOnEOSDecode(bool send_eos,bool eos_for_audio)600 void VerifyPlaybackCompletesOnEOSDecode(bool send_eos, bool eos_for_audio) {
601 int original_num_data_requests = demuxer_->num_data_requests();
602 if (send_eos)
603 player_.OnDemuxerDataAvailable(CreateEOSAck(eos_for_audio));
604 EXPECT_FALSE(manager_.playback_completed());
605 message_loop_.Run();
606 EXPECT_TRUE(manager_.playback_completed());
607 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests());
608 }
609
VerifyCompletedPlaybackResumesOnSeekPlusStart(bool have_audio,bool have_video)610 void VerifyCompletedPlaybackResumesOnSeekPlusStart(bool have_audio,
611 bool have_video) {
612 DCHECK(have_audio || have_video);
613
614 EXPECT_TRUE(manager_.playback_completed());
615
616 player_.SeekTo(base::TimeDelta());
617 player_.OnDemuxerSeekDone(kNoTimestamp());
618 Start(CreateDemuxerConfigs(have_audio, have_video), true);
619 }
620
621 // Starts the appropriate decoder jobs according to |have_audio| and
622 // |have_video|. Then starts seek during decode of EOS or non-EOS according to
623 // |eos_audio| and |eos_video|. Simulates seek completion and verifies that
624 // playback never completed. |eos_{audio,video}| is ignored if the
625 // corresponding |have_{audio,video}| is false.
VerifySeekDuringEOSDecodePreventsPlaybackCompletion(bool have_audio,bool have_video,bool eos_audio,bool eos_video)626 void VerifySeekDuringEOSDecodePreventsPlaybackCompletion(bool have_audio,
627 bool have_video,
628 bool eos_audio,
629 bool eos_video) {
630 DCHECK(have_audio || have_video);
631
632 if (have_video)
633 CreateNextTextureAndSetVideoSurface();
634
635 Start(CreateDemuxerConfigs(have_audio, have_video), true);
636
637 if (have_audio)
638 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
639
640 if (have_video)
641 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
642
643 // Run until more data is requested a number of times equal to the number of
644 // media types configured. Since prefetching may be in progress, we cannot
645 // reliably expect Run() to complete until we have sent demuxer data for all
646 // configured media types, above.
647 for (int i = 0; i < (have_audio ? 1 : 0) + (have_video ? 1 : 0); i++)
648 message_loop_.Run();
649
650 // Simulate seek while decoding EOS or non-EOS for the appropriate
651 // stream(s).
652 if (have_audio) {
653 if (eos_audio)
654 player_.OnDemuxerDataAvailable(CreateEOSAck(true));
655 else
656 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
657 }
658
659 if (have_video) {
660 if (eos_video)
661 player_.OnDemuxerDataAvailable(CreateEOSAck(false));
662 else
663 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
664 }
665
666 player_.SeekTo(base::TimeDelta());
667 EXPECT_EQ(0, demuxer_->num_seek_requests());
668 WaitForDecodeDone(have_audio, have_video);
669 EXPECT_EQ(1, demuxer_->num_seek_requests());
670
671 player_.OnDemuxerSeekDone(kNoTimestamp());
672 EXPECT_FALSE(manager_.playback_completed());
673 }
674
StartTimeTicks()675 base::TimeTicks StartTimeTicks() {
676 return player_.start_time_ticks_;
677 }
678
IsTypeSupported(const std::vector<uint8> & scheme_uuid,const std::string & security_level,const std::string & container,const std::vector<std::string> & codecs)679 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid,
680 const std::string& security_level,
681 const std::string& container,
682 const std::vector<std::string>& codecs) {
683 return MediaSourcePlayer::IsTypeSupported(
684 scheme_uuid, security_level, container, codecs);
685 }
686
687 base::MessageLoop message_loop_;
688 MockMediaPlayerManager manager_;
689 MockDemuxerAndroid* demuxer_; // Owned by |player_|.
690 MediaSourcePlayer player_;
691
692 // Track whether a possibly asynch decoder callback test hook has run.
693 bool decoder_callback_hook_executed_;
694
695 // We need to keep the surface texture while the decoder is actively decoding.
696 // Otherwise, it may trigger unexpected crashes on some devices. To switch
697 // surfaces, tests need to create a new surface texture without releasing
698 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
699 // between two surface textures, only replacing the N-2 texture. Assumption is
700 // that no more than N-1 texture is in use by decoder when
701 // CreateNextTextureAndSetVideoSurface() is called.
702 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
703 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
704 bool surface_texture_a_is_next_;
705 int next_texture_id_;
706
707 DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayerTest);
708 };
709
TEST_F(MediaSourcePlayerTest,StartAudioDecoderWithValidConfig)710 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithValidConfig) {
711 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
712
713 // Test audio decoder job will be created when codec is successfully started.
714 StartAudioDecoderJob(true);
715 EXPECT_EQ(0, demuxer_->num_seek_requests());
716 }
717
TEST_F(MediaSourcePlayerTest,StartAudioDecoderWithInvalidConfig)718 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithInvalidConfig) {
719 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
720
721 // Test audio decoder job will not be created when failed to start the codec.
722 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis);
723 // Replace with invalid |audio_extra_data|
724 configs.audio_extra_data.clear();
725 uint8 invalid_codec_data[] = { 0x00, 0xff, 0xff, 0xff, 0xff };
726 configs.audio_extra_data.insert(configs.audio_extra_data.begin(),
727 invalid_codec_data, invalid_codec_data + 4);
728 Start(configs, false);
729 EXPECT_EQ(0, demuxer_->num_seek_requests());
730 }
731
TEST_F(MediaSourcePlayerTest,StartVideoCodecWithValidSurface)732 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithValidSurface) {
733 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
734
735 // Test video decoder job will be created when surface is valid.
736 // Video decoder job will not be created until surface is available.
737 StartVideoDecoderJob(false);
738
739 // Set both an initial and a later video surface without receiving any
740 // demuxed data yet.
741 CreateNextTextureAndSetVideoSurface();
742 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
743 EXPECT_TRUE(first_job);
744 CreateNextTextureAndSetVideoSurface();
745
746 // Setting another surface will not create a new job until any pending
747 // read is satisfied (and job is no longer decoding).
748 EXPECT_EQ(first_job, GetMediaDecoderJob(false));
749
750 // No seeks, even on setting surface, should have occurred. (Browser seeks can
751 // occur on setting surface, but only after previously receiving video data.)
752 EXPECT_EQ(0, demuxer_->num_seek_requests());
753
754 // Note, the decoder job for the second surface set, above, will be created
755 // only after the pending read is satisfied and decoded, and the resulting
756 // browser seek is done. See BrowserSeek_* tests for this coverage.
757 }
758
TEST_F(MediaSourcePlayerTest,StartVideoCodecWithInvalidSurface)759 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithInvalidSurface) {
760 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
761
762 // Test video decoder job will not be created when surface is invalid.
763 scoped_refptr<gfx::SurfaceTexture> surface_texture(
764 new gfx::SurfaceTexture(0));
765 gfx::ScopedJavaSurface surface(surface_texture.get());
766 StartVideoDecoderJob(false);
767
768 // Release the surface texture.
769 surface_texture = NULL;
770 player_.SetVideoSurface(surface.Pass());
771
772 // Player should not seek the demuxer on setting initial surface.
773 EXPECT_EQ(0, demuxer_->num_seek_requests());
774
775 EXPECT_FALSE(GetMediaDecoderJob(false));
776 EXPECT_EQ(0, demuxer_->num_data_requests());
777 }
778
TEST_F(MediaSourcePlayerTest,ReadFromDemuxerAfterSeek)779 TEST_F(MediaSourcePlayerTest, ReadFromDemuxerAfterSeek) {
780 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
781
782 // Test decoder job will resend a ReadFromDemuxer request after seek.
783 StartAudioDecoderJob(true);
784 SeekPlayerWithAbort(true, base::TimeDelta());
785 }
786
TEST_F(MediaSourcePlayerTest,SetSurfaceWhileSeeking)787 TEST_F(MediaSourcePlayerTest, SetSurfaceWhileSeeking) {
788 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
789
790 // Test SetVideoSurface() will not cause an extra seek while the player is
791 // waiting for demuxer to indicate seek is done.
792 // Player is still waiting for SetVideoSurface(), so no request is sent.
793 StartVideoDecoderJob(false); // Verifies no data requested.
794
795 // Initiate a seek. Skip requesting element seek of renderer.
796 // Instead behave as if the renderer has asked us to seek.
797 EXPECT_EQ(0, demuxer_->num_seek_requests());
798 player_.SeekTo(base::TimeDelta());
799 EXPECT_EQ(1, demuxer_->num_seek_requests());
800
801 CreateNextTextureAndSetVideoSurface();
802 EXPECT_FALSE(GetMediaDecoderJob(false));
803 EXPECT_EQ(1, demuxer_->num_seek_requests());
804
805 // Reconfirm player has not yet requested data.
806 EXPECT_EQ(0, demuxer_->num_data_requests());
807
808 // Send the seek done notification. The player should start requesting data.
809 player_.OnDemuxerSeekDone(kNoTimestamp());
810 EXPECT_TRUE(GetMediaDecoderJob(false));
811 EXPECT_EQ(1, demuxer_->num_data_requests());
812
813 // Reconfirm exactly 1 seek request has been made of demuxer, and that it
814 // was not a browser seek request.
815 EXPECT_EQ(1, demuxer_->num_seek_requests());
816 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
817 }
818
TEST_F(MediaSourcePlayerTest,ChangeMultipleSurfaceWhileDecoding)819 TEST_F(MediaSourcePlayerTest, ChangeMultipleSurfaceWhileDecoding) {
820 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
821
822 // Test MediaSourcePlayer can switch multiple surfaces during decoding.
823 CreateNextTextureAndSetVideoSurface();
824 StartVideoDecoderJob(true);
825 EXPECT_EQ(0, demuxer_->num_seek_requests());
826
827 // Send the first input chunk.
828 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
829
830 // While the decoder is decoding, change multiple surfaces. Pass an empty
831 // surface first.
832 gfx::ScopedJavaSurface empty_surface;
833 player_.SetVideoSurface(empty_surface.Pass());
834 // Next, pass a new non-empty surface.
835 CreateNextTextureAndSetVideoSurface();
836
837 // Wait for the decoder job to finish decoding and be reset pending a browser
838 // seek.
839 while (GetMediaDecoderJob(false))
840 message_loop_.RunUntilIdle();
841
842 // Only one browser seek should have been initiated. No further data request
843 // should have been processed on |message_loop_| before surface change event
844 // became pending, above.
845 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
846 EXPECT_EQ(1, demuxer_->num_data_requests());
847
848 // Simulate browser seek is done and confirm player requests more data for new
849 // video decoder job.
850 player_.OnDemuxerSeekDone(player_.GetCurrentTime());
851 EXPECT_TRUE(GetMediaDecoderJob(false));
852 EXPECT_EQ(2, demuxer_->num_data_requests());
853 EXPECT_EQ(1, demuxer_->num_seek_requests());
854 }
855
TEST_F(MediaSourcePlayerTest,AudioOnlyStartAfterSeekFinish)856 TEST_F(MediaSourcePlayerTest, AudioOnlyStartAfterSeekFinish) {
857 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
858
859 // Test audio decoder job will not start until pending seek event is handled.
860 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis);
861 player_.OnDemuxerConfigsAvailable(configs);
862 EXPECT_FALSE(GetMediaDecoderJob(true));
863
864 // Initiate a seek. Skip requesting element seek of renderer.
865 // Instead behave as if the renderer has asked us to seek.
866 player_.SeekTo(base::TimeDelta());
867 EXPECT_EQ(1, demuxer_->num_seek_requests());
868
869 player_.Start();
870 EXPECT_FALSE(GetMediaDecoderJob(true));
871 EXPECT_EQ(0, demuxer_->num_data_requests());
872
873 // Sending back the seek done notification.
874 player_.OnDemuxerSeekDone(kNoTimestamp());
875 EXPECT_TRUE(GetMediaDecoderJob(true));
876 EXPECT_EQ(1, demuxer_->num_data_requests());
877
878 // Reconfirm exactly 1 seek request has been made of demuxer.
879 EXPECT_EQ(1, demuxer_->num_seek_requests());
880 }
881
TEST_F(MediaSourcePlayerTest,VideoOnlyStartAfterSeekFinish)882 TEST_F(MediaSourcePlayerTest, VideoOnlyStartAfterSeekFinish) {
883 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
884
885 // Test video decoder job will not start until pending seek event is handled.
886 CreateNextTextureAndSetVideoSurface();
887 DemuxerConfigs configs = CreateVideoDemuxerConfigs();
888 player_.OnDemuxerConfigsAvailable(configs);
889 EXPECT_FALSE(GetMediaDecoderJob(false));
890
891 // Initiate a seek. Skip requesting element seek of renderer.
892 // Instead behave as if the renderer has asked us to seek.
893 player_.SeekTo(base::TimeDelta());
894 EXPECT_EQ(1, demuxer_->num_seek_requests());
895
896 player_.Start();
897 EXPECT_FALSE(GetMediaDecoderJob(false));
898 EXPECT_EQ(0, demuxer_->num_data_requests());
899
900 // Sending back the seek done notification.
901 player_.OnDemuxerSeekDone(kNoTimestamp());
902 EXPECT_TRUE(GetMediaDecoderJob(false));
903 EXPECT_EQ(1, demuxer_->num_data_requests());
904
905 // Reconfirm exactly 1 seek request has been made of demuxer.
906 EXPECT_EQ(1, demuxer_->num_seek_requests());
907 }
908
TEST_F(MediaSourcePlayerTest,StartImmediatelyAfterPause)909 TEST_F(MediaSourcePlayerTest, StartImmediatelyAfterPause) {
910 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
911
912 // Test that if the decoding job is not fully stopped after Pause(),
913 // calling Start() will be a noop.
914 StartAudioDecoderJob(true);
915
916 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
917 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
918
919 // Sending data to player.
920 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
921 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
922
923 // Decoder job will not immediately stop after Pause() since it is
924 // running on another thread.
925 player_.Pause(true);
926 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
927
928 // Nothing happens when calling Start() again.
929 player_.Start();
930 // Verify that Start() will not destroy and recreate the decoder job.
931 EXPECT_EQ(decoder_job, GetMediaDecoderJob(true));
932 EXPECT_EQ(1, demuxer_->num_data_requests());
933 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
934 message_loop_.Run();
935 // The decoder job should finish and a new request will be sent.
936 EXPECT_EQ(2, demuxer_->num_data_requests());
937 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
938 }
939
TEST_F(MediaSourcePlayerTest,DecoderJobsCannotStartWithoutAudio)940 TEST_F(MediaSourcePlayerTest, DecoderJobsCannotStartWithoutAudio) {
941 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
942
943 // Test that when Start() is called, video decoder jobs will wait for audio
944 // decoder job before start decoding the data.
945 CreateNextTextureAndSetVideoSurface();
946 Start(CreateAudioVideoDemuxerConfigs(), true);
947 MediaDecoderJob* audio_decoder_job = GetMediaDecoderJob(true);
948 MediaDecoderJob* video_decoder_job = GetMediaDecoderJob(false);
949
950 EXPECT_FALSE(audio_decoder_job->is_decoding());
951 EXPECT_FALSE(video_decoder_job->is_decoding());
952
953 // Sending video data to player, video decoder should not start.
954 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
955 EXPECT_FALSE(video_decoder_job->is_decoding());
956
957 // Sending audio data to player, both decoders should start now.
958 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
959 EXPECT_TRUE(audio_decoder_job->is_decoding());
960 EXPECT_TRUE(video_decoder_job->is_decoding());
961
962 // No seeks should have occurred.
963 EXPECT_EQ(0, demuxer_->num_seek_requests());
964 }
965
TEST_F(MediaSourcePlayerTest,StartTimeTicksResetAfterDecoderUnderruns)966 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) {
967 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
968
969 // Test start time ticks will reset after decoder job underruns.
970 StartAudioDecoderJob(true);
971
972 // For the first couple chunks, the decoder job may return
973 // DECODE_FORMAT_CHANGED status instead of DECODE_SUCCEEDED status. Decode
974 // more frames to guarantee that DECODE_SUCCEEDED will be returned.
975 for (int i = 0; i < 4; ++i) {
976 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i));
977 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
978 message_loop_.Run();
979 }
980
981 // The decoder job should finish and a new request will be sent.
982 EXPECT_EQ(5, demuxer_->num_data_requests());
983 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
984 base::TimeTicks previous = StartTimeTicks();
985
986 // Let the decoder timeout and execute the OnDecoderStarved() callback.
987 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
988
989 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
990 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
991 message_loop_.RunUntilIdle();
992
993 // Send new data to the decoder so it can finish the currently
994 // pending decode.
995 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
996 WaitForAudioDecodeDone();
997
998 // Verify the start time ticks is cleared at this point because the
999 // player is prefetching.
1000 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks());
1001
1002 // Send new data to the decoder so it can finish prefetching. This should
1003 // reset the start time ticks.
1004 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1005 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
1006
1007 base::TimeTicks current = StartTimeTicks();
1008 EXPECT_LE(100.0, (current - previous).InMillisecondsF());
1009 }
1010
TEST_F(MediaSourcePlayerTest,V_SecondAccessUnitIsEOSAndResumePlayAfterSeek)1011 TEST_F(MediaSourcePlayerTest, V_SecondAccessUnitIsEOSAndResumePlayAfterSeek) {
1012 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1013
1014 // Test MediaSourcePlayer can replay video after input EOS is reached.
1015 CreateNextTextureAndSetVideoSurface();
1016 StartVideoDecoderJob(true);
1017
1018 // Send the first input chunk.
1019 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1020 message_loop_.Run();
1021
1022 VerifyPlaybackCompletesOnEOSDecode(true, false);
1023 VerifyCompletedPlaybackResumesOnSeekPlusStart(false, true);
1024 }
1025
TEST_F(MediaSourcePlayerTest,A_FirstAccessUnitIsEOSAndResumePlayAfterSeek)1026 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitIsEOSAndResumePlayAfterSeek) {
1027 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1028
1029 // Test decode of audio EOS buffer without any prior decode. See also
1030 // http://b/11696552.
1031 // Also tests that seeking+Start() after completing audio playback resumes
1032 // playback.
1033 Start(CreateAudioDemuxerConfigs(kCodecAAC), true);
1034 VerifyPlaybackCompletesOnEOSDecode(true, true);
1035 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, false);
1036 }
1037
TEST_F(MediaSourcePlayerTest,V_FirstAccessUnitAfterSeekIsEOS)1038 TEST_F(MediaSourcePlayerTest, V_FirstAccessUnitAfterSeekIsEOS) {
1039 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1040
1041 // Test decode of video EOS buffer, just after seeking, without any prior
1042 // decode (other than the simulated |kAborted| resulting from the seek
1043 // process.)
1044 CreateNextTextureAndSetVideoSurface();
1045 StartVideoDecoderJob(true);
1046 SeekPlayerWithAbort(false, base::TimeDelta());
1047 VerifyPlaybackCompletesOnEOSDecode(true, false);
1048 }
1049
TEST_F(MediaSourcePlayerTest,A_FirstAccessUnitAfterSeekIsEOS)1050 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitAfterSeekIsEOS) {
1051 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1052
1053 // Test decode of audio EOS buffer, just after seeking, without any prior
1054 // decode (other than the simulated |kAborted| resulting from the seek
1055 // process.) See also http://b/11696552.
1056 Start(CreateAudioDemuxerConfigs(kCodecAAC), true);
1057 SeekPlayerWithAbort(true, base::TimeDelta());
1058 VerifyPlaybackCompletesOnEOSDecode(true, true);
1059 }
1060
TEST_F(MediaSourcePlayerTest,AV_PlaybackCompletionAcrossConfigChange)1061 TEST_F(MediaSourcePlayerTest, AV_PlaybackCompletionAcrossConfigChange) {
1062 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1063
1064 // Test that if one stream (audio) has completed decode of EOS and the other
1065 // stream (video) processes config change, that subsequent video EOS completes
1066 // A/V playback.
1067 // Also tests that seeking+Start() after completing playback resumes playback.
1068 CreateNextTextureAndSetVideoSurface();
1069 Start(CreateAudioVideoDemuxerConfigs(), true);
1070
1071 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1072 EXPECT_EQ(0, demuxer_->num_config_requests());
1073 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1074 false, 0)); // Video |kConfigChanged| as first unit.
1075
1076 WaitForAudioVideoDecodeDone();
1077
1078 EXPECT_EQ(1, demuxer_->num_config_requests());
1079 EXPECT_EQ(2, demuxer_->num_data_requests());
1080 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1081 EXPECT_EQ(3, demuxer_->num_data_requests());
1082
1083 // At no time after completing audio EOS decode, above, should the
1084 // audio decoder job resume decoding. Send and decode video EOS.
1085 VerifyPlaybackCompletesOnEOSDecode(true, false);
1086 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1087 }
1088
TEST_F(MediaSourcePlayerTest,VA_PlaybackCompletionAcrossConfigChange)1089 TEST_F(MediaSourcePlayerTest, VA_PlaybackCompletionAcrossConfigChange) {
1090 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1091
1092 // Test that if one stream (video) has completed decode of EOS and the other
1093 // stream (audio) processes config change, that subsequent audio EOS completes
1094 // A/V playback.
1095 // Also tests that seeking+Start() after completing playback resumes playback.
1096 CreateNextTextureAndSetVideoSurface();
1097 Start(CreateAudioVideoDemuxerConfigs(), true);
1098
1099 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1100 EXPECT_EQ(0, demuxer_->num_config_requests());
1101 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1102 true, 0)); // Audio |kConfigChanged| as first unit.
1103
1104 WaitForAudioVideoDecodeDone();
1105
1106 // TODO(wolenetz/qinmin): Prevent redundant demuxer config request and change
1107 // expectation to 1 here. See http://crbug.com/325528.
1108 EXPECT_EQ(2, demuxer_->num_config_requests());
1109 EXPECT_EQ(2, demuxer_->num_data_requests());
1110 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1111 EXPECT_EQ(3, demuxer_->num_data_requests());
1112
1113 // At no time after completing video EOS decode, above, should the
1114 // video decoder job resume decoding. Send and decode audio EOS.
1115 VerifyPlaybackCompletesOnEOSDecode(true, true);
1116 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1117 }
1118
TEST_F(MediaSourcePlayerTest,AV_NoPrefetchForFinishedVideoOnAudioStarvation)1119 TEST_F(MediaSourcePlayerTest, AV_NoPrefetchForFinishedVideoOnAudioStarvation) {
1120 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1121
1122 // Test that if one stream (video) has completed decode of EOS, prefetch
1123 // resulting from player starvation occurs only for the other stream (audio),
1124 // and responding to that prefetch with EOS completes A/V playback, even if
1125 // another starvation occurs during the latter EOS's decode.
1126 CreateNextTextureAndSetVideoSurface();
1127 Start(CreateAudioVideoDemuxerConfigs(), true);
1128
1129 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1130 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1131
1132 // Wait until video EOS is processed and more data (assumed to be audio) is
1133 // requested.
1134 while (demuxer_->num_data_requests() < 3)
1135 message_loop_.RunUntilIdle();
1136 WaitForVideoDecodeDone();
1137 EXPECT_EQ(3, demuxer_->num_data_requests());
1138
1139 // Simulate decoder underrun to trigger prefetch while still decoding audio.
1140 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
1141 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding() &&
1142 !GetMediaDecoderJob(false)->is_decoding());
1143 TriggerPlayerStarvation();
1144
1145 // Complete the audio decode that was in progress when simulated player
1146 // starvation was triggered.
1147 WaitForAudioDecodeDone();
1148 EXPECT_EQ(4, demuxer_->num_data_requests());
1149
1150 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1151 EXPECT_FALSE(GetMediaDecoderJob(false)->is_decoding());
1152 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1153
1154 // Simulate another decoder underrun to trigger prefetch while decoding EOS.
1155 TriggerPlayerStarvation();
1156 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1157 }
1158
TEST_F(MediaSourcePlayerTest,V_StarvationDuringEOSDecode)1159 TEST_F(MediaSourcePlayerTest, V_StarvationDuringEOSDecode) {
1160 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1161
1162 // Test that video-only playback completes without further data requested when
1163 // starvation occurs during EOS decode.
1164 CreateNextTextureAndSetVideoSurface();
1165 StartVideoDecoderJob(true);
1166 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1167 message_loop_.Run();
1168
1169 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1170 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1171 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1172 TriggerPlayerStarvation();
1173 VerifyPlaybackCompletesOnEOSDecode(false, false /* ignored */);
1174 }
1175
TEST_F(MediaSourcePlayerTest,A_StarvationDuringEOSDecode)1176 TEST_F(MediaSourcePlayerTest, A_StarvationDuringEOSDecode) {
1177 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1178
1179 // Test that audio-only playback completes without further data requested when
1180 // starvation occurs during EOS decode.
1181 StartAudioDecoderJob(true);
1182 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1183 message_loop_.Run();
1184
1185 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1186 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1187 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1188 TriggerPlayerStarvation();
1189 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1190 }
1191
TEST_F(MediaSourcePlayerTest,AV_SeekDuringEOSDecodePreventsCompletion)1192 TEST_F(MediaSourcePlayerTest, AV_SeekDuringEOSDecodePreventsCompletion) {
1193 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1194
1195 // Test that seek supercedes audio+video playback completion on simultaneous
1196 // audio and video EOS decode, if SeekTo() occurs during these EOS decodes.
1197 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, true);
1198 }
1199
TEST_F(MediaSourcePlayerTest,AV_SeekDuringAudioEOSDecodePreventsCompletion)1200 TEST_F(MediaSourcePlayerTest, AV_SeekDuringAudioEOSDecodePreventsCompletion) {
1201 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1202
1203 // Test that seek supercedes audio+video playback completion on simultaneous
1204 // audio EOS and video non-EOS decode, if SeekTo() occurs during these
1205 // decodes.
1206 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, false);
1207 }
1208
TEST_F(MediaSourcePlayerTest,AV_SeekDuringVideoEOSDecodePreventsCompletion)1209 TEST_F(MediaSourcePlayerTest, AV_SeekDuringVideoEOSDecodePreventsCompletion) {
1210 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1211
1212 // Test that seek supercedes audio+video playback completion on simultaneous
1213 // audio non-EOS and video EOS decode, if SeekTo() occurs during these
1214 // decodes.
1215 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, false, true);
1216 }
1217
TEST_F(MediaSourcePlayerTest,V_SeekDuringEOSDecodePreventsCompletion)1218 TEST_F(MediaSourcePlayerTest, V_SeekDuringEOSDecodePreventsCompletion) {
1219 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1220
1221 // Test that seek supercedes video-only playback completion on EOS decode, if
1222 // SeekTo() occurs during EOS decode.
1223 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(false, true, false, true);
1224 }
1225
TEST_F(MediaSourcePlayerTest,A_SeekDuringEOSDecodePreventsCompletion)1226 TEST_F(MediaSourcePlayerTest, A_SeekDuringEOSDecodePreventsCompletion) {
1227 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1228
1229 // Test that seek supercedes audio-only playback completion on EOS decode, if
1230 // SeekTo() occurs during EOS decode.
1231 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, false, true, false);
1232 }
1233
TEST_F(MediaSourcePlayerTest,NoRequestForDataAfterAbort)1234 TEST_F(MediaSourcePlayerTest, NoRequestForDataAfterAbort) {
1235 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1236
1237 // Test that the decoder will not request new data after receiving an aborted
1238 // access unit.
1239 StartAudioDecoderJob(true);
1240
1241 // Send an aborted access unit.
1242 player_.OnDemuxerDataAvailable(CreateAbortedAck(true));
1243 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1244 WaitForAudioDecodeDone();
1245
1246 // No request will be sent for new data.
1247 EXPECT_EQ(1, demuxer_->num_data_requests());
1248
1249 // No seek requests should have occurred.
1250 EXPECT_EQ(0, demuxer_->num_seek_requests());
1251 }
1252
TEST_F(MediaSourcePlayerTest,DemuxerDataArrivesAfterRelease)1253 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) {
1254 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1255
1256 // Test that the decoder should not crash if demuxer data arrives after
1257 // Release().
1258 StartAudioDecoderJob(true);
1259
1260 ReleasePlayer();
1261 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1262
1263 // The decoder job should have been released.
1264 EXPECT_FALSE(player_.IsPlaying());
1265
1266 // No further data should have been requested.
1267 EXPECT_EQ(1, demuxer_->num_data_requests());
1268
1269 // No seek requests should have occurred.
1270 EXPECT_EQ(0, demuxer_->num_seek_requests());
1271 }
1272
TEST_F(MediaSourcePlayerTest,BrowserSeek_RegularSeekPendsBrowserSeekDone)1273 TEST_F(MediaSourcePlayerTest, BrowserSeek_RegularSeekPendsBrowserSeekDone) {
1274 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1275
1276 // Test that a browser seek, once started, delays a newly arrived regular
1277 // SeekTo() request's demuxer seek until the browser seek is done.
1278 BrowserSeekPlayer(false);
1279
1280 // Simulate renderer requesting a regular seek while browser seek in progress.
1281 player_.SeekTo(base::TimeDelta());
1282 EXPECT_FALSE(GetMediaDecoderJob(false));
1283
1284 // Simulate browser seek is done. Confirm player requests the regular seek,
1285 // still has no video decoder job configured, and has not requested any
1286 // further data since the surface change event became pending in
1287 // BrowserSeekPlayer().
1288 EXPECT_EQ(1, demuxer_->num_seek_requests());
1289 player_.OnDemuxerSeekDone(base::TimeDelta());
1290 EXPECT_FALSE(GetMediaDecoderJob(false));
1291 EXPECT_EQ(2, demuxer_->num_seek_requests());
1292 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
1293 EXPECT_EQ(1, demuxer_->num_data_requests());
1294
1295 // Simulate regular seek is done and confirm player requests more data for
1296 // new video decoder job.
1297 player_.OnDemuxerSeekDone(kNoTimestamp());
1298 EXPECT_TRUE(GetMediaDecoderJob(false));
1299 EXPECT_EQ(2, demuxer_->num_data_requests());
1300 EXPECT_EQ(2, demuxer_->num_seek_requests());
1301 }
1302
TEST_F(MediaSourcePlayerTest,NoSeekForInitialReleaseAndStart)1303 TEST_F(MediaSourcePlayerTest, NoSeekForInitialReleaseAndStart) {
1304 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1305
1306 // Test that no seek is requested if player Release() + Start() occurs prior
1307 // to receiving any data.
1308 CreateNextTextureAndSetVideoSurface();
1309 StartVideoDecoderJob(true);
1310 ReleasePlayer();
1311
1312 // Pass a new non-empty surface.
1313 CreateNextTextureAndSetVideoSurface();
1314
1315 player_.Start();
1316
1317 // TODO(wolenetz/qinmin): Multiple in-flight data requests for same stream
1318 // should be prevented. See http://crbug.com/306314.
1319 EXPECT_EQ(2, demuxer_->num_data_requests());
1320 EXPECT_TRUE(GetMediaDecoderJob(false));
1321
1322 EXPECT_EQ(0, demuxer_->num_seek_requests());
1323 }
1324
TEST_F(MediaSourcePlayerTest,BrowserSeek_MidStreamReleaseAndStart)1325 TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) {
1326 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1327
1328 // Test that one browser seek is requested if player Release() + Start(), with
1329 // video data received between Release() and Start().
1330 BrowserSeekPlayer(true);
1331 EXPECT_EQ(1, demuxer_->num_data_requests());
1332
1333 // Simulate browser seek is done and confirm player requests more data.
1334 player_.OnDemuxerSeekDone(base::TimeDelta());
1335 EXPECT_TRUE(GetMediaDecoderJob(false));
1336 EXPECT_EQ(2, demuxer_->num_data_requests());
1337 EXPECT_EQ(1, demuxer_->num_seek_requests());
1338 }
1339
TEST_F(MediaSourcePlayerTest,PrerollAudioAfterSeek)1340 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) {
1341 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1342
1343 // Test decoder job will preroll the media to the seek position.
1344 StartAudioDecoderJob(true);
1345
1346 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1347 EXPECT_TRUE(IsPrerolling(true));
1348 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1349
1350 // Send some data before the seek position.
1351 for (int i = 1; i < 4; ++i) {
1352 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i));
1353 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1354 message_loop_.Run();
1355 }
1356 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1357 EXPECT_TRUE(IsPrerolling(true));
1358
1359 // Send data after the seek position.
1360 DemuxerData data = CreateReadFromDemuxerAckForAudio(3);
1361 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(100);
1362 player_.OnDemuxerDataAvailable(data);
1363 message_loop_.Run();
1364 EXPECT_LT(100.0, player_.GetCurrentTime().InMillisecondsF());
1365 EXPECT_FALSE(IsPrerolling(true));
1366 }
1367
TEST_F(MediaSourcePlayerTest,PrerollVideoAfterSeek)1368 TEST_F(MediaSourcePlayerTest, PrerollVideoAfterSeek) {
1369 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1370
1371 // Test decoder job will preroll the media to the seek position.
1372 CreateNextTextureAndSetVideoSurface();
1373 StartVideoDecoderJob(true);
1374
1375 SeekPlayerWithAbort(false, base::TimeDelta::FromMilliseconds(100));
1376 EXPECT_TRUE(IsPrerolling(false));
1377 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1378
1379 // Send some data before the seek position.
1380 DemuxerData data;
1381 for (int i = 1; i < 4; ++i) {
1382 data = CreateReadFromDemuxerAckForVideo();
1383 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(i * 30);
1384 player_.OnDemuxerDataAvailable(data);
1385 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1386 message_loop_.Run();
1387 }
1388 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1389 EXPECT_TRUE(IsPrerolling(false));
1390
1391 // Send data at the seek position.
1392 data = CreateReadFromDemuxerAckForVideo();
1393 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(100);
1394 player_.OnDemuxerDataAvailable(data);
1395 message_loop_.Run();
1396
1397 // TODO(wolenetz/qinmin): Player's maintenance of current time for video-only
1398 // streams depends on decoder output, which may be initially inaccurate, and
1399 // encoded video test data may also need updating. Verify at least that AU
1400 // timestamp-based preroll logic has determined video preroll has completed.
1401 // See http://crbug.com/310823 and http://b/11356652.
1402 EXPECT_FALSE(IsPrerolling(false));
1403 }
1404
TEST_F(MediaSourcePlayerTest,SeekingAfterCompletingPrerollRestartsPreroll)1405 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) {
1406 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1407
1408 // Test decoder job will begin prerolling upon seek, when it was not
1409 // prerolling prior to the seek.
1410 StartAudioDecoderJob(true);
1411 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
1412 EXPECT_TRUE(IsPrerolling(true));
1413
1414 // Complete the initial preroll by feeding data to the decoder.
1415 for (int i = 0; i < 4; ++i) {
1416 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i));
1417 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1418 message_loop_.Run();
1419 }
1420 EXPECT_LT(0.0, player_.GetCurrentTime().InMillisecondsF());
1421 EXPECT_FALSE(IsPrerolling(true));
1422
1423 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500));
1424
1425 // Prerolling should have begun again.
1426 EXPECT_TRUE(IsPrerolling(true));
1427 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF());
1428
1429 // Send data at and after the seek position. Prerolling should complete.
1430 for (int i = 0; i < 4; ++i) {
1431 DemuxerData data = CreateReadFromDemuxerAckForAudio(i);
1432 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(
1433 500 + 30 * (i - 1));
1434 player_.OnDemuxerDataAvailable(data);
1435 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1436 message_loop_.Run();
1437 }
1438 EXPECT_LT(500.0, player_.GetCurrentTime().InMillisecondsF());
1439 EXPECT_FALSE(IsPrerolling(true));
1440
1441 // Throughout this test, we should have not re-created the decoder job, so
1442 // IsPrerolling() transition from false to true was not due to constructor
1443 // initialization. It was due to BeginPrerolling().
1444 EXPECT_EQ(decoder_job, GetMediaDecoderJob(true));
1445 }
1446
TEST_F(MediaSourcePlayerTest,PrerollContinuesAcrossReleaseAndStart)1447 TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossReleaseAndStart) {
1448 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1449
1450 // Test decoder job will resume media prerolling if interrupted by Release()
1451 // and Start().
1452 StartAudioDecoderJob(true);
1453
1454 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1455 EXPECT_TRUE(IsPrerolling(true));
1456 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1457
1458 // Send some data before the seek position.
1459 // Test uses 'large' number of iterations because decoder job may not get
1460 // MEDIA_CODEC_OK output status until after a few dequeue output attempts.
1461 // This allows decoder status to stabilize prior to AU timestamp reaching
1462 // the preroll target.
1463 DemuxerData data;
1464 for (int i = 0; i < 10; ++i) {
1465 data = CreateReadFromDemuxerAckForAudio(3);
1466 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(i * 10);
1467 if (i == 1) {
1468 // While still prerolling, Release() and Start() the player.
1469 // TODO(qinmin): Simulation of multiple in-flight data requests (one from
1470 // before Release(), one from after Start()) is not included here, and
1471 // neither is any data enqueued for later decode if it arrives after
1472 // Release() and before Start(). See http://crbug.com/306314. Assumption
1473 // for this test, to prevent flakiness until the bug is fixed, is the
1474 // first request's data arrives before Start(). Though that data is not
1475 // seen by decoder, this assumption allows preroll continuation
1476 // verification and prevents multiple in-flight data requests.
1477 ReleasePlayer();
1478 player_.OnDemuxerDataAvailable(data);
1479 message_loop_.RunUntilIdle();
1480 EXPECT_FALSE(GetMediaDecoderJob(true));
1481 StartAudioDecoderJob(true);
1482 } else {
1483 player_.OnDemuxerDataAvailable(data);
1484 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1485 message_loop_.Run();
1486 }
1487 EXPECT_TRUE(IsPrerolling(true));
1488 }
1489 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1490 EXPECT_TRUE(IsPrerolling(true));
1491
1492 // Send data after the seek position.
1493 data = CreateReadFromDemuxerAckForAudio(3);
1494 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(100);
1495 player_.OnDemuxerDataAvailable(data);
1496 message_loop_.Run();
1497 EXPECT_LT(100.0, player_.GetCurrentTime().InMillisecondsF());
1498 EXPECT_FALSE(IsPrerolling(true));
1499 }
1500
TEST_F(MediaSourcePlayerTest,PrerollContinuesAcrossConfigChange)1501 TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossConfigChange) {
1502 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1503
1504 // Test decoder job will resume media prerolling if interrupted by
1505 // |kConfigChanged| and OnDemuxerConfigsAvailable().
1506 StartAudioDecoderJob(true);
1507
1508 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1509 EXPECT_TRUE(IsPrerolling(true));
1510 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1511
1512 // In response to data request, simulate that demuxer signals config change by
1513 // sending an AU with |kConfigChanged|. Player should prepare to reconfigure
1514 // the audio decoder job, and should request new demuxer configs.
1515 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(true, 0);
1516 EXPECT_EQ(0, demuxer_->num_config_requests());
1517 player_.OnDemuxerDataAvailable(data);
1518 EXPECT_EQ(1, demuxer_->num_config_requests());
1519
1520 // Simulate arrival of new configs.
1521 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis));
1522
1523 // Send some data before the seek position.
1524 for (int i = 1; i < 4; ++i) {
1525 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i));
1526 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1527 message_loop_.Run();
1528 }
1529 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1530 EXPECT_TRUE(IsPrerolling(true));
1531
1532 // Send data after the seek position.
1533 data = CreateReadFromDemuxerAckForAudio(3);
1534 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(100);
1535 player_.OnDemuxerDataAvailable(data);
1536 message_loop_.Run();
1537 EXPECT_LT(100.0, player_.GetCurrentTime().InMillisecondsF());
1538 EXPECT_FALSE(IsPrerolling(true));
1539 }
1540
TEST_F(MediaSourcePlayerTest,SimultaneousAudioVideoConfigChange)1541 TEST_F(MediaSourcePlayerTest, SimultaneousAudioVideoConfigChange) {
1542 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1543
1544 // Test that the player allows simultaneous audio and video config change,
1545 // such as might occur during OnPrefetchDone() if next access unit for both
1546 // audio and video jobs is |kConfigChanged|.
1547 CreateNextTextureAndSetVideoSurface();
1548 Start(CreateAudioVideoDemuxerConfigs(), true);
1549 MediaDecoderJob* first_audio_job = GetMediaDecoderJob(true);
1550 MediaDecoderJob* first_video_job = GetMediaDecoderJob(false);
1551
1552 // Simulate audio |kConfigChanged| prefetched as standalone access unit.
1553 player_.OnDemuxerDataAvailable(
1554 CreateReadFromDemuxerAckWithConfigChanged(true, 0));
1555 EXPECT_EQ(0, demuxer_->num_config_requests()); // No OnPrefetchDone() yet.
1556
1557 // Simulate video |kConfigChanged| prefetched as standalone access unit.
1558 player_.OnDemuxerDataAvailable(
1559 CreateReadFromDemuxerAckWithConfigChanged(false, 0));
1560 EXPECT_EQ(1, demuxer_->num_config_requests()); // OnPrefetchDone() occurred.
1561 EXPECT_EQ(2, demuxer_->num_data_requests()); // No more data requested yet.
1562
1563 // No job re-creation should occur until the requested configs arrive.
1564 EXPECT_EQ(first_audio_job, GetMediaDecoderJob(true));
1565 EXPECT_EQ(first_video_job, GetMediaDecoderJob(false));
1566
1567 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1568 EXPECT_EQ(4, demuxer_->num_data_requests());
1569 MediaDecoderJob* second_audio_job = GetMediaDecoderJob(true);
1570 MediaDecoderJob* second_video_job = GetMediaDecoderJob(false);
1571 EXPECT_NE(first_audio_job, second_audio_job);
1572 EXPECT_NE(first_video_job, second_video_job);
1573 EXPECT_TRUE(second_audio_job && second_video_job);
1574
1575 // Confirm no further demuxer configs requested.
1576 EXPECT_EQ(1, demuxer_->num_config_requests());
1577 }
1578
TEST_F(MediaSourcePlayerTest,DemuxerConfigRequestedIfInPrefetchUnit0)1579 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInPrefetchUnit0) {
1580 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1581
1582 // Test that the player detects need for and requests demuxer configs if
1583 // the |kConfigChanged| unit is the very first unit in the set of units
1584 // received in OnDemuxerDataAvailable() ostensibly while
1585 // |PREFETCH_DONE_EVENT_PENDING|.
1586 StartConfigChange(true, true, 0);
1587 }
1588
TEST_F(MediaSourcePlayerTest,DemuxerConfigRequestedIfInPrefetchUnit1)1589 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInPrefetchUnit1) {
1590 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1591
1592 // Test that the player detects need for and requests demuxer configs if
1593 // the |kConfigChanged| unit is not the first unit in the set of units
1594 // received in OnDemuxerDataAvailable() ostensibly while
1595 // |PREFETCH_DONE_EVENT_PENDING|.
1596 StartConfigChange(true, true, 1);
1597 }
1598
TEST_F(MediaSourcePlayerTest,DemuxerConfigRequestedIfInUnit0AfterPrefetch)1599 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInUnit0AfterPrefetch) {
1600 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1601
1602 // Test that the player detects need for and requests demuxer configs if
1603 // the |kConfigChanged| unit is the very first unit in the set of units
1604 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1605 // not prefetching.
1606 StartConfigChange(true, false, 0);
1607 }
1608
TEST_F(MediaSourcePlayerTest,DemuxerConfigRequestedIfInUnit1AfterPrefetch)1609 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInUnit1AfterPrefetch) {
1610 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1611
1612 // Test that the player detects need for and requests demuxer configs if
1613 // the |kConfigChanged| unit is not the first unit in the set of units
1614 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1615 // not prefetching.
1616 StartConfigChange(true, false, 1);
1617 }
1618
TEST_F(MediaSourcePlayerTest,BrowserSeek_PrerollAfterBrowserSeek)1619 TEST_F(MediaSourcePlayerTest, BrowserSeek_PrerollAfterBrowserSeek) {
1620 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1621
1622 // Test decoder job will preroll the media to the actual seek position
1623 // resulting from a browser seek.
1624 BrowserSeekPlayer(false);
1625
1626 // Simulate browser seek is done, but to a later time than was requested.
1627 EXPECT_LT(player_.GetCurrentTime().InMillisecondsF(), 100);
1628 player_.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100));
1629 EXPECT_TRUE(GetMediaDecoderJob(false));
1630 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1631 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1632 EXPECT_EQ(2, demuxer_->num_data_requests());
1633
1634 // Send some data with access unit timestamps before the actual browser seek
1635 // position. This is a bit unrealistic in this case where the browser seek
1636 // jumped forward and next data from demuxer would normally begin at this
1637 // browser seek position, immediately completing preroll. For simplicity and
1638 // coverage, this test simulates the more common condition that AUs received
1639 // after browser seek begin with timestamps before the seek target, and don't
1640 // immediately complete preroll.
1641 DemuxerData data;
1642 for (int i = 1; i < 4; ++i) {
1643 data = CreateReadFromDemuxerAckForVideo();
1644 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(i * 30);
1645 player_.OnDemuxerDataAvailable(data);
1646 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1647 message_loop_.Run();
1648 EXPECT_TRUE(IsPrerolling(false));
1649 }
1650
1651 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1652
1653 // Send data after the browser seek position.
1654 data = CreateReadFromDemuxerAckForVideo();
1655 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(120);
1656 player_.OnDemuxerDataAvailable(data);
1657 message_loop_.Run();
1658 EXPECT_FALSE(IsPrerolling(false));
1659 }
1660
TEST_F(MediaSourcePlayerTest,VideoDemuxerConfigChange)1661 TEST_F(MediaSourcePlayerTest, VideoDemuxerConfigChange) {
1662 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1663
1664 // Test that video config change notification results in request for demuxer
1665 // configuration, and that a video decoder job results without any browser
1666 // seek necessary once the new demuxer config arrives.
1667 StartConfigChange(false, true, 1);
1668 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
1669 EXPECT_TRUE(first_job);
1670 EXPECT_EQ(1, demuxer_->num_data_requests());
1671 EXPECT_EQ(1, demuxer_->num_config_requests());
1672
1673 // Simulate arrival of new configs.
1674 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1675
1676 // New video decoder job should have been created and configured, without any
1677 // browser seek.
1678 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1679 EXPECT_TRUE(second_job);
1680 EXPECT_NE(first_job, second_job);
1681 EXPECT_EQ(2, demuxer_->num_data_requests());
1682 EXPECT_EQ(1, demuxer_->num_config_requests());
1683 EXPECT_EQ(0, demuxer_->num_seek_requests());
1684 }
1685
TEST_F(MediaSourcePlayerTest,VideoConfigChangeContinuesAcrossSeek)1686 TEST_F(MediaSourcePlayerTest, VideoConfigChangeContinuesAcrossSeek) {
1687 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1688
1689 // Test if a demuxer config request is pending (due to previously receiving
1690 // |kConfigChanged|), and a seek request arrives prior to demuxer configs,
1691 // then seek is processed first, followed by the decoder config change.
1692 // This assumes the demuxer sends |kConfigChanged| read response prior to
1693 // canceling any reads pending seek; no |kAborted| is involved in this test.
1694 StartConfigChange(false, false, 1);
1695 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
1696 EXPECT_TRUE(first_job);
1697 EXPECT_EQ(1, demuxer_->num_config_requests());
1698 EXPECT_EQ(2, demuxer_->num_data_requests());
1699 EXPECT_EQ(0, demuxer_->num_seek_requests());
1700
1701 player_.SeekTo(base::TimeDelta::FromMilliseconds(100));
1702
1703 // Verify that the seek is requested immediately.
1704 EXPECT_EQ(1, demuxer_->num_seek_requests());
1705
1706 // Simulate unlikely delayed arrival of the demuxer configs, completing the
1707 // config change.
1708 // TODO(wolenetz): Is it even possible for requested demuxer configs to be
1709 // delayed until after a SeekTo request arrives?
1710 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1711
1712 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1713 EXPECT_NE(first_job, second_job);
1714 EXPECT_TRUE(second_job);
1715
1716 // Send back the seek done notification. This should finish the seek and
1717 // trigger the player to request more data.
1718 EXPECT_EQ(2, demuxer_->num_data_requests());
1719 player_.OnDemuxerSeekDone(kNoTimestamp());
1720 EXPECT_EQ(3, demuxer_->num_data_requests());
1721 }
1722
TEST_F(MediaSourcePlayerTest,NewSurfaceWhileChangingConfigs)1723 TEST_F(MediaSourcePlayerTest, NewSurfaceWhileChangingConfigs) {
1724 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1725
1726 // Test that no seek or duplicated demuxer config request results from a
1727 // SetVideoSurface() that occurs while the player is expecting new demuxer
1728 // configs. This test may be good to keep beyond browser seek hack.
1729 StartConfigChange(false, false, 1);
1730 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
1731 EXPECT_TRUE(first_job);
1732 EXPECT_EQ(1, demuxer_->num_config_requests());
1733 EXPECT_EQ(2, demuxer_->num_data_requests());
1734
1735 CreateNextTextureAndSetVideoSurface();
1736
1737 // Surface change processing (including decoder job re-creation) should
1738 // not occur until the pending video config change is completed.
1739 EXPECT_EQ(first_job, GetMediaDecoderJob(false));
1740
1741 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1742 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1743 EXPECT_NE(first_job, second_job);
1744 EXPECT_TRUE(second_job);
1745
1746 EXPECT_EQ(3, demuxer_->num_data_requests());
1747 EXPECT_EQ(1, demuxer_->num_config_requests());
1748 EXPECT_EQ(0, demuxer_->num_seek_requests());
1749 }
1750
TEST_F(MediaSourcePlayerTest,BrowserSeek_DecoderStarvationWhilePendingSurfaceChange)1751 TEST_F(MediaSourcePlayerTest,
1752 BrowserSeek_DecoderStarvationWhilePendingSurfaceChange) {
1753 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1754
1755 // Test video decoder starvation while handling a pending surface change
1756 // should not cause any crashes.
1757 CreateNextTextureAndSetVideoSurface();
1758 StartVideoDecoderJob(true);
1759 DemuxerData data = CreateReadFromDemuxerAckForVideo();
1760 player_.OnDemuxerDataAvailable(data);
1761
1762 // Trigger a surface change and decoder starvation.
1763 CreateNextTextureAndSetVideoSurface();
1764 TriggerPlayerStarvation();
1765 WaitForVideoDecodeDone();
1766
1767 // Surface change should trigger a seek.
1768 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
1769 player_.OnDemuxerSeekDone(base::TimeDelta());
1770 EXPECT_TRUE(GetMediaDecoderJob(false));
1771
1772 // A new data request should be sent.
1773 EXPECT_EQ(2, demuxer_->num_data_requests());
1774 }
1775
TEST_F(MediaSourcePlayerTest,ReleaseWithOnPrefetchDoneAlreadyPosted)1776 TEST_F(MediaSourcePlayerTest, ReleaseWithOnPrefetchDoneAlreadyPosted) {
1777 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1778
1779 // Test if OnPrefetchDone() had already been posted before and is executed
1780 // after Release(), then player does not DCHECK. This test is fragile to
1781 // change to MediaDecoderJob::Prefetch() implementation; it assumes task
1782 // is posted to run |prefetch_cb| if the job already HasData().
1783 // TODO(wolenetz): Remove MSP::set_decode_callback_for_testing() if this test
1784 // becomes obsolete. See http://crbug.com/304234.
1785 StartAudioDecoderJob(true);
1786
1787 // Escape the original prefetch by decoding a single access unit.
1788 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1789 message_loop_.Run();
1790
1791 // Prime the job with a few more access units, so that a later prefetch,
1792 // triggered by starvation to simulate decoder underrun, can trivially
1793 // post task to run OnPrefetchDone().
1794 player_.OnDemuxerDataAvailable(
1795 CreateReadFromDemuxerAckWithConfigChanged(true, 4));
1796 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1797
1798 // Simulate decoder underrun, so trivial prefetch starts while still decoding.
1799 // The prefetch and posting of OnPrefetchDone() will not occur until next
1800 // MediaDecoderCallBack() occurs.
1801 TriggerPlayerStarvation();
1802
1803 // Upon the next successful decode callback, post a task to call Release() on
1804 // the |player_|, such that the trivial OnPrefetchDone() task posting also
1805 // occurs and should execute after the Release().
1806 OnNextTestDecodeCallbackPostTaskToReleasePlayer();
1807
1808 while (GetMediaDecoderJob(true))
1809 message_loop_.RunUntilIdle();
1810 EXPECT_TRUE(decoder_callback_hook_executed_);
1811 EXPECT_EQ(2, demuxer_->num_data_requests());
1812
1813 // Player should have no decoder job until after Start().
1814 StartAudioDecoderJob(true);
1815 }
1816
TEST_F(MediaSourcePlayerTest,SeekToThenReleaseThenDemuxerSeekAndDone)1817 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekAndDone) {
1818 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1819
1820 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1821 // has not yet been sent, then the seek request is sent after Release(). Also,
1822 // test if OnDemuxerSeekDone() occurs prior to next Start(), then the player
1823 // will resume correct post-seek preroll upon Start().
1824 StartAudioDecoderJobAndSeekToWhileDecoding(
1825 base::TimeDelta::FromMilliseconds(100));
1826 ReleasePlayer();
1827 EXPECT_EQ(1, demuxer_->num_seek_requests());
1828
1829 player_.OnDemuxerSeekDone(kNoTimestamp());
1830 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1831 EXPECT_FALSE(GetMediaDecoderJob(true));
1832 EXPECT_FALSE(player_.IsPlaying());
1833
1834 // Player should begin prefetch and resume preroll upon Start().
1835 EXPECT_EQ(1, demuxer_->num_data_requests());
1836 StartAudioDecoderJob(true);
1837 EXPECT_TRUE(IsPrerolling(true));
1838 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1839
1840 // No further seek should have been requested since Release(), above.
1841 EXPECT_EQ(1, demuxer_->num_seek_requests());
1842 }
1843
TEST_F(MediaSourcePlayerTest,SeekToThenReleaseThenDemuxerSeekThenStart)1844 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekThenStart) {
1845 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1846
1847 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1848 // has not yet been sent, then the seek request is sent after Release(). Also,
1849 // test if OnDemuxerSeekDone() does not occur until after the next Start(),
1850 // then the player remains pending seek done until (and resumes correct
1851 // post-seek preroll after) OnDemuxerSeekDone().
1852 StartAudioDecoderJobAndSeekToWhileDecoding(
1853 base::TimeDelta::FromMilliseconds(100));
1854 ReleasePlayer();
1855 EXPECT_EQ(1, demuxer_->num_seek_requests());
1856
1857 // Player should not prefetch upon Start() nor create the decoder job, due to
1858 // awaiting DemuxerSeekDone.
1859 EXPECT_EQ(1, demuxer_->num_data_requests());
1860 StartAudioDecoderJob(false);
1861
1862 player_.OnDemuxerSeekDone(kNoTimestamp());
1863 EXPECT_TRUE(GetMediaDecoderJob(true));
1864 EXPECT_TRUE(IsPrerolling(true));
1865 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1866 EXPECT_EQ(2, demuxer_->num_data_requests());
1867
1868 // No further seek should have been requested since Release(), above.
1869 EXPECT_EQ(1, demuxer_->num_seek_requests());
1870 }
1871
TEST_F(MediaSourcePlayerTest,SeekToThenDemuxerSeekThenReleaseThenSeekDone)1872 TEST_F(MediaSourcePlayerTest, SeekToThenDemuxerSeekThenReleaseThenSeekDone) {
1873 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1874
1875 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC
1876 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the
1877 // player will resume correct post-seek preroll upon Start().
1878 StartAudioDecoderJobAndSeekToWhileDecoding(
1879 base::TimeDelta::FromMilliseconds(100));
1880 WaitForAudioDecodeDone();
1881 EXPECT_EQ(1, demuxer_->num_seek_requests());
1882
1883 ReleasePlayer();
1884 player_.OnDemuxerSeekDone(kNoTimestamp());
1885 EXPECT_FALSE(player_.IsPlaying());
1886 EXPECT_FALSE(GetMediaDecoderJob(true));
1887 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1888
1889 // Player should begin prefetch and resume preroll upon Start().
1890 EXPECT_EQ(1, demuxer_->num_data_requests());
1891 StartAudioDecoderJob(true);
1892 EXPECT_TRUE(IsPrerolling(true));
1893 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1894
1895 // No further seek should have been requested since before Release(), above.
1896 EXPECT_EQ(1, demuxer_->num_seek_requests());
1897 }
1898
TEST_F(MediaSourcePlayerTest,SeekToThenReleaseThenStart)1899 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenStart) {
1900 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1901
1902 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC
1903 // request and OnDemuxerSeekDone() does not occur until after the next
1904 // Start(), then the player remains pending seek done until (and resumes
1905 // correct post-seek preroll after) OnDemuxerSeekDone().
1906 StartAudioDecoderJobAndSeekToWhileDecoding(
1907 base::TimeDelta::FromMilliseconds(100));
1908 WaitForAudioDecodeDone();
1909 EXPECT_EQ(1, demuxer_->num_seek_requests());
1910
1911 ReleasePlayer();
1912 EXPECT_EQ(1, demuxer_->num_data_requests());
1913 StartAudioDecoderJob(false);
1914
1915 player_.OnDemuxerSeekDone(kNoTimestamp());
1916 EXPECT_TRUE(GetMediaDecoderJob(true));
1917 EXPECT_TRUE(IsPrerolling(true));
1918 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1919 EXPECT_EQ(2, demuxer_->num_data_requests());
1920
1921 // No further seek should have been requested since before Release(), above.
1922 EXPECT_EQ(1, demuxer_->num_seek_requests());
1923 }
1924
TEST_F(MediaSourcePlayerTest,ConfigChangedThenReleaseThenConfigsAvailable)1925 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenConfigsAvailable) {
1926 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1927
1928 // Test if Release() occurs after |kConfigChanged| detected, new configs
1929 // requested of demuxer, and the requested configs arrive before the next
1930 // Start(), then the player completes the pending config change processing on
1931 // their receipt.
1932 StartConfigChange(true, true, 0);
1933 ReleasePlayer();
1934
1935 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis));
1936 EXPECT_FALSE(GetMediaDecoderJob(true));
1937 EXPECT_FALSE(player_.IsPlaying());
1938 EXPECT_EQ(1, demuxer_->num_data_requests());
1939
1940 // Player should resume upon Start(), even without further configs supplied.
1941 player_.Start();
1942 EXPECT_TRUE(GetMediaDecoderJob(true));
1943 EXPECT_TRUE(player_.IsPlaying());
1944 EXPECT_EQ(2, demuxer_->num_data_requests());
1945
1946 // No further config request should have occurred since StartConfigChange().
1947 EXPECT_EQ(1, demuxer_->num_config_requests());
1948 }
1949
TEST_F(MediaSourcePlayerTest,ConfigChangedThenReleaseThenStart)1950 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenStart) {
1951 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1952
1953 // Test if Release() occurs after |kConfigChanged| detected, new configs
1954 // requested of demuxer, and the requested configs arrive after the next
1955 // Start(), then the player pends job creation until the new configs arrive.
1956 StartConfigChange(true, true, 0);
1957 ReleasePlayer();
1958
1959 player_.Start();
1960 EXPECT_TRUE(player_.IsPlaying());
1961 EXPECT_FALSE(GetMediaDecoderJob(true));
1962 EXPECT_EQ(1, demuxer_->num_data_requests());
1963
1964 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis));
1965 EXPECT_TRUE(GetMediaDecoderJob(true));
1966 EXPECT_EQ(2, demuxer_->num_data_requests());
1967
1968 // No further config request should have occurred since StartConfigChange().
1969 EXPECT_EQ(1, demuxer_->num_config_requests());
1970 }
1971
TEST_F(MediaSourcePlayerTest,BrowserSeek_ThenReleaseThenDemuxerSeekDone)1972 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenDemuxerSeekDone) {
1973 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1974
1975 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
1976 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() occurs
1977 // before the next Start()+SetVideoSurface(), then the player will resume
1978 // correct post-seek preroll upon Start()+SetVideoSurface().
1979 BrowserSeekPlayer(false);
1980 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
1981 ReleasePlayer();
1982
1983 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
1984 EXPECT_FALSE(player_.IsPlaying());
1985 EXPECT_FALSE(GetMediaDecoderJob(false));
1986 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1987
1988 // Player should begin prefetch and resume preroll upon Start().
1989 EXPECT_EQ(1, demuxer_->num_data_requests());
1990 CreateNextTextureAndSetVideoSurface();
1991 StartVideoDecoderJob(true);
1992 EXPECT_TRUE(IsPrerolling(false));
1993 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1994 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
1995
1996 // No further seek should have been requested since BrowserSeekPlayer().
1997 EXPECT_EQ(1, demuxer_->num_seek_requests());
1998 }
1999
TEST_F(MediaSourcePlayerTest,BrowserSeek_ThenReleaseThenStart)2000 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenStart) {
2001 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2002
2003 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
2004 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
2005 // occur until after the next Start()+SetVideoSurface(), then the player
2006 // remains pending seek done until (and resumes correct post-seek preroll
2007 // after) OnDemuxerSeekDone().
2008 BrowserSeekPlayer(false);
2009 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
2010 ReleasePlayer();
2011
2012 EXPECT_EQ(1, demuxer_->num_data_requests());
2013 CreateNextTextureAndSetVideoSurface();
2014 StartVideoDecoderJob(false);
2015
2016 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
2017 EXPECT_TRUE(GetMediaDecoderJob(false));
2018 EXPECT_TRUE(IsPrerolling(false));
2019 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
2020 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
2021 EXPECT_EQ(2, demuxer_->num_data_requests());
2022
2023 // No further seek should have been requested since BrowserSeekPlayer().
2024 EXPECT_EQ(1, demuxer_->num_seek_requests());
2025 }
2026
2027 // TODO(xhwang): Once we add tests to cover DrmBridge, update this test to
2028 // also verify that the job is successfully created if SetDrmBridge(), Start()
2029 // and eventually OnMediaCrypto() occur. This would increase test coverage of
2030 // http://crbug.com/313470 and allow us to remove inspection of internal player
2031 // pending event state. See http://crbug.com/313860.
TEST_F(MediaSourcePlayerTest,SurfaceChangeClearedEvenIfMediaCryptoAbsent)2032 TEST_F(MediaSourcePlayerTest, SurfaceChangeClearedEvenIfMediaCryptoAbsent) {
2033 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2034
2035 // Test that |SURFACE_CHANGE_EVENT_PENDING| is not pending after
2036 // SetVideoSurface() for a player configured for encrypted video, when the
2037 // player has not yet received media crypto.
2038 DemuxerConfigs configs = CreateVideoDemuxerConfigs();
2039 configs.is_video_encrypted = true;
2040
2041 player_.OnDemuxerConfigsAvailable(configs);
2042 CreateNextTextureAndSetVideoSurface();
2043 EXPECT_FALSE(IsPendingSurfaceChange());
2044 EXPECT_FALSE(GetMediaDecoderJob(false));
2045 }
2046
2047 // TODO(xhwang): Enable this test when the test devices are updated.
TEST_F(MediaSourcePlayerTest,DISABLED_IsTypeSupported_Widevine)2048 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) {
2049 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
2050 VLOG(0) << "Could not run test - not supported on device.";
2051 return;
2052 }
2053
2054 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,
2055 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED };
2056
2057 std::vector<uint8> widevine_uuid(kWidevineUUID,
2058 kWidevineUUID + arraysize(kWidevineUUID));
2059
2060 // We test "L3" fully. But for "L1" we don't check the result as it depend on
2061 // whether the test device supports "L1" decoding.
2062
2063 std::vector<std::string> codec_avc(1, "avc1");
2064 std::vector<std::string> codec_aac(1, "mp4a");
2065 std::vector<std::string> codec_avc_aac(1, "avc1");
2066 codec_avc_aac.push_back("mp4a");
2067
2068 EXPECT_TRUE(IsTypeSupported(widevine_uuid, "L3", kVideoMp4, codec_avc));
2069 IsTypeSupported(widevine_uuid, "L1", kVideoMp4, codec_avc);
2070
2071 // TODO(xhwang): L1/L3 doesn't apply to audio, so the result is messy.
2072 // Clean this up after we have a solution to specifying decoding mode.
2073 EXPECT_TRUE(IsTypeSupported(widevine_uuid, "L3", kAudioMp4, codec_aac));
2074 IsTypeSupported(widevine_uuid, "L1", kAudioMp4, codec_aac);
2075
2076 EXPECT_TRUE(IsTypeSupported(widevine_uuid, "L3", kVideoMp4, codec_avc_aac));
2077 IsTypeSupported(widevine_uuid, "L1", kVideoMp4, codec_avc_aac);
2078
2079 std::vector<std::string> codec_vp8(1, "vp8");
2080 std::vector<std::string> codec_vorbis(1, "vorbis");
2081 std::vector<std::string> codec_vp8_vorbis(1, "vp8");
2082 codec_vp8_vorbis.push_back("vorbis");
2083
2084 // TODO(xhwang): WebM is actually not supported but currently
2085 // MediaDrmBridge.isCryptoSchemeSupported() doesn't check the container type.
2086 // Fix isCryptoSchemeSupported() and update this test as necessary.
2087 EXPECT_TRUE(IsTypeSupported(widevine_uuid, "L3", kVideoWebM, codec_vp8));
2088 IsTypeSupported(widevine_uuid, "L1", kVideoWebM, codec_vp8);
2089
2090 // TODO(xhwang): L1/L3 doesn't apply to audio, so the result is messy.
2091 // Clean this up after we have a solution to specifying decoding mode.
2092 EXPECT_TRUE(IsTypeSupported(widevine_uuid, "L3", kAudioWebM, codec_vorbis));
2093 IsTypeSupported(widevine_uuid, "L1", kAudioWebM, codec_vorbis);
2094
2095 EXPECT_TRUE(
2096 IsTypeSupported(widevine_uuid, "L3", kVideoWebM, codec_vp8_vorbis));
2097 IsTypeSupported(widevine_uuid, "L1", kVideoWebM, codec_vp8_vorbis);
2098 }
2099
TEST_F(MediaSourcePlayerTest,IsTypeSupported_InvalidUUID)2100 TEST_F(MediaSourcePlayerTest, IsTypeSupported_InvalidUUID) {
2101 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
2102 VLOG(0) << "Could not run test - not supported on device.";
2103 return;
2104 }
2105
2106 uint8 kInvalidUUID[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
2107 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
2108
2109 std::vector<uint8> invalid_uuid(kInvalidUUID,
2110 kInvalidUUID + arraysize(kInvalidUUID));
2111
2112 std::vector<std::string> codec_avc(1, "avc1");
2113 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc));
2114 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc));
2115 }
2116
2117 // TODO(xhwang): Are these IsTypeSupported tests device specific?
2118 // TODO(xhwang): Add more IsTypeSupported tests.
2119
2120 } // namespace media
2121