1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/stringprintf.h"
10 #include "media/base/android/media_codec_bridge.h"
11 #include "media/base/android/media_drm_bridge.h"
12 #include "media/base/android/media_player_manager.h"
13 #include "media/base/android/media_source_player.h"
14 #include "media/base/bind_to_current_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"
22 // Helper macro to skip the test if MediaCodecBridge isn't available.
23 #define SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE() \
25 if (!MediaCodecBridge::IsAvailable()) { \
26 VLOG(0) << "Could not run test - not supported on device."; \
31 const int kDefaultDurationInMs = 10000;
33 const char kAudioMp4[] = "audio/mp4";
34 const char kVideoMp4[] = "video/mp4";
35 const char kAudioWebM[] = "audio/webm";
36 const char kVideoWebM[] = "video/webm";
37 const MediaDrmBridge::SecurityLevel kL1 = MediaDrmBridge::SECURITY_LEVEL_1;
38 const MediaDrmBridge::SecurityLevel kL3 = MediaDrmBridge::SECURITY_LEVEL_3;
40 // TODO(wolenetz/qinmin): Simplify tests with more effective mock usage, and
41 // fix flaky pointer-based MDJ inequality testing. See http://crbug.com/327839.
43 // Mock of MediaPlayerManager for testing purpose
44 class MockMediaPlayerManager : public MediaPlayerManager {
46 explicit MockMediaPlayerManager(base::MessageLoop* message_loop)
47 : message_loop_(message_loop),
48 playback_completed_(false) {}
49 virtual ~MockMediaPlayerManager() {}
51 // MediaPlayerManager implementation.
52 virtual void RequestMediaResources(int player_id) OVERRIDE {}
53 virtual void ReleaseMediaResources(int player_id) OVERRIDE {}
54 virtual MediaResourceGetter* GetMediaResourceGetter() OVERRIDE {
57 virtual void OnTimeUpdate(int player_id,
58 base::TimeDelta current_time) OVERRIDE {}
59 virtual void OnMediaMetadataChanged(
60 int player_id, base::TimeDelta duration, int width, int height,
61 bool success) OVERRIDE {}
62 virtual void OnPlaybackComplete(int player_id) OVERRIDE {
63 playback_completed_ = true;
64 if (message_loop_->is_running())
65 message_loop_->Quit();
67 virtual void OnMediaInterrupted(int player_id) OVERRIDE {}
68 virtual void OnBufferingUpdate(int player_id, int percentage) OVERRIDE {}
69 virtual void OnSeekComplete(int player_id,
70 const base::TimeDelta& current_time) OVERRIDE {}
71 virtual void OnError(int player_id, int error) OVERRIDE {}
72 virtual void OnVideoSizeChanged(int player_id, int width,
73 int height) OVERRIDE {}
74 virtual MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE { return NULL; }
75 virtual MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE { return NULL; }
76 virtual void DestroyAllMediaPlayers() OVERRIDE {}
77 virtual MediaDrmBridge* GetDrmBridge(int media_keys_id) OVERRIDE {
80 virtual void OnProtectedSurfaceRequested(int player_id) OVERRIDE {}
81 virtual void OnSessionCreated(int media_keys_id,
83 const std::string& web_session_id) OVERRIDE {}
84 virtual void OnSessionMessage(int media_keys_id,
86 const std::vector<uint8>& message,
87 const GURL& destination_url) OVERRIDE {}
88 virtual void OnSessionReady(int media_keys_id, uint32 session_id) OVERRIDE {}
89 virtual void OnSessionClosed(int media_keys_id, uint32 session_id) OVERRIDE {}
90 virtual void OnSessionError(int media_keys_id,
92 media::MediaKeys::KeyError error_code,
93 int system_code) OVERRIDE {}
95 bool playback_completed() const {
96 return playback_completed_;
100 base::MessageLoop* message_loop_;
101 bool playback_completed_;
103 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager);
106 class MockDemuxerAndroid : public DemuxerAndroid {
108 explicit MockDemuxerAndroid(base::MessageLoop* message_loop)
109 : message_loop_(message_loop),
110 num_data_requests_(0),
111 num_seek_requests_(0),
112 num_browser_seek_requests_(0),
113 num_config_requests_(0) {}
114 virtual ~MockDemuxerAndroid() {}
116 virtual void Initialize(DemuxerAndroidClient* client) OVERRIDE {}
117 virtual void RequestDemuxerConfigs() OVERRIDE {
118 num_config_requests_++;
120 virtual void RequestDemuxerData(DemuxerStream::Type type) OVERRIDE {
121 num_data_requests_++;
122 if (message_loop_->is_running())
123 message_loop_->Quit();
125 virtual void RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
126 bool is_browser_seek) OVERRIDE {
127 num_seek_requests_++;
129 num_browser_seek_requests_++;
132 int num_data_requests() const { return num_data_requests_; }
133 int num_seek_requests() const { return num_seek_requests_; }
134 int num_browser_seek_requests() const { return num_browser_seek_requests_; }
135 int num_config_requests() const { return num_config_requests_; }
138 base::MessageLoop* message_loop_;
140 // The number of encoded data requests this object has seen.
141 int num_data_requests_;
143 // The number of regular and browser seek requests this object has seen.
144 int num_seek_requests_;
146 // The number of browser seek requests this object has seen.
147 int num_browser_seek_requests_;
149 // The number of demuxer config requests this object has seen.
150 int num_config_requests_;
152 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
155 class MediaSourcePlayerTest : public testing::Test {
157 MediaSourcePlayerTest()
158 : manager_(&message_loop_),
159 demuxer_(new MockDemuxerAndroid(&message_loop_)),
160 player_(0, &manager_, scoped_ptr<DemuxerAndroid>(demuxer_)),
161 decoder_callback_hook_executed_(false),
162 surface_texture_a_is_next_(true) {}
163 virtual ~MediaSourcePlayerTest() {}
166 // Get the decoder job from the MediaSourcePlayer.
167 MediaDecoderJob* GetMediaDecoderJob(bool is_audio) {
169 return reinterpret_cast<MediaDecoderJob*>(
170 player_.audio_decoder_job_.get());
172 return reinterpret_cast<MediaDecoderJob*>(
173 player_.video_decoder_job_.get());
176 // Get the per-job prerolling status from the MediaSourcePlayer's job matching
177 // |is_audio|. Caller must guard against NPE if the player's job is NULL.
178 bool IsPrerolling(bool is_audio) {
179 return GetMediaDecoderJob(is_audio)->prerolling();
182 // Get the preroll timestamp from the MediaSourcePlayer.
183 base::TimeDelta GetPrerollTimestamp() {
184 return player_.preroll_timestamp_;
187 // Simulate player has reached starvation timeout.
188 void TriggerPlayerStarvation() {
189 player_.decoder_starvation_callback_.Cancel();
190 player_.OnDecoderStarved();
193 // Release() the player.
194 void ReleasePlayer() {
195 EXPECT_TRUE(player_.IsPlaying());
197 EXPECT_FALSE(player_.IsPlaying());
198 EXPECT_FALSE(GetMediaDecoderJob(true));
199 EXPECT_FALSE(GetMediaDecoderJob(false));
202 // Upon the next successful decode callback, post a task to call Release()
203 // on the |player_|. TEST_F's do not have access to the private player
204 // members, hence this helper method.
205 // Prevent usage creep of MSP::set_decode_callback_for_testing() by
206 // only using it for the ReleaseWithOnPrefetchDoneAlreadyPosted test.
207 void OnNextTestDecodeCallbackPostTaskToReleasePlayer() {
208 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
209 player_.set_decode_callback_for_testing(media::BindToCurrentLoop(
211 &MediaSourcePlayerTest::ReleaseWithPendingPrefetchDoneVerification,
212 base::Unretained(this))));
215 // Asynch test callback posted upon decode completion to verify that a pending
216 // prefetch done event is cleared across |player_|'s Release(). This helps
217 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
218 void ReleaseWithPendingPrefetchDoneVerification() {
219 EXPECT_TRUE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
221 EXPECT_FALSE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
222 EXPECT_FALSE(decoder_callback_hook_executed_);
223 decoder_callback_hook_executed_ = true;
226 // Inspect internal pending_event_ state of |player_|. This is for infrequent
227 // use by tests, only where required.
228 bool IsPendingSurfaceChange() {
229 return player_.IsEventPending(player_.SURFACE_CHANGE_EVENT_PENDING);
232 DemuxerConfigs CreateAudioDemuxerConfigs(AudioCodec audio_codec) {
233 DemuxerConfigs configs;
234 configs.audio_codec = audio_codec;
235 configs.audio_channels = 2;
236 configs.is_audio_encrypted = false;
237 configs.duration_ms = kDefaultDurationInMs;
239 if (audio_codec == kCodecVorbis) {
240 configs.audio_sampling_rate = 44100;
241 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(
243 configs.audio_extra_data = std::vector<uint8>(
245 buffer->data() + buffer->data_size());
249 // Other codecs are not yet supported by this helper.
250 EXPECT_EQ(audio_codec, kCodecAAC);
252 configs.audio_sampling_rate = 48000;
253 uint8 aac_extra_data[] = { 0x13, 0x10 };
254 configs.audio_extra_data = std::vector<uint8>(
260 DemuxerConfigs CreateVideoDemuxerConfigs() {
261 DemuxerConfigs configs;
262 configs.video_codec = kCodecVP8;
263 configs.video_size = gfx::Size(320, 240);
264 configs.is_video_encrypted = false;
265 configs.duration_ms = kDefaultDurationInMs;
269 DemuxerConfigs CreateAudioVideoDemuxerConfigs() {
270 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis);
271 configs.video_codec = kCodecVP8;
272 configs.video_size = gfx::Size(320, 240);
273 configs.is_video_encrypted = false;
277 DemuxerConfigs CreateDemuxerConfigs(bool have_audio, bool have_video) {
278 DCHECK(have_audio || have_video);
280 if (have_audio && !have_video)
281 return CreateAudioDemuxerConfigs(kCodecVorbis);
283 if (have_video && !have_audio)
284 return CreateVideoDemuxerConfigs();
286 return CreateAudioVideoDemuxerConfigs();
289 // Starts an audio decoder job. Verifies player behavior relative to
290 // |expect_player_requests_data|.
291 void StartAudioDecoderJob(bool expect_player_requests_data) {
292 Start(CreateAudioDemuxerConfigs(kCodecVorbis), expect_player_requests_data);
295 // Starts a video decoder job. Verifies player behavior relative to
296 // |expect_player_requests_data|.
297 void StartVideoDecoderJob(bool expect_player_requests_data) {
298 Start(CreateVideoDemuxerConfigs(), expect_player_requests_data);
301 // Starts decoding the data. Verifies player behavior relative to
302 // |expect_player_requests_data|.
303 void Start(const DemuxerConfigs& configs, bool expect_player_requests_data) {
304 bool has_audio = configs.audio_codec != kUnknownAudioCodec;
305 bool has_video = configs.video_codec != kUnknownVideoCodec;
306 int original_num_data_requests = demuxer_->num_data_requests();
307 int expected_request_delta = expect_player_requests_data ?
308 ((has_audio ? 1 : 0) + (has_video ? 1 : 0)) : 0;
310 player_.OnDemuxerConfigsAvailable(configs);
313 EXPECT_TRUE(player_.IsPlaying());
314 EXPECT_EQ(original_num_data_requests + expected_request_delta,
315 demuxer_->num_data_requests());
317 // Verify player has decoder job iff the config included the media type for
318 // the job and the player is expected to request data due to Start(), above.
319 EXPECT_EQ(expect_player_requests_data && has_audio,
320 GetMediaDecoderJob(true) != NULL);
321 EXPECT_EQ(expect_player_requests_data && has_video,
322 GetMediaDecoderJob(false) != NULL);
325 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) {
328 unit.status = DemuxerStream::kOk;
329 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(
330 is_audio ? base::StringPrintf("vorbis-packet-%d", audio_packet_id)
331 : "vp8-I-frame-320x240");
332 unit.data = std::vector<uint8>(
333 buffer->data(), buffer->data() + buffer->data_size());
336 // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
337 // NuMediaExtractor.cpp in Android source code.
338 uint8 padding[4] = { 0xff , 0xff , 0xff , 0xff };
339 unit.data.insert(unit.data.end(), padding, padding + 4);
345 DemuxerData CreateReadFromDemuxerAckForAudio(int packet_id) {
347 data.type = DemuxerStream::AUDIO;
348 data.access_units.resize(1);
349 data.access_units[0] = CreateAccessUnitWithData(true, packet_id);
353 DemuxerData CreateReadFromDemuxerAckForVideo() {
355 data.type = DemuxerStream::VIDEO;
356 data.access_units.resize(1);
357 data.access_units[0] = CreateAccessUnitWithData(false, 0);
361 DemuxerData CreateEOSAck(bool is_audio) {
363 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
364 data.access_units.resize(1);
365 data.access_units[0].status = DemuxerStream::kOk;
366 data.access_units[0].end_of_stream = true;
370 DemuxerData CreateAbortedAck(bool is_audio) {
372 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
373 data.access_units.resize(1);
374 data.access_units[0].status = DemuxerStream::kAborted;
378 // Helper method for use at test start. It starts an audio decoder job and
379 // immediately feeds it some data to decode. Then, without letting the decoder
380 // job complete a decode cycle, it also starts player SeekTo(). Upon return,
381 // the player should not yet have sent the DemuxerSeek IPC request, though
382 // seek event should be pending. The audio decoder job will also still be
384 void StartAudioDecoderJobAndSeekToWhileDecoding(
385 const base::TimeDelta& seek_time) {
386 EXPECT_FALSE(GetMediaDecoderJob(true));
387 EXPECT_FALSE(player_.IsPlaying());
388 EXPECT_EQ(0, demuxer_->num_data_requests());
389 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
390 EXPECT_EQ(player_.GetCurrentTime(), GetPrerollTimestamp());
391 StartAudioDecoderJob(true);
392 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
393 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
394 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
395 player_.SeekTo(seek_time);
396 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
397 EXPECT_EQ(0, demuxer_->num_seek_requests());
400 // Seek, including simulated receipt of |kAborted| read between SeekTo() and
401 // OnDemuxerSeekDone(). Use this helper method only when the player already
402 // has created the decoder job. Exactly one request for more data is expected
403 // following the seek, so use this helper for players with only audio or only
405 void SeekPlayerWithAbort(bool is_audio, const base::TimeDelta& seek_time) {
406 int original_num_seeks = demuxer_->num_seek_requests();
407 int original_num_data_requests = demuxer_->num_data_requests();
409 // Initiate a seek. Skip the round-trip of requesting seek from renderer.
410 // Instead behave as if the renderer has asked us to seek.
411 player_.SeekTo(seek_time);
413 // Verify that the seek does not occur until previously outstanding data
414 // request is satisfied.
415 EXPECT_EQ(original_num_seeks, demuxer_->num_seek_requests());
417 // Simulate seeking causes the demuxer to abort the outstanding read
418 // caused by the seek.
419 player_.OnDemuxerDataAvailable(CreateAbortedAck(is_audio));
421 // Verify that the seek is requested.
422 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests());
424 // Send back the seek done notification. This should trigger the player to
425 // call OnReadFromDemuxer() again.
426 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests());
427 player_.OnDemuxerSeekDone(kNoTimestamp());
428 EXPECT_EQ(original_num_data_requests + 1, demuxer_->num_data_requests());
430 // No other seek should have been requested.
431 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests());
434 // Preroll the decoder job to |target_timestamp|. The first access unit
435 // to decode will have a timestamp equal to |start_timestamp|.
436 // TODO(qinmin): Add additional test cases for out-of-order decodes.
437 // See http://crbug.com/331421.
438 void PrerollDecoderToTime(bool is_audio,
439 const base::TimeDelta& start_timestamp,
440 const base::TimeDelta& target_timestamp) {
441 EXPECT_EQ(target_timestamp, player_.GetCurrentTime());
442 // |start_timestamp| must be smaller than |target_timestamp|.
443 EXPECT_LE(start_timestamp, target_timestamp);
444 DemuxerData data = is_audio ? CreateReadFromDemuxerAckForAudio(1) :
445 CreateReadFromDemuxerAckForVideo();
446 int current_timestamp = start_timestamp.InMilliseconds();
448 // Send some data with access unit timestamps before the |target_timestamp|,
449 // and continue sending the data until preroll finishes.
450 // This simulates the common condition that AUs received after browser
451 // seek begin with timestamps before the seek target, and don't
452 // immediately complete preroll.
453 while (IsPrerolling(is_audio)) {
454 data.access_units[0].timestamp =
455 base::TimeDelta::FromMilliseconds(current_timestamp);
456 player_.OnDemuxerDataAvailable(data);
457 EXPECT_TRUE(GetMediaDecoderJob(is_audio)->is_decoding());
458 EXPECT_EQ(target_timestamp, player_.GetCurrentTime());
459 current_timestamp += 30;
462 EXPECT_LE(target_timestamp, player_.GetCurrentTime());
465 DemuxerData CreateReadFromDemuxerAckWithConfigChanged(bool is_audio,
466 int config_unit_index) {
468 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
469 data.access_units.resize(config_unit_index + 1);
471 for (int i = 0; i < config_unit_index; ++i)
472 data.access_units[i] = CreateAccessUnitWithData(is_audio, i);
474 data.access_units[config_unit_index].status = DemuxerStream::kConfigChanged;
478 // Valid only for video-only player tests. If |trigger_with_release_start| is
479 // true, triggers the browser seek with a Release() + video data received +
480 // Start() with a new surface. If false, triggers the browser seek by
481 // setting a new video surface after beginning decode of received video data.
482 // Such data receipt causes possibility that an I-frame is not next, and
483 // browser seek results once decode completes and surface change processing
485 void BrowserSeekPlayer(bool trigger_with_release_start) {
486 int expected_num_data_requests = demuxer_->num_data_requests() + 1;
487 int expected_num_seek_requests = demuxer_->num_seek_requests();
488 int expected_num_browser_seek_requests =
489 demuxer_->num_browser_seek_requests();
491 EXPECT_FALSE(GetMediaDecoderJob(false));
492 CreateNextTextureAndSetVideoSurface();
493 StartVideoDecoderJob(true);
495 if (trigger_with_release_start) {
498 // Simulate demuxer's response to the video data request.
499 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
500 EXPECT_FALSE(GetMediaDecoderJob(false));
501 EXPECT_FALSE(player_.IsPlaying());
502 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
504 CreateNextTextureAndSetVideoSurface();
505 StartVideoDecoderJob(false);
507 // Simulate demuxer's response to the video data request.
508 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
510 // While the decoder is decoding, trigger a browser seek by changing
511 // surface. Demuxer does not know of browser seek in advance, so no
512 // |kAborted| data is required (though |kAborted| can certainly occur for
513 // any pending read in reality due to renderer preparing for a regular
515 CreateNextTextureAndSetVideoSurface();
517 // Browser seek should not begin until decoding has completed.
518 EXPECT_TRUE(GetMediaDecoderJob(false));
519 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
521 // Wait for the decoder job to finish decoding and be reset pending the
523 while (GetMediaDecoderJob(false))
524 message_loop_.RunUntilIdle();
527 // Only one browser seek should have been initiated, and no further data
528 // should have been requested.
529 expected_num_seek_requests++;
530 expected_num_browser_seek_requests++;
531 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
532 EXPECT_EQ(expected_num_browser_seek_requests,
533 demuxer_->num_browser_seek_requests());
534 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
537 // Creates a new decoder job and feeds it data ending with a |kConfigChanged|
538 // access unit. If |config_unit_in_prefetch| is true, sends feeds the config
539 // change AU in response to the job's first read request (prefetch). If
540 // false, regular data is fed and decoded prior to feeding the config change
541 // AU in response to the second data request (after prefetch completed).
542 // |config_unit_index| controls which access unit is |kConfigChanged|.
543 void StartConfigChange(bool is_audio,
544 bool config_unit_in_prefetch,
545 int config_unit_index) {
546 int expected_num_config_requests = demuxer_->num_config_requests();
548 EXPECT_FALSE(GetMediaDecoderJob(is_audio));
550 StartAudioDecoderJob(true);
552 CreateNextTextureAndSetVideoSurface();
553 StartVideoDecoderJob(true);
556 int expected_num_data_requests = demuxer_->num_data_requests();
558 // Feed and decode a standalone access unit so the player exits prefetch.
559 if (!config_unit_in_prefetch) {
561 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
563 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
567 // We should have completed the prefetch phase at this point.
568 expected_num_data_requests++;
569 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
572 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests());
574 // Feed and decode access units with data for any units prior to
575 // |config_unit_index|, and a |kConfigChanged| unit at that index.
576 // Player should prepare to reconfigure the decoder job, and should request
577 // new demuxer configs.
578 player_.OnDemuxerDataAvailable(
579 CreateReadFromDemuxerAckWithConfigChanged(is_audio, config_unit_index));
580 WaitForDecodeDone(is_audio, !is_audio);
582 expected_num_config_requests++;
583 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
584 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests());
587 void CreateNextTextureAndSetVideoSurface() {
588 gfx::SurfaceTexture* surface_texture;
589 if (surface_texture_a_is_next_) {
590 surface_texture_a_ = new gfx::SurfaceTexture(next_texture_id_++);
591 surface_texture = surface_texture_a_.get();
593 surface_texture_b_ = new gfx::SurfaceTexture(next_texture_id_++);
594 surface_texture = surface_texture_b_.get();
597 surface_texture_a_is_next_ = !surface_texture_a_is_next_;
598 gfx::ScopedJavaSurface surface = gfx::ScopedJavaSurface(surface_texture);
599 player_.SetVideoSurface(surface.Pass());
602 // Wait for one or both of the jobs to complete decoding. Decoder jobs are
603 // assumed to exist for any stream whose decode completion is awaited.
604 void WaitForDecodeDone(bool wait_for_audio, bool wait_for_video) {
605 DCHECK(wait_for_audio || wait_for_video);
607 while ((wait_for_audio && GetMediaDecoderJob(true) &&
608 GetMediaDecoderJob(true)->is_decoding()) ||
609 (wait_for_video && GetMediaDecoderJob(false) &&
610 GetMediaDecoderJob(false)->is_decoding())) {
611 message_loop_.RunUntilIdle();
615 void WaitForAudioDecodeDone() {
616 WaitForDecodeDone(true, false);
619 void WaitForVideoDecodeDone() {
620 WaitForDecodeDone(false, true);
623 void WaitForAudioVideoDecodeDone() {
624 WaitForDecodeDone(true, true);
627 // If |send_eos| is true, generates EOS for the stream corresponding to
628 // |eos_for_audio|. Verifies that playback completes and no further data
630 // If |send_eos| is false, then it is assumed that caller previously arranged
631 // for player to receive EOS for each stream, but the player has not yet
632 // decoded all of them. In this case, |eos_for_audio| is ignored.
633 void VerifyPlaybackCompletesOnEOSDecode(bool send_eos, bool eos_for_audio) {
634 int original_num_data_requests = demuxer_->num_data_requests();
636 player_.OnDemuxerDataAvailable(CreateEOSAck(eos_for_audio));
637 EXPECT_FALSE(manager_.playback_completed());
639 EXPECT_TRUE(manager_.playback_completed());
640 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests());
643 void VerifyCompletedPlaybackResumesOnSeekPlusStart(bool have_audio,
645 DCHECK(have_audio || have_video);
647 EXPECT_TRUE(manager_.playback_completed());
649 player_.SeekTo(base::TimeDelta());
650 player_.OnDemuxerSeekDone(kNoTimestamp());
651 Start(CreateDemuxerConfigs(have_audio, have_video), true);
654 // Starts the appropriate decoder jobs according to |have_audio| and
655 // |have_video|. Then starts seek during decode of EOS or non-EOS according to
656 // |eos_audio| and |eos_video|. Simulates seek completion and verifies that
657 // playback never completed. |eos_{audio,video}| is ignored if the
658 // corresponding |have_{audio,video}| is false.
659 void VerifySeekDuringEOSDecodePreventsPlaybackCompletion(bool have_audio,
663 DCHECK(have_audio || have_video);
666 CreateNextTextureAndSetVideoSurface();
668 Start(CreateDemuxerConfigs(have_audio, have_video), true);
671 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
674 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
676 // Run until more data is requested a number of times equal to the number of
677 // media types configured. Since prefetching may be in progress, we cannot
678 // reliably expect Run() to complete until we have sent demuxer data for all
679 // configured media types, above.
680 for (int i = 0; i < (have_audio ? 1 : 0) + (have_video ? 1 : 0); i++)
683 // Simulate seek while decoding EOS or non-EOS for the appropriate
687 player_.OnDemuxerDataAvailable(CreateEOSAck(true));
689 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
694 player_.OnDemuxerDataAvailable(CreateEOSAck(false));
696 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
699 player_.SeekTo(base::TimeDelta());
700 EXPECT_EQ(0, demuxer_->num_seek_requests());
701 WaitForDecodeDone(have_audio, have_video);
702 EXPECT_EQ(1, demuxer_->num_seek_requests());
704 player_.OnDemuxerSeekDone(kNoTimestamp());
705 EXPECT_FALSE(manager_.playback_completed());
708 base::TimeTicks StartTimeTicks() {
709 return player_.start_time_ticks_;
712 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid,
713 MediaDrmBridge::SecurityLevel security_level,
714 const std::string& container,
715 const std::vector<std::string>& codecs) {
716 return MediaSourcePlayer::IsTypeSupported(
717 scheme_uuid, security_level, container, codecs);
720 base::MessageLoop message_loop_;
721 MockMediaPlayerManager manager_;
722 MockDemuxerAndroid* demuxer_; // Owned by |player_|.
723 MediaSourcePlayer player_;
725 // Track whether a possibly async decoder callback test hook has run.
726 bool decoder_callback_hook_executed_;
728 // We need to keep the surface texture while the decoder is actively decoding.
729 // Otherwise, it may trigger unexpected crashes on some devices. To switch
730 // surfaces, tests need to create a new surface texture without releasing
731 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
732 // between two surface textures, only replacing the N-2 texture. Assumption is
733 // that no more than N-1 texture is in use by decoder when
734 // CreateNextTextureAndSetVideoSurface() is called.
735 scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
736 scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
737 bool surface_texture_a_is_next_;
738 int next_texture_id_;
740 DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayerTest);
743 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithValidConfig) {
744 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
746 // Test audio decoder job will be created when codec is successfully started.
747 StartAudioDecoderJob(true);
748 EXPECT_EQ(0, demuxer_->num_seek_requests());
751 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithInvalidConfig) {
752 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
754 // Test audio decoder job will not be created when failed to start the codec.
755 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis);
756 // Replace with invalid |audio_extra_data|
757 configs.audio_extra_data.clear();
758 uint8 invalid_codec_data[] = { 0x00, 0xff, 0xff, 0xff, 0xff };
759 configs.audio_extra_data.insert(configs.audio_extra_data.begin(),
760 invalid_codec_data, invalid_codec_data + 4);
761 Start(configs, false);
762 EXPECT_EQ(0, demuxer_->num_seek_requests());
765 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithValidSurface) {
766 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
768 // Test video decoder job will be created when surface is valid.
769 // Video decoder job will not be created until surface is available.
770 StartVideoDecoderJob(false);
772 // Set both an initial and a later video surface without receiving any
774 CreateNextTextureAndSetVideoSurface();
775 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
776 EXPECT_TRUE(first_job);
777 CreateNextTextureAndSetVideoSurface();
779 // Setting another surface will not create a new job until any pending
780 // read is satisfied (and job is no longer decoding).
781 EXPECT_EQ(first_job, GetMediaDecoderJob(false));
783 // No seeks, even on setting surface, should have occurred. (Browser seeks can
784 // occur on setting surface, but only after previously receiving video data.)
785 EXPECT_EQ(0, demuxer_->num_seek_requests());
787 // Note, the decoder job for the second surface set, above, will be created
788 // only after the pending read is satisfied and decoded, and the resulting
789 // browser seek is done. See BrowserSeek_* tests for this coverage.
792 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithInvalidSurface) {
793 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
795 // Test video decoder job will not be created when surface is invalid.
796 scoped_refptr<gfx::SurfaceTexture> surface_texture(
797 new gfx::SurfaceTexture(0));
798 gfx::ScopedJavaSurface surface(surface_texture.get());
799 StartVideoDecoderJob(false);
801 // Release the surface texture.
802 surface_texture = NULL;
803 player_.SetVideoSurface(surface.Pass());
805 // Player should not seek the demuxer on setting initial surface.
806 EXPECT_EQ(0, demuxer_->num_seek_requests());
808 EXPECT_FALSE(GetMediaDecoderJob(false));
809 EXPECT_EQ(0, demuxer_->num_data_requests());
812 TEST_F(MediaSourcePlayerTest, ReadFromDemuxerAfterSeek) {
813 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
815 // Test decoder job will resend a ReadFromDemuxer request after seek.
816 StartAudioDecoderJob(true);
817 SeekPlayerWithAbort(true, base::TimeDelta());
820 TEST_F(MediaSourcePlayerTest, SetSurfaceWhileSeeking) {
821 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
823 // Test SetVideoSurface() will not cause an extra seek while the player is
824 // waiting for demuxer to indicate seek is done.
825 // Player is still waiting for SetVideoSurface(), so no request is sent.
826 StartVideoDecoderJob(false); // Verifies no data requested.
828 // Initiate a seek. Skip requesting element seek of renderer.
829 // Instead behave as if the renderer has asked us to seek.
830 EXPECT_EQ(0, demuxer_->num_seek_requests());
831 player_.SeekTo(base::TimeDelta());
832 EXPECT_EQ(1, demuxer_->num_seek_requests());
834 CreateNextTextureAndSetVideoSurface();
835 EXPECT_FALSE(GetMediaDecoderJob(false));
836 EXPECT_EQ(1, demuxer_->num_seek_requests());
838 // Reconfirm player has not yet requested data.
839 EXPECT_EQ(0, demuxer_->num_data_requests());
841 // Send the seek done notification. The player should start requesting data.
842 player_.OnDemuxerSeekDone(kNoTimestamp());
843 EXPECT_TRUE(GetMediaDecoderJob(false));
844 EXPECT_EQ(1, demuxer_->num_data_requests());
846 // Reconfirm exactly 1 seek request has been made of demuxer, and that it
847 // was not a browser seek request.
848 EXPECT_EQ(1, demuxer_->num_seek_requests());
849 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
852 TEST_F(MediaSourcePlayerTest, ChangeMultipleSurfaceWhileDecoding) {
853 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
855 // Test MediaSourcePlayer can switch multiple surfaces during decoding.
856 CreateNextTextureAndSetVideoSurface();
857 StartVideoDecoderJob(true);
858 EXPECT_EQ(0, demuxer_->num_seek_requests());
860 // Send the first input chunk.
861 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
863 // While the decoder is decoding, change multiple surfaces. Pass an empty
865 gfx::ScopedJavaSurface empty_surface;
866 player_.SetVideoSurface(empty_surface.Pass());
867 // Next, pass a new non-empty surface.
868 CreateNextTextureAndSetVideoSurface();
870 // Wait for the decoder job to finish decoding and be reset pending a browser
872 while (GetMediaDecoderJob(false))
873 message_loop_.RunUntilIdle();
875 // Only one browser seek should have been initiated. No further data request
876 // should have been processed on |message_loop_| before surface change event
877 // became pending, above.
878 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
879 EXPECT_EQ(1, demuxer_->num_data_requests());
881 // Simulate browser seek is done and confirm player requests more data for new
882 // video decoder job.
883 player_.OnDemuxerSeekDone(player_.GetCurrentTime());
884 EXPECT_TRUE(GetMediaDecoderJob(false));
885 EXPECT_EQ(2, demuxer_->num_data_requests());
886 EXPECT_EQ(1, demuxer_->num_seek_requests());
889 TEST_F(MediaSourcePlayerTest, SetEmptySurfaceAndStarveWhileDecoding) {
890 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
892 // Test player pauses if an empty surface is passed.
893 CreateNextTextureAndSetVideoSurface();
894 StartVideoDecoderJob(true);
895 EXPECT_EQ(1, demuxer_->num_data_requests());
897 // Send the first input chunk.
898 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
900 // While the decoder is decoding, pass an empty surface.
901 gfx::ScopedJavaSurface empty_surface;
902 player_.SetVideoSurface(empty_surface.Pass());
904 // Let the player starve. However, it should not issue any new data request in
906 TriggerPlayerStarvation();
907 // Wait for the decoder job to finish decoding and be reset.
908 while (GetMediaDecoderJob(false))
909 message_loop_.RunUntilIdle();
911 // No further seek or data requests should have been received since the
913 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
914 EXPECT_EQ(1, demuxer_->num_data_requests());
916 // Playback resumes once a non-empty surface is passed.
917 CreateNextTextureAndSetVideoSurface();
918 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
921 TEST_F(MediaSourcePlayerTest, AudioOnlyStartAfterSeekFinish) {
922 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
924 // Test audio decoder job will not start until pending seek event is handled.
925 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis);
926 player_.OnDemuxerConfigsAvailable(configs);
927 EXPECT_FALSE(GetMediaDecoderJob(true));
929 // Initiate a seek. Skip requesting element seek of renderer.
930 // Instead behave as if the renderer has asked us to seek.
931 player_.SeekTo(base::TimeDelta());
932 EXPECT_EQ(1, demuxer_->num_seek_requests());
935 EXPECT_FALSE(GetMediaDecoderJob(true));
936 EXPECT_EQ(0, demuxer_->num_data_requests());
938 // Sending back the seek done notification.
939 player_.OnDemuxerSeekDone(kNoTimestamp());
940 EXPECT_TRUE(GetMediaDecoderJob(true));
941 EXPECT_EQ(1, demuxer_->num_data_requests());
943 // Reconfirm exactly 1 seek request has been made of demuxer.
944 EXPECT_EQ(1, demuxer_->num_seek_requests());
947 TEST_F(MediaSourcePlayerTest, VideoOnlyStartAfterSeekFinish) {
948 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
950 // Test video decoder job will not start until pending seek event is handled.
951 CreateNextTextureAndSetVideoSurface();
952 DemuxerConfigs configs = CreateVideoDemuxerConfigs();
953 player_.OnDemuxerConfigsAvailable(configs);
954 EXPECT_FALSE(GetMediaDecoderJob(false));
956 // Initiate a seek. Skip requesting element seek of renderer.
957 // Instead behave as if the renderer has asked us to seek.
958 player_.SeekTo(base::TimeDelta());
959 EXPECT_EQ(1, demuxer_->num_seek_requests());
962 EXPECT_FALSE(GetMediaDecoderJob(false));
963 EXPECT_EQ(0, demuxer_->num_data_requests());
965 // Sending back the seek done notification.
966 player_.OnDemuxerSeekDone(kNoTimestamp());
967 EXPECT_TRUE(GetMediaDecoderJob(false));
968 EXPECT_EQ(1, demuxer_->num_data_requests());
970 // Reconfirm exactly 1 seek request has been made of demuxer.
971 EXPECT_EQ(1, demuxer_->num_seek_requests());
974 TEST_F(MediaSourcePlayerTest, StartImmediatelyAfterPause) {
975 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
977 // Test that if the decoding job is not fully stopped after Pause(),
978 // calling Start() will be a noop.
979 StartAudioDecoderJob(true);
981 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
982 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
984 // Sending data to player.
985 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
986 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
988 // Decoder job will not immediately stop after Pause() since it is
989 // running on another thread.
991 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
993 // Nothing happens when calling Start() again.
995 // Verify that Start() will not destroy and recreate the decoder job.
996 EXPECT_EQ(decoder_job, GetMediaDecoderJob(true));
997 EXPECT_EQ(1, demuxer_->num_data_requests());
998 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1000 // The decoder job should finish and a new request will be sent.
1001 EXPECT_EQ(2, demuxer_->num_data_requests());
1002 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
1005 TEST_F(MediaSourcePlayerTest, DecoderJobsCannotStartWithoutAudio) {
1006 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1008 // Test that when Start() is called, video decoder jobs will wait for audio
1009 // decoder job before start decoding the data.
1010 CreateNextTextureAndSetVideoSurface();
1011 Start(CreateAudioVideoDemuxerConfigs(), true);
1012 MediaDecoderJob* audio_decoder_job = GetMediaDecoderJob(true);
1013 MediaDecoderJob* video_decoder_job = GetMediaDecoderJob(false);
1015 EXPECT_FALSE(audio_decoder_job->is_decoding());
1016 EXPECT_FALSE(video_decoder_job->is_decoding());
1018 // Sending video data to player, video decoder should not start.
1019 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1020 EXPECT_FALSE(video_decoder_job->is_decoding());
1022 // Sending audio data to player, both decoders should start now.
1023 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1024 EXPECT_TRUE(audio_decoder_job->is_decoding());
1025 EXPECT_TRUE(video_decoder_job->is_decoding());
1027 // No seeks should have occurred.
1028 EXPECT_EQ(0, demuxer_->num_seek_requests());
1031 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) {
1032 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1034 // Test start time ticks will reset after decoder job underruns.
1035 StartAudioDecoderJob(true);
1037 // For the first couple chunks, the decoder job may return
1038 // DECODE_FORMAT_CHANGED status instead of DECODE_SUCCEEDED status. Decode
1039 // more frames to guarantee that DECODE_SUCCEEDED will be returned.
1040 for (int i = 0; i < 4; ++i) {
1041 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i));
1042 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1043 message_loop_.Run();
1046 // The decoder job should finish and a new request will be sent.
1047 EXPECT_EQ(5, demuxer_->num_data_requests());
1048 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1049 base::TimeTicks previous = StartTimeTicks();
1051 // Let the decoder timeout and execute the OnDecoderStarved() callback.
1052 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
1054 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1055 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
1056 message_loop_.RunUntilIdle();
1058 // Send new data to the decoder so it can finish the currently
1060 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1061 WaitForAudioDecodeDone();
1063 // Verify the start time ticks is cleared at this point because the
1064 // player is prefetching.
1065 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks());
1067 // Send new data to the decoder so it can finish prefetching. This should
1068 // reset the start time ticks.
1069 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1070 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks());
1072 base::TimeTicks current = StartTimeTicks();
1073 EXPECT_LE(100.0, (current - previous).InMillisecondsF());
1076 TEST_F(MediaSourcePlayerTest, V_SecondAccessUnitIsEOSAndResumePlayAfterSeek) {
1077 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1079 // Test MediaSourcePlayer can replay video after input EOS is reached.
1080 CreateNextTextureAndSetVideoSurface();
1081 StartVideoDecoderJob(true);
1083 // Send the first input chunk.
1084 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1085 message_loop_.Run();
1087 VerifyPlaybackCompletesOnEOSDecode(true, false);
1088 VerifyCompletedPlaybackResumesOnSeekPlusStart(false, true);
1091 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitIsEOSAndResumePlayAfterSeek) {
1092 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1094 // Test decode of audio EOS buffer without any prior decode. See also
1095 // http://b/11696552.
1096 // Also tests that seeking+Start() after completing audio playback resumes
1098 Start(CreateAudioDemuxerConfigs(kCodecAAC), true);
1099 VerifyPlaybackCompletesOnEOSDecode(true, true);
1100 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, false);
1103 TEST_F(MediaSourcePlayerTest, V_FirstAccessUnitAfterSeekIsEOS) {
1104 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1106 // Test decode of video EOS buffer, just after seeking, without any prior
1107 // decode (other than the simulated |kAborted| resulting from the seek
1109 CreateNextTextureAndSetVideoSurface();
1110 StartVideoDecoderJob(true);
1111 SeekPlayerWithAbort(false, base::TimeDelta());
1112 VerifyPlaybackCompletesOnEOSDecode(true, false);
1115 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitAfterSeekIsEOS) {
1116 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1118 // Test decode of audio EOS buffer, just after seeking, without any prior
1119 // decode (other than the simulated |kAborted| resulting from the seek
1120 // process.) See also http://b/11696552.
1121 Start(CreateAudioDemuxerConfigs(kCodecAAC), true);
1122 SeekPlayerWithAbort(true, base::TimeDelta());
1123 VerifyPlaybackCompletesOnEOSDecode(true, true);
1126 TEST_F(MediaSourcePlayerTest, AV_PlaybackCompletionAcrossConfigChange) {
1127 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1129 // Test that if one stream (audio) has completed decode of EOS and the other
1130 // stream (video) processes config change, that subsequent video EOS completes
1132 // Also tests that seeking+Start() after completing playback resumes playback.
1133 CreateNextTextureAndSetVideoSurface();
1134 Start(CreateAudioVideoDemuxerConfigs(), true);
1136 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1137 EXPECT_EQ(0, demuxer_->num_config_requests());
1138 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1139 false, 0)); // Video |kConfigChanged| as first unit.
1141 WaitForAudioVideoDecodeDone();
1143 EXPECT_EQ(1, demuxer_->num_config_requests());
1144 EXPECT_EQ(2, demuxer_->num_data_requests());
1145 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1146 EXPECT_EQ(3, demuxer_->num_data_requests());
1148 // At no time after completing audio EOS decode, above, should the
1149 // audio decoder job resume decoding. Send and decode video EOS.
1150 VerifyPlaybackCompletesOnEOSDecode(true, false);
1151 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1154 TEST_F(MediaSourcePlayerTest, VA_PlaybackCompletionAcrossConfigChange) {
1155 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1157 // Test that if one stream (video) has completed decode of EOS and the other
1158 // stream (audio) processes config change, that subsequent audio EOS completes
1160 // Also tests that seeking+Start() after completing playback resumes playback.
1161 CreateNextTextureAndSetVideoSurface();
1162 Start(CreateAudioVideoDemuxerConfigs(), true);
1164 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1165 EXPECT_EQ(0, demuxer_->num_config_requests());
1166 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1167 true, 0)); // Audio |kConfigChanged| as first unit.
1169 WaitForAudioVideoDecodeDone();
1171 // TODO(wolenetz/qinmin): Prevent redundant demuxer config request and change
1172 // expectation to 1 here. See http://crbug.com/325528.
1173 EXPECT_EQ(2, demuxer_->num_config_requests());
1174 EXPECT_EQ(2, demuxer_->num_data_requests());
1175 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1176 EXPECT_EQ(3, demuxer_->num_data_requests());
1178 // At no time after completing video EOS decode, above, should the
1179 // video decoder job resume decoding. Send and decode audio EOS.
1180 VerifyPlaybackCompletesOnEOSDecode(true, true);
1181 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1184 TEST_F(MediaSourcePlayerTest, AV_NoPrefetchForFinishedVideoOnAudioStarvation) {
1185 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1187 // Test that if one stream (video) has completed decode of EOS, prefetch
1188 // resulting from player starvation occurs only for the other stream (audio),
1189 // and responding to that prefetch with EOS completes A/V playback, even if
1190 // another starvation occurs during the latter EOS's decode.
1191 CreateNextTextureAndSetVideoSurface();
1192 Start(CreateAudioVideoDemuxerConfigs(), true);
1194 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1195 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1197 // Wait until video EOS is processed and more data (assumed to be audio) is
1199 while (demuxer_->num_data_requests() < 3)
1200 message_loop_.RunUntilIdle();
1201 WaitForVideoDecodeDone();
1202 EXPECT_EQ(3, demuxer_->num_data_requests());
1204 // Simulate decoder underrun to trigger prefetch while still decoding audio.
1205 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
1206 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding() &&
1207 !GetMediaDecoderJob(false)->is_decoding());
1208 TriggerPlayerStarvation();
1210 // Complete the audio decode that was in progress when simulated player
1211 // starvation was triggered.
1212 WaitForAudioDecodeDone();
1213 EXPECT_EQ(4, demuxer_->num_data_requests());
1215 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1216 EXPECT_FALSE(GetMediaDecoderJob(false)->is_decoding());
1217 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1219 // Simulate another decoder underrun to trigger prefetch while decoding EOS.
1220 TriggerPlayerStarvation();
1221 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1224 TEST_F(MediaSourcePlayerTest, V_StarvationDuringEOSDecode) {
1225 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1227 // Test that video-only playback completes without further data requested when
1228 // starvation occurs during EOS decode.
1229 CreateNextTextureAndSetVideoSurface();
1230 StartVideoDecoderJob(true);
1231 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo());
1232 message_loop_.Run();
1234 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1235 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1236 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1237 TriggerPlayerStarvation();
1238 VerifyPlaybackCompletesOnEOSDecode(false, false /* ignored */);
1241 TEST_F(MediaSourcePlayerTest, A_StarvationDuringEOSDecode) {
1242 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1244 // Test that audio-only playback completes without further data requested when
1245 // starvation occurs during EOS decode.
1246 StartAudioDecoderJob(true);
1247 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1248 message_loop_.Run();
1250 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1251 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1252 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1253 TriggerPlayerStarvation();
1254 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1257 TEST_F(MediaSourcePlayerTest, AV_SeekDuringEOSDecodePreventsCompletion) {
1258 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1260 // Test that seek supercedes audio+video playback completion on simultaneous
1261 // audio and video EOS decode, if SeekTo() occurs during these EOS decodes.
1262 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, true);
1265 TEST_F(MediaSourcePlayerTest, AV_SeekDuringAudioEOSDecodePreventsCompletion) {
1266 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1268 // Test that seek supercedes audio+video playback completion on simultaneous
1269 // audio EOS and video non-EOS decode, if SeekTo() occurs during these
1271 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, false);
1274 TEST_F(MediaSourcePlayerTest, AV_SeekDuringVideoEOSDecodePreventsCompletion) {
1275 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1277 // Test that seek supercedes audio+video playback completion on simultaneous
1278 // audio non-EOS and video EOS decode, if SeekTo() occurs during these
1280 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, false, true);
1283 TEST_F(MediaSourcePlayerTest, V_SeekDuringEOSDecodePreventsCompletion) {
1284 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1286 // Test that seek supercedes video-only playback completion on EOS decode, if
1287 // SeekTo() occurs during EOS decode.
1288 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(false, true, false, true);
1291 TEST_F(MediaSourcePlayerTest, A_SeekDuringEOSDecodePreventsCompletion) {
1292 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1294 // Test that seek supercedes audio-only playback completion on EOS decode, if
1295 // SeekTo() occurs during EOS decode.
1296 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, false, true, false);
1299 TEST_F(MediaSourcePlayerTest, NoRequestForDataAfterAbort) {
1300 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1302 // Test that the decoder will not request new data after receiving an aborted
1304 StartAudioDecoderJob(true);
1306 // Send an aborted access unit.
1307 player_.OnDemuxerDataAvailable(CreateAbortedAck(true));
1308 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1309 WaitForAudioDecodeDone();
1311 // No request will be sent for new data.
1312 EXPECT_EQ(1, demuxer_->num_data_requests());
1314 // No seek requests should have occurred.
1315 EXPECT_EQ(0, demuxer_->num_seek_requests());
1318 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) {
1319 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1321 // Test that the decoder should not crash if demuxer data arrives after
1323 StartAudioDecoderJob(true);
1326 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1328 // The decoder job should have been released.
1329 EXPECT_FALSE(player_.IsPlaying());
1331 // No further data should have been requested.
1332 EXPECT_EQ(1, demuxer_->num_data_requests());
1334 // No seek requests should have occurred.
1335 EXPECT_EQ(0, demuxer_->num_seek_requests());
1338 TEST_F(MediaSourcePlayerTest, BrowserSeek_RegularSeekPendsBrowserSeekDone) {
1339 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1341 // Test that a browser seek, once started, delays a newly arrived regular
1342 // SeekTo() request's demuxer seek until the browser seek is done.
1343 BrowserSeekPlayer(false);
1345 // Simulate renderer requesting a regular seek while browser seek in progress.
1346 player_.SeekTo(base::TimeDelta());
1347 EXPECT_FALSE(GetMediaDecoderJob(false));
1349 // Simulate browser seek is done. Confirm player requests the regular seek,
1350 // still has no video decoder job configured, and has not requested any
1351 // further data since the surface change event became pending in
1352 // BrowserSeekPlayer().
1353 EXPECT_EQ(1, demuxer_->num_seek_requests());
1354 player_.OnDemuxerSeekDone(base::TimeDelta());
1355 EXPECT_FALSE(GetMediaDecoderJob(false));
1356 EXPECT_EQ(2, demuxer_->num_seek_requests());
1357 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
1358 EXPECT_EQ(1, demuxer_->num_data_requests());
1360 // Simulate regular seek is done and confirm player requests more data for
1361 // new video decoder job.
1362 player_.OnDemuxerSeekDone(kNoTimestamp());
1363 EXPECT_TRUE(GetMediaDecoderJob(false));
1364 EXPECT_EQ(2, demuxer_->num_data_requests());
1365 EXPECT_EQ(2, demuxer_->num_seek_requests());
1368 TEST_F(MediaSourcePlayerTest, NoSeekForInitialReleaseAndStart) {
1369 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1371 // Test that no seek is requested if player Release() + Start() occurs prior
1372 // to receiving any data.
1373 CreateNextTextureAndSetVideoSurface();
1374 StartVideoDecoderJob(true);
1377 // Pass a new non-empty surface.
1378 CreateNextTextureAndSetVideoSurface();
1382 // TODO(wolenetz/qinmin): Multiple in-flight data requests for same stream
1383 // should be prevented. See http://crbug.com/306314.
1384 EXPECT_EQ(2, demuxer_->num_data_requests());
1385 EXPECT_TRUE(GetMediaDecoderJob(false));
1387 EXPECT_EQ(0, demuxer_->num_seek_requests());
1390 TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) {
1391 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1393 // Test that one browser seek is requested if player Release() + Start(), with
1394 // video data received between Release() and Start().
1395 BrowserSeekPlayer(true);
1396 EXPECT_EQ(1, demuxer_->num_data_requests());
1398 // Simulate browser seek is done and confirm player requests more data.
1399 player_.OnDemuxerSeekDone(base::TimeDelta());
1400 EXPECT_TRUE(GetMediaDecoderJob(false));
1401 EXPECT_EQ(2, demuxer_->num_data_requests());
1402 EXPECT_EQ(1, demuxer_->num_seek_requests());
1405 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) {
1406 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1408 // Test decoder job will preroll the media to the seek position.
1409 StartAudioDecoderJob(true);
1411 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1412 EXPECT_TRUE(IsPrerolling(true));
1413 PrerollDecoderToTime(
1414 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1417 TEST_F(MediaSourcePlayerTest, PrerollVideoAfterSeek) {
1418 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1420 // Test decoder job will preroll the media to the seek position.
1421 CreateNextTextureAndSetVideoSurface();
1422 StartVideoDecoderJob(true);
1424 SeekPlayerWithAbort(false, base::TimeDelta::FromMilliseconds(100));
1425 EXPECT_TRUE(IsPrerolling(false));
1426 PrerollDecoderToTime(
1427 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1430 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) {
1431 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1433 // Test decoder job will begin prerolling upon seek, when it was not
1434 // prerolling prior to the seek.
1435 StartAudioDecoderJob(true);
1436 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
1437 EXPECT_TRUE(IsPrerolling(true));
1439 // Complete the initial preroll by feeding data to the decoder.
1440 for (int i = 0; i < 4; ++i) {
1441 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(i));
1442 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1443 message_loop_.Run();
1445 EXPECT_LT(0.0, player_.GetCurrentTime().InMillisecondsF());
1446 EXPECT_FALSE(IsPrerolling(true));
1448 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500));
1450 // Prerolling should have begun again.
1451 EXPECT_TRUE(IsPrerolling(true));
1452 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF());
1454 // Send data at and after the seek position. Prerolling should complete.
1455 for (int i = 0; i < 4; ++i) {
1456 DemuxerData data = CreateReadFromDemuxerAckForAudio(i);
1457 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(
1458 500 + 30 * (i - 1));
1459 player_.OnDemuxerDataAvailable(data);
1460 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1461 message_loop_.Run();
1463 EXPECT_LT(500.0, player_.GetCurrentTime().InMillisecondsF());
1464 EXPECT_FALSE(IsPrerolling(true));
1466 // Throughout this test, we should have not re-created the decoder job, so
1467 // IsPrerolling() transition from false to true was not due to constructor
1468 // initialization. It was due to BeginPrerolling().
1469 EXPECT_EQ(decoder_job, GetMediaDecoderJob(true));
1472 TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossReleaseAndStart) {
1473 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1475 // Test decoder job will resume media prerolling if interrupted by Release()
1477 StartAudioDecoderJob(true);
1479 base::TimeDelta target_timestamp = base::TimeDelta::FromMilliseconds(100);
1480 SeekPlayerWithAbort(true, target_timestamp);
1481 EXPECT_TRUE(IsPrerolling(true));
1482 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1484 // Send some data before the seek position.
1485 // Test uses 'large' number of iterations because decoder job may not get
1486 // MEDIA_CODEC_OK output status until after a few dequeue output attempts.
1487 // This allows decoder status to stabilize prior to AU timestamp reaching
1488 // the preroll target.
1490 for (int i = 0; i < 10; ++i) {
1491 data = CreateReadFromDemuxerAckForAudio(3);
1492 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(i * 10);
1494 // While still prerolling, Release() and Start() the player.
1495 // TODO(qinmin): Simulation of multiple in-flight data requests (one from
1496 // before Release(), one from after Start()) is not included here, and
1497 // neither is any data enqueued for later decode if it arrives after
1498 // Release() and before Start(). See http://crbug.com/306314. Assumption
1499 // for this test, to prevent flakiness until the bug is fixed, is the
1500 // first request's data arrives before Start(). Though that data is not
1501 // seen by decoder, this assumption allows preroll continuation
1502 // verification and prevents multiple in-flight data requests.
1504 player_.OnDemuxerDataAvailable(data);
1505 message_loop_.RunUntilIdle();
1506 EXPECT_FALSE(GetMediaDecoderJob(true));
1507 StartAudioDecoderJob(true);
1509 player_.OnDemuxerDataAvailable(data);
1510 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1511 message_loop_.Run();
1513 EXPECT_TRUE(IsPrerolling(true));
1515 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1516 EXPECT_TRUE(IsPrerolling(true));
1518 // Send data after the seek position.
1519 PrerollDecoderToTime(true, target_timestamp, target_timestamp);
1522 TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossConfigChange) {
1523 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1525 // Test decoder job will resume media prerolling if interrupted by
1526 // |kConfigChanged| and OnDemuxerConfigsAvailable().
1527 StartAudioDecoderJob(true);
1529 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1530 EXPECT_TRUE(IsPrerolling(true));
1531 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1533 // In response to data request, simulate that demuxer signals config change by
1534 // sending an AU with |kConfigChanged|. Player should prepare to reconfigure
1535 // the audio decoder job, and should request new demuxer configs.
1536 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(true, 0);
1537 EXPECT_EQ(0, demuxer_->num_config_requests());
1538 player_.OnDemuxerDataAvailable(data);
1539 EXPECT_EQ(1, demuxer_->num_config_requests());
1541 // Simulate arrival of new configs.
1542 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis));
1544 PrerollDecoderToTime(
1545 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1548 TEST_F(MediaSourcePlayerTest, SimultaneousAudioVideoConfigChange) {
1549 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1551 // Test that the player allows simultaneous audio and video config change,
1552 // such as might occur during OnPrefetchDone() if next access unit for both
1553 // audio and video jobs is |kConfigChanged|.
1554 CreateNextTextureAndSetVideoSurface();
1555 Start(CreateAudioVideoDemuxerConfigs(), true);
1556 MediaDecoderJob* first_audio_job = GetMediaDecoderJob(true);
1557 MediaDecoderJob* first_video_job = GetMediaDecoderJob(false);
1559 // Simulate audio |kConfigChanged| prefetched as standalone access unit.
1560 player_.OnDemuxerDataAvailable(
1561 CreateReadFromDemuxerAckWithConfigChanged(true, 0));
1562 EXPECT_EQ(0, demuxer_->num_config_requests()); // No OnPrefetchDone() yet.
1564 // Simulate video |kConfigChanged| prefetched as standalone access unit.
1565 player_.OnDemuxerDataAvailable(
1566 CreateReadFromDemuxerAckWithConfigChanged(false, 0));
1567 EXPECT_EQ(1, demuxer_->num_config_requests()); // OnPrefetchDone() occurred.
1568 EXPECT_EQ(2, demuxer_->num_data_requests()); // No more data requested yet.
1570 // No job re-creation should occur until the requested configs arrive.
1571 EXPECT_EQ(first_audio_job, GetMediaDecoderJob(true));
1572 EXPECT_EQ(first_video_job, GetMediaDecoderJob(false));
1574 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs());
1575 EXPECT_EQ(4, demuxer_->num_data_requests());
1576 MediaDecoderJob* second_audio_job = GetMediaDecoderJob(true);
1577 MediaDecoderJob* second_video_job = GetMediaDecoderJob(false);
1578 EXPECT_NE(first_audio_job, second_audio_job);
1579 EXPECT_NE(first_video_job, second_video_job);
1580 EXPECT_TRUE(second_audio_job && second_video_job);
1582 // Confirm no further demuxer configs requested.
1583 EXPECT_EQ(1, demuxer_->num_config_requests());
1586 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInPrefetchUnit0) {
1587 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1589 // Test that the player detects need for and requests demuxer configs if
1590 // the |kConfigChanged| unit is the very first unit in the set of units
1591 // received in OnDemuxerDataAvailable() ostensibly while
1592 // |PREFETCH_DONE_EVENT_PENDING|.
1593 StartConfigChange(true, true, 0);
1596 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInPrefetchUnit1) {
1597 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1599 // Test that the player detects need for and requests demuxer configs if
1600 // the |kConfigChanged| unit is not the first unit in the set of units
1601 // received in OnDemuxerDataAvailable() ostensibly while
1602 // |PREFETCH_DONE_EVENT_PENDING|.
1603 StartConfigChange(true, true, 1);
1606 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInUnit0AfterPrefetch) {
1607 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1609 // Test that the player detects need for and requests demuxer configs if
1610 // the |kConfigChanged| unit is the very first unit in the set of units
1611 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1613 StartConfigChange(true, false, 0);
1616 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInUnit1AfterPrefetch) {
1617 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1619 // Test that the player detects need for and requests demuxer configs if
1620 // the |kConfigChanged| unit is not the first unit in the set of units
1621 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1623 StartConfigChange(true, false, 1);
1626 TEST_F(MediaSourcePlayerTest, BrowserSeek_PrerollAfterBrowserSeek) {
1627 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1629 // Test decoder job will preroll the media to the actual seek position
1630 // resulting from a browser seek.
1631 BrowserSeekPlayer(false);
1633 // Simulate browser seek is done, but to a later time than was requested.
1634 EXPECT_LT(player_.GetCurrentTime().InMillisecondsF(), 100);
1635 player_.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100));
1636 EXPECT_TRUE(GetMediaDecoderJob(false));
1637 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1638 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1639 EXPECT_EQ(2, demuxer_->num_data_requests());
1641 PrerollDecoderToTime(
1642 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100));
1645 TEST_F(MediaSourcePlayerTest, VideoDemuxerConfigChange) {
1646 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1648 // Test that video config change notification results in request for demuxer
1649 // configuration, and that a video decoder job results without any browser
1650 // seek necessary once the new demuxer config arrives.
1651 StartConfigChange(false, true, 1);
1652 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
1653 EXPECT_TRUE(first_job);
1654 EXPECT_EQ(1, demuxer_->num_data_requests());
1655 EXPECT_EQ(1, demuxer_->num_config_requests());
1657 // Simulate arrival of new configs.
1658 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1660 // New video decoder job should have been created and configured, without any
1662 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1663 EXPECT_TRUE(second_job);
1664 EXPECT_NE(first_job, second_job);
1665 EXPECT_EQ(2, demuxer_->num_data_requests());
1666 EXPECT_EQ(1, demuxer_->num_config_requests());
1667 EXPECT_EQ(0, demuxer_->num_seek_requests());
1670 TEST_F(MediaSourcePlayerTest, VideoConfigChangeContinuesAcrossSeek) {
1671 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1673 // Test if a demuxer config request is pending (due to previously receiving
1674 // |kConfigChanged|), and a seek request arrives prior to demuxer configs,
1675 // then seek is processed first, followed by the decoder config change.
1676 // This assumes the demuxer sends |kConfigChanged| read response prior to
1677 // canceling any reads pending seek; no |kAborted| is involved in this test.
1678 StartConfigChange(false, false, 1);
1679 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
1680 EXPECT_TRUE(first_job);
1681 EXPECT_EQ(1, demuxer_->num_config_requests());
1682 EXPECT_EQ(2, demuxer_->num_data_requests());
1683 EXPECT_EQ(0, demuxer_->num_seek_requests());
1685 player_.SeekTo(base::TimeDelta::FromMilliseconds(100));
1687 // Verify that the seek is requested immediately.
1688 EXPECT_EQ(1, demuxer_->num_seek_requests());
1690 // Simulate unlikely delayed arrival of the demuxer configs, completing the
1692 // TODO(wolenetz): Is it even possible for requested demuxer configs to be
1693 // delayed until after a SeekTo request arrives?
1694 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1696 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1697 EXPECT_NE(first_job, second_job);
1698 EXPECT_TRUE(second_job);
1700 // Send back the seek done notification. This should finish the seek and
1701 // trigger the player to request more data.
1702 EXPECT_EQ(2, demuxer_->num_data_requests());
1703 player_.OnDemuxerSeekDone(kNoTimestamp());
1704 EXPECT_EQ(3, demuxer_->num_data_requests());
1707 TEST_F(MediaSourcePlayerTest, NewSurfaceWhileChangingConfigs) {
1708 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1710 // Test that no seek or duplicated demuxer config request results from a
1711 // SetVideoSurface() that occurs while the player is expecting new demuxer
1712 // configs. This test may be good to keep beyond browser seek hack.
1713 StartConfigChange(false, false, 1);
1714 MediaDecoderJob* first_job = GetMediaDecoderJob(false);
1715 EXPECT_TRUE(first_job);
1716 EXPECT_EQ(1, demuxer_->num_config_requests());
1717 EXPECT_EQ(2, demuxer_->num_data_requests());
1719 CreateNextTextureAndSetVideoSurface();
1721 // Surface change processing (including decoder job re-creation) should
1722 // not occur until the pending video config change is completed.
1723 EXPECT_EQ(first_job, GetMediaDecoderJob(false));
1725 player_.OnDemuxerConfigsAvailable(CreateVideoDemuxerConfigs());
1726 MediaDecoderJob* second_job = GetMediaDecoderJob(false);
1727 EXPECT_NE(first_job, second_job);
1728 EXPECT_TRUE(second_job);
1730 EXPECT_EQ(3, demuxer_->num_data_requests());
1731 EXPECT_EQ(1, demuxer_->num_config_requests());
1732 EXPECT_EQ(0, demuxer_->num_seek_requests());
1735 TEST_F(MediaSourcePlayerTest,
1736 BrowserSeek_DecoderStarvationWhilePendingSurfaceChange) {
1737 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1739 // Test video decoder starvation while handling a pending surface change
1740 // should not cause any crashes.
1741 CreateNextTextureAndSetVideoSurface();
1742 StartVideoDecoderJob(true);
1743 DemuxerData data = CreateReadFromDemuxerAckForVideo();
1744 player_.OnDemuxerDataAvailable(data);
1746 // Trigger a surface change and decoder starvation.
1747 CreateNextTextureAndSetVideoSurface();
1748 TriggerPlayerStarvation();
1749 WaitForVideoDecodeDone();
1751 // Surface change should trigger a seek.
1752 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
1753 player_.OnDemuxerSeekDone(base::TimeDelta());
1754 EXPECT_TRUE(GetMediaDecoderJob(false));
1756 // A new data request should be sent.
1757 EXPECT_EQ(2, demuxer_->num_data_requests());
1760 TEST_F(MediaSourcePlayerTest, ReleaseWithOnPrefetchDoneAlreadyPosted) {
1761 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1763 // Test if OnPrefetchDone() had already been posted before and is executed
1764 // after Release(), then player does not DCHECK. This test is fragile to
1765 // change to MediaDecoderJob::Prefetch() implementation; it assumes task
1766 // is posted to run |prefetch_cb| if the job already HasData().
1767 // TODO(wolenetz): Remove MSP::set_decode_callback_for_testing() if this test
1768 // becomes obsolete. See http://crbug.com/304234.
1769 StartAudioDecoderJob(true);
1771 // Escape the original prefetch by decoding a single access unit.
1772 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1773 message_loop_.Run();
1775 // Prime the job with a few more access units, so that a later prefetch,
1776 // triggered by starvation to simulate decoder underrun, can trivially
1777 // post task to run OnPrefetchDone().
1778 player_.OnDemuxerDataAvailable(
1779 CreateReadFromDemuxerAckWithConfigChanged(true, 4));
1780 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1782 // Simulate decoder underrun, so trivial prefetch starts while still decoding.
1783 // The prefetch and posting of OnPrefetchDone() will not occur until next
1784 // MediaDecoderCallBack() occurs.
1785 TriggerPlayerStarvation();
1787 // Upon the next successful decode callback, post a task to call Release() on
1788 // the |player_|, such that the trivial OnPrefetchDone() task posting also
1789 // occurs and should execute after the Release().
1790 OnNextTestDecodeCallbackPostTaskToReleasePlayer();
1792 while (GetMediaDecoderJob(true))
1793 message_loop_.RunUntilIdle();
1794 EXPECT_TRUE(decoder_callback_hook_executed_);
1795 EXPECT_EQ(2, demuxer_->num_data_requests());
1797 // Player should have no decoder job until after Start().
1798 StartAudioDecoderJob(true);
1801 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekAndDone) {
1802 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1804 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1805 // has not yet been sent, then the seek request is sent after Release(). Also,
1806 // test if OnDemuxerSeekDone() occurs prior to next Start(), then the player
1807 // will resume correct post-seek preroll upon Start().
1808 StartAudioDecoderJobAndSeekToWhileDecoding(
1809 base::TimeDelta::FromMilliseconds(100));
1811 EXPECT_EQ(1, demuxer_->num_seek_requests());
1813 player_.OnDemuxerSeekDone(kNoTimestamp());
1814 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1815 EXPECT_FALSE(GetMediaDecoderJob(true));
1816 EXPECT_FALSE(player_.IsPlaying());
1818 // Player should begin prefetch and resume preroll upon Start().
1819 EXPECT_EQ(1, demuxer_->num_data_requests());
1820 StartAudioDecoderJob(true);
1821 EXPECT_TRUE(IsPrerolling(true));
1822 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1824 // No further seek should have been requested since Release(), above.
1825 EXPECT_EQ(1, demuxer_->num_seek_requests());
1828 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekThenStart) {
1829 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1831 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
1832 // has not yet been sent, then the seek request is sent after Release(). Also,
1833 // test if OnDemuxerSeekDone() does not occur until after the next Start(),
1834 // then the player remains pending seek done until (and resumes correct
1835 // post-seek preroll after) OnDemuxerSeekDone().
1836 StartAudioDecoderJobAndSeekToWhileDecoding(
1837 base::TimeDelta::FromMilliseconds(100));
1839 EXPECT_EQ(1, demuxer_->num_seek_requests());
1841 // Player should not prefetch upon Start() nor create the decoder job, due to
1842 // awaiting DemuxerSeekDone.
1843 EXPECT_EQ(1, demuxer_->num_data_requests());
1844 StartAudioDecoderJob(false);
1846 player_.OnDemuxerSeekDone(kNoTimestamp());
1847 EXPECT_TRUE(GetMediaDecoderJob(true));
1848 EXPECT_TRUE(IsPrerolling(true));
1849 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1850 EXPECT_EQ(2, demuxer_->num_data_requests());
1852 // No further seek should have been requested since Release(), above.
1853 EXPECT_EQ(1, demuxer_->num_seek_requests());
1856 TEST_F(MediaSourcePlayerTest, SeekToThenDemuxerSeekThenReleaseThenSeekDone) {
1857 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1859 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC
1860 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the
1861 // player will resume correct post-seek preroll upon Start().
1862 StartAudioDecoderJobAndSeekToWhileDecoding(
1863 base::TimeDelta::FromMilliseconds(100));
1864 WaitForAudioDecodeDone();
1865 EXPECT_EQ(1, demuxer_->num_seek_requests());
1868 player_.OnDemuxerSeekDone(kNoTimestamp());
1869 EXPECT_FALSE(player_.IsPlaying());
1870 EXPECT_FALSE(GetMediaDecoderJob(true));
1871 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1873 // Player should begin prefetch and resume preroll upon Start().
1874 EXPECT_EQ(1, demuxer_->num_data_requests());
1875 StartAudioDecoderJob(true);
1876 EXPECT_TRUE(IsPrerolling(true));
1877 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1879 // No further seek should have been requested since before Release(), above.
1880 EXPECT_EQ(1, demuxer_->num_seek_requests());
1883 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenStart) {
1884 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1886 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC
1887 // request and OnDemuxerSeekDone() does not occur until after the next
1888 // Start(), then the player remains pending seek done until (and resumes
1889 // correct post-seek preroll after) OnDemuxerSeekDone().
1890 StartAudioDecoderJobAndSeekToWhileDecoding(
1891 base::TimeDelta::FromMilliseconds(100));
1892 WaitForAudioDecodeDone();
1893 EXPECT_EQ(1, demuxer_->num_seek_requests());
1896 EXPECT_EQ(1, demuxer_->num_data_requests());
1897 StartAudioDecoderJob(false);
1899 player_.OnDemuxerSeekDone(kNoTimestamp());
1900 EXPECT_TRUE(GetMediaDecoderJob(true));
1901 EXPECT_TRUE(IsPrerolling(true));
1902 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1903 EXPECT_EQ(2, demuxer_->num_data_requests());
1905 // No further seek should have been requested since before Release(), above.
1906 EXPECT_EQ(1, demuxer_->num_seek_requests());
1909 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenConfigsAvailable) {
1910 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1912 // Test if Release() occurs after |kConfigChanged| detected, new configs
1913 // requested of demuxer, and the requested configs arrive before the next
1914 // Start(), then the player completes the pending config change processing on
1916 StartConfigChange(true, true, 0);
1919 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis));
1920 EXPECT_FALSE(GetMediaDecoderJob(true));
1921 EXPECT_FALSE(player_.IsPlaying());
1922 EXPECT_EQ(1, demuxer_->num_data_requests());
1924 // Player should resume upon Start(), even without further configs supplied.
1926 EXPECT_TRUE(GetMediaDecoderJob(true));
1927 EXPECT_TRUE(player_.IsPlaying());
1928 EXPECT_EQ(2, demuxer_->num_data_requests());
1930 // No further config request should have occurred since StartConfigChange().
1931 EXPECT_EQ(1, demuxer_->num_config_requests());
1934 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenStart) {
1935 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1937 // Test if Release() occurs after |kConfigChanged| detected, new configs
1938 // requested of demuxer, and the requested configs arrive after the next
1939 // Start(), then the player pends job creation until the new configs arrive.
1940 StartConfigChange(true, true, 0);
1944 EXPECT_TRUE(player_.IsPlaying());
1945 EXPECT_FALSE(GetMediaDecoderJob(true));
1946 EXPECT_EQ(1, demuxer_->num_data_requests());
1948 player_.OnDemuxerConfigsAvailable(CreateAudioDemuxerConfigs(kCodecVorbis));
1949 EXPECT_TRUE(GetMediaDecoderJob(true));
1950 EXPECT_EQ(2, demuxer_->num_data_requests());
1952 // No further config request should have occurred since StartConfigChange().
1953 EXPECT_EQ(1, demuxer_->num_config_requests());
1956 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenDemuxerSeekDone) {
1957 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1959 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
1960 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() occurs
1961 // before the next Start()+SetVideoSurface(), then the player will resume
1962 // correct post-seek preroll upon Start()+SetVideoSurface().
1963 BrowserSeekPlayer(false);
1964 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
1967 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
1968 EXPECT_FALSE(player_.IsPlaying());
1969 EXPECT_FALSE(GetMediaDecoderJob(false));
1970 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1972 // Player should begin prefetch and resume preroll upon Start().
1973 EXPECT_EQ(1, demuxer_->num_data_requests());
1974 CreateNextTextureAndSetVideoSurface();
1975 StartVideoDecoderJob(true);
1976 EXPECT_TRUE(IsPrerolling(false));
1977 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
1978 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
1980 // No further seek should have been requested since BrowserSeekPlayer().
1981 EXPECT_EQ(1, demuxer_->num_seek_requests());
1984 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenStart) {
1985 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1987 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
1988 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
1989 // occur until after the next Start()+SetVideoSurface(), then the player
1990 // remains pending seek done until (and resumes correct post-seek preroll
1991 // after) OnDemuxerSeekDone().
1992 BrowserSeekPlayer(false);
1993 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
1996 EXPECT_EQ(1, demuxer_->num_data_requests());
1997 CreateNextTextureAndSetVideoSurface();
1998 StartVideoDecoderJob(false);
2000 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
2001 EXPECT_TRUE(GetMediaDecoderJob(false));
2002 EXPECT_TRUE(IsPrerolling(false));
2003 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
2004 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
2005 EXPECT_EQ(2, demuxer_->num_data_requests());
2007 // No further seek should have been requested since BrowserSeekPlayer().
2008 EXPECT_EQ(1, demuxer_->num_seek_requests());
2011 // TODO(xhwang): Once we add tests to cover DrmBridge, update this test to
2012 // also verify that the job is successfully created if SetDrmBridge(), Start()
2013 // and eventually OnMediaCrypto() occur. This would increase test coverage of
2014 // http://crbug.com/313470 and allow us to remove inspection of internal player
2015 // pending event state. See http://crbug.com/313860.
2016 TEST_F(MediaSourcePlayerTest, SurfaceChangeClearedEvenIfMediaCryptoAbsent) {
2017 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2019 // Test that |SURFACE_CHANGE_EVENT_PENDING| is not pending after
2020 // SetVideoSurface() for a player configured for encrypted video, when the
2021 // player has not yet received media crypto.
2022 DemuxerConfigs configs = CreateVideoDemuxerConfigs();
2023 configs.is_video_encrypted = true;
2025 player_.OnDemuxerConfigsAvailable(configs);
2026 CreateNextTextureAndSetVideoSurface();
2027 EXPECT_FALSE(IsPendingSurfaceChange());
2028 EXPECT_FALSE(GetMediaDecoderJob(false));
2031 // TODO(xhwang): Enable this test when the test devices are updated.
2032 TEST_F(MediaSourcePlayerTest, DISABLED_IsTypeSupported_Widevine) {
2033 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
2034 VLOG(0) << "Could not run test - not supported on device.";
2038 uint8 kWidevineUUID[] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,
2039 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED };
2041 std::vector<uint8> widevine_uuid(kWidevineUUID,
2042 kWidevineUUID + arraysize(kWidevineUUID));
2044 // We test "L3" fully. But for "L1" we don't check the result as it depend on
2045 // whether the test device supports "L1" decoding.
2047 std::vector<std::string> codec_avc(1, "avc1");
2048 std::vector<std::string> codec_aac(1, "mp4a");
2049 std::vector<std::string> codec_avc_aac(1, "avc1");
2050 codec_avc_aac.push_back("mp4a");
2052 EXPECT_TRUE(IsTypeSupported(widevine_uuid, kL3, kVideoMp4, codec_avc));
2053 IsTypeSupported(widevine_uuid, kL1, kVideoMp4, codec_avc);
2055 // TODO(xhwang): L1/L3 doesn't apply to audio, so the result is messy.
2056 // Clean this up after we have a solution to specifying decoding mode.
2057 EXPECT_TRUE(IsTypeSupported(widevine_uuid, kL3, kAudioMp4, codec_aac));
2058 IsTypeSupported(widevine_uuid, kL1, kAudioMp4, codec_aac);
2060 EXPECT_TRUE(IsTypeSupported(widevine_uuid, kL3, kVideoMp4, codec_avc_aac));
2061 IsTypeSupported(widevine_uuid, kL1, kVideoMp4, codec_avc_aac);
2063 std::vector<std::string> codec_vp8(1, "vp8");
2064 std::vector<std::string> codec_vorbis(1, "vorbis");
2065 std::vector<std::string> codec_vp8_vorbis(1, "vp8");
2066 codec_vp8_vorbis.push_back("vorbis");
2068 // TODO(xhwang): WebM is actually not supported but currently
2069 // MediaDrmBridge.isCryptoSchemeSupported() doesn't check the container type.
2070 // Fix isCryptoSchemeSupported() and update this test as necessary.
2071 EXPECT_TRUE(IsTypeSupported(widevine_uuid, kL3, kVideoWebM, codec_vp8));
2072 IsTypeSupported(widevine_uuid, kL1, kVideoWebM, codec_vp8);
2074 // TODO(xhwang): L1/L3 doesn't apply to audio, so the result is messy.
2075 // Clean this up after we have a solution to specifying decoding mode.
2076 EXPECT_TRUE(IsTypeSupported(widevine_uuid, kL3, kAudioWebM, codec_vorbis));
2077 IsTypeSupported(widevine_uuid, kL1, kAudioWebM, codec_vorbis);
2080 IsTypeSupported(widevine_uuid, kL3, kVideoWebM, codec_vp8_vorbis));
2081 IsTypeSupported(widevine_uuid, kL1, kVideoWebM, codec_vp8_vorbis);
2084 TEST_F(MediaSourcePlayerTest, IsTypeSupported_InvalidUUID) {
2085 if (!MediaCodecBridge::IsAvailable() || !MediaDrmBridge::IsAvailable()) {
2086 VLOG(0) << "Could not run test - not supported on device.";
2090 uint8 kInvalidUUID[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
2091 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
2093 std::vector<uint8> invalid_uuid(kInvalidUUID,
2094 kInvalidUUID + arraysize(kInvalidUUID));
2096 std::vector<std::string> codec_avc(1, "avc1");
2097 EXPECT_FALSE(IsTypeSupported(invalid_uuid, kL3, kVideoMp4, codec_avc));
2098 EXPECT_FALSE(IsTypeSupported(invalid_uuid, kL1, kVideoMp4, codec_avc));
2101 // TODO(xhwang): Are these IsTypeSupported tests device specific?
2102 // TODO(xhwang): Add more IsTypeSupported tests.
2104 } // namespace media