Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: media/base/android/media_source_player_unittest.cc

Issue 2283493003: Delete browser MSE implementation. (Closed)
Patch Set: Actually delete MSP. Cleanse references. Remove AudioTrack usage. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "media/base/android/media_source_player.h"
6
7 #include <stdint.h>
8
9 #include <string>
10 #include <utility>
11
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "build/build_config.h"
18 #include "media/base/android/audio_decoder_job.h"
19 #include "media/base/android/media_codec_util.h"
20 #include "media/base/android/media_drm_bridge.h"
21 #include "media/base/android/media_player_manager.h"
22 #include "media/base/android/media_url_interceptor.h"
23 #include "media/base/android/sdk_media_codec_bridge.h"
24 #include "media/base/android/video_decoder_job.h"
25 #include "media/base/bind_to_current_loop.h"
26 #include "media/base/decoder_buffer.h"
27 #include "media/base/test_data_util.h"
28 #include "media/base/timestamp_constants.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "ui/gl/android/surface_texture.h"
31
32 namespace media {
33
34 const base::TimeDelta kDefaultDuration =
35 base::TimeDelta::FromMilliseconds(10000);
36
37 // TODO(wolenetz/qinmin): Simplify tests with more effective mock usage, and
38 // fix flaky pointer-based MDJ inequality testing. See http://crbug.com/327839.
39
40 // Mock of MediaPlayerManager for testing purpose.
41 class MockMediaPlayerManager : public MediaPlayerManager {
42 public:
43 explicit MockMediaPlayerManager(base::MessageLoop* message_loop)
44 : message_loop_(message_loop),
45 playback_completed_(false),
46 num_metadata_changes_(0),
47 timestamp_updated_(false),
48 allow_play_(true) {}
49 ~MockMediaPlayerManager() override {}
50
51 // MediaPlayerManager implementation.
52 MediaResourceGetter* GetMediaResourceGetter() override { return NULL; }
53 MediaUrlInterceptor* GetMediaUrlInterceptor() override { return NULL; }
54 void OnTimeUpdate(int player_id,
55 base::TimeDelta current_time,
56 base::TimeTicks current_time_ticks) override {
57 timestamp_updated_ = true;
58 }
59 void OnMediaMetadataChanged(int player_id,
60 base::TimeDelta duration,
61 int width,
62 int height,
63 bool success) override {
64 num_metadata_changes_++;
65 }
66 void OnPlaybackComplete(int player_id) override {
67 playback_completed_ = true;
68 if (message_loop_->is_running())
69 message_loop_->QuitWhenIdle();
70 }
71 void OnMediaInterrupted(int player_id) override {}
72 void OnBufferingUpdate(int player_id, int percentage) override {}
73 void OnSeekComplete(int player_id,
74 const base::TimeDelta& current_time) override {}
75 void OnError(int player_id, int error) override {}
76 void OnVideoSizeChanged(int player_id, int width, int height) override {}
77 void OnWaitingForDecryptionKey(int player_id) override {}
78 MediaPlayerAndroid* GetFullscreenPlayer() override { return NULL; }
79 MediaPlayerAndroid* GetPlayer(int player_id) override { return NULL; }
80 void OnDecorderResourcesReleased(int player_id) {}
81
82 bool RequestPlay(int player_id,
83 base::TimeDelta duration,
84 bool has_audio) override {
85 return allow_play_;
86 }
87
88 bool playback_completed() const {
89 return playback_completed_;
90 }
91
92 int num_metadata_changes() const {
93 return num_metadata_changes_;
94 }
95
96 bool timestamp_updated() const {
97 return timestamp_updated_;
98 }
99
100 void ResetTimestampUpdated() {
101 timestamp_updated_ = false;
102 }
103
104 void set_allow_play(bool value) {
105 allow_play_ = value;
106 }
107
108 private:
109 base::MessageLoop* message_loop_;
110 bool playback_completed_;
111 // The number of metadata changes reported by the player.
112 int num_metadata_changes_;
113 // Playback timestamp was updated.
114 bool timestamp_updated_;
115 // Whether the manager will allow players that request playing.
116 bool allow_play_;
117
118 DISALLOW_COPY_AND_ASSIGN(MockMediaPlayerManager);
119 };
120
121 class MockDemuxerAndroid : public DemuxerAndroid {
122 public:
123 explicit MockDemuxerAndroid(base::MessageLoop* message_loop)
124 : message_loop_(message_loop),
125 num_data_requests_(0),
126 num_seek_requests_(0),
127 num_browser_seek_requests_(0) {}
128 ~MockDemuxerAndroid() override {}
129
130 void Initialize(DemuxerAndroidClient* client) override {}
131 void RequestDemuxerData(DemuxerStream::Type type) override {
132 num_data_requests_++;
133 if (message_loop_->is_running())
134 message_loop_->QuitWhenIdle();
135 }
136 void RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
137 bool is_browser_seek) override {
138 num_seek_requests_++;
139 if (is_browser_seek)
140 num_browser_seek_requests_++;
141 }
142
143 int num_data_requests() const { return num_data_requests_; }
144 int num_seek_requests() const { return num_seek_requests_; }
145 int num_browser_seek_requests() const { return num_browser_seek_requests_; }
146
147 private:
148 base::MessageLoop* message_loop_;
149
150 // The number of encoded data requests this object has seen.
151 int num_data_requests_;
152
153 // The number of regular and browser seek requests this object has seen.
154 int num_seek_requests_;
155
156 // The number of browser seek requests this object has seen.
157 int num_browser_seek_requests_;
158
159 DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
160 };
161
162 class MediaSourcePlayerTest : public testing::Test {
163 public:
164 MediaSourcePlayerTest()
165 : manager_(&message_loop_),
166 demuxer_(new MockDemuxerAndroid(&message_loop_)),
167 player_(0,
168 &manager_,
169 base::Bind(&MockMediaPlayerManager::OnDecorderResourcesReleased,
170 base::Unretained(&manager_)),
171 base::WrapUnique(demuxer_),
172 GURL()),
173 decoder_callback_hook_executed_(false),
174 surface_texture_a_is_next_(true) {}
175
176 ~MediaSourcePlayerTest() override {}
177
178 protected:
179 // Get the decoder job from the MediaSourcePlayer. The return value must not
180 // be NULL.
181 MediaDecoderJob* GetMediaDecoderJob(bool is_audio) {
182 if (is_audio) {
183 return reinterpret_cast<MediaDecoderJob*>(
184 player_.audio_decoder_job_.get());
185 }
186 return reinterpret_cast<MediaDecoderJob*>(
187 player_.video_decoder_job_.get());
188 }
189
190 // Get the MediaCodecBridge from the decoder job. The return value could be
191 // NULL if the decoder is not yet created.
192 MediaCodecBridge* GetMediaCodecBridge(bool is_audio) {
193 if (is_audio)
194 return player_.audio_decoder_job_->media_codec_bridge_.get();
195 return player_.video_decoder_job_->media_codec_bridge_.get();
196 }
197
198 // Get the per-job prerolling status from the MediaSourcePlayer's job matching
199 // |is_audio|. Caller must guard against NPE if the player's job is NULL.
200 bool IsPrerolling(bool is_audio) {
201 return GetMediaDecoderJob(is_audio)->prerolling_;
202 }
203
204 // Get the preroll timestamp from the MediaSourcePlayer.
205 base::TimeDelta GetPrerollTimestamp() {
206 return player_.preroll_timestamp_;
207 }
208
209 // Simulate player has reached starvation timeout.
210 void TriggerPlayerStarvation() {
211 player_.decoder_starvation_callback_.Cancel();
212 player_.OnDecoderStarved();
213 }
214
215 // Release() the player.
216 void ReleasePlayer() {
217 EXPECT_TRUE(player_.IsPlaying());
218 player_.Release();
219 EXPECT_FALSE(player_.IsPlaying());
220 }
221
222 // Upon the next successful decode callback, post a task to call Release()
223 // on the |player_|. TEST_F's do not have access to the private player
224 // members, hence this helper method.
225 // Prevent usage creep of MSP::set_decode_callback_for_testing() by
226 // only using it for the ReleaseWithOnPrefetchDoneAlreadyPosted test.
227 void OnNextTestDecodeCallbackPostTaskToReleasePlayer() {
228 DCHECK_EQ(&message_loop_, base::MessageLoop::current());
229 player_.set_decode_callback_for_testing(media::BindToCurrentLoop(
230 base::Bind(
231 &MediaSourcePlayerTest::ReleaseWithPendingPrefetchDoneVerification,
232 base::Unretained(this))));
233 }
234
235 // Asynch test callback posted upon decode completion to verify that a pending
236 // prefetch done event is not cleared across |player_|'s Release(). This helps
237 // ensure the ReleaseWithOnPrefetchDoneAlreadyPosted test scenario is met.
238 void ReleaseWithPendingPrefetchDoneVerification() {
239 EXPECT_TRUE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
240 ReleasePlayer();
241 EXPECT_TRUE(player_.IsEventPending(player_.PREFETCH_DONE_EVENT_PENDING));
242 EXPECT_FALSE(decoder_callback_hook_executed_);
243 EXPECT_FALSE(GetMediaCodecBridge(true));
244 decoder_callback_hook_executed_ = true;
245 }
246
247 DemuxerConfigs CreateAudioDemuxerConfigs(AudioCodec audio_codec,
248 bool use_low_sample_rate) {
249 DemuxerConfigs configs;
250 configs.audio_codec = audio_codec;
251 configs.audio_channels = 2;
252 configs.is_audio_encrypted = false;
253 configs.duration = kDefaultDuration;
254
255 if (audio_codec == kCodecVorbis) {
256 configs.audio_sampling_rate = use_low_sample_rate ? 11025 : 44100;
257 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(
258 "vorbis-extradata");
259 configs.audio_extra_data = std::vector<uint8_t>(
260 buffer->data(), buffer->data() + buffer->data_size());
261 return configs;
262 }
263
264 // Other codecs are not yet supported by this helper.
265 EXPECT_EQ(audio_codec, kCodecAAC);
266
267 configs.audio_sampling_rate = 48000;
268 uint8_t aac_extra_data[] = {0x13, 0x10};
269 configs.audio_extra_data =
270 std::vector<uint8_t>(aac_extra_data, aac_extra_data + 2);
271 return configs;
272 }
273
274 DemuxerConfigs CreateVideoDemuxerConfigs(bool use_larger_size) {
275 DemuxerConfigs configs;
276 configs.video_codec = kCodecVP8;
277 configs.video_size =
278 use_larger_size ? gfx::Size(640, 240) : gfx::Size(320, 240);
279 configs.is_video_encrypted = false;
280 configs.duration = kDefaultDuration;
281 return configs;
282 }
283
284 DemuxerConfigs CreateAudioVideoDemuxerConfigs() {
285 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, false);
286 configs.video_codec = kCodecVP8;
287 configs.video_size = gfx::Size(320, 240);
288 configs.is_video_encrypted = false;
289 return configs;
290 }
291
292 DemuxerConfigs CreateDemuxerConfigs(bool have_audio, bool have_video) {
293 DCHECK(have_audio || have_video);
294
295 if (have_audio && !have_video)
296 return CreateAudioDemuxerConfigs(kCodecVorbis, false);
297
298 if (have_video && !have_audio)
299 return CreateVideoDemuxerConfigs(false);
300
301 return CreateAudioVideoDemuxerConfigs();
302 }
303
304 // Starts an audio decoder job.
305 void StartAudioDecoderJob() {
306 Start(CreateAudioDemuxerConfigs(kCodecVorbis, false));
307 }
308
309 // Starts a video decoder job.
310 void StartVideoDecoderJob() {
311 Start(CreateVideoDemuxerConfigs(false));
312 }
313
314 // Starts decoding the data.
315 void Start(const DemuxerConfigs& configs) {
316 EXPECT_EQ(demuxer_->num_data_requests(), 0);
317 player_.OnDemuxerConfigsAvailable(configs);
318 player_.Start();
319
320 EXPECT_TRUE(player_.IsPlaying());
321 int expected_num_requests = (player_.HasAudio() ? 1 : 0) +
322 (player_.HasVideo() ? 1 : 0);
323 EXPECT_EQ(expected_num_requests, demuxer_->num_data_requests());
324 }
325
326 // Resumes decoding the data. Verifies player behavior relative to
327 // |expect_player_requests_audio_data| and
328 // |expect_player_requests_video_data|.
329 void Resume(bool expect_player_requests_audio_data,
330 bool expect_player_requests_video_data) {
331 EXPECT_FALSE(player_.IsPlaying());
332 EXPECT_TRUE(player_.HasVideo() || player_.HasAudio());
333 int original_num_data_requests = demuxer_->num_data_requests();
334 int expected_request_delta =
335 (expect_player_requests_audio_data ? 1 : 0) +
336 (expect_player_requests_video_data ? 1 : 0);
337
338 player_.Start();
339
340 EXPECT_TRUE(player_.IsPlaying());
341 EXPECT_EQ(original_num_data_requests + expected_request_delta,
342 demuxer_->num_data_requests());
343 }
344
345 // Keeps decoding audio data until the decoder starts to output samples.
346 // Gives up if no audio output after decoding 10 frames.
347 void DecodeAudioDataUntilOutputBecomesAvailable() {
348 EXPECT_TRUE(player_.IsPlaying());
349 base::TimeDelta current_time = player_.GetCurrentTime();
350 base::TimeDelta start_timestamp = current_time;
351 for (int i = 0; i < 10; ++i) {
352 manager_.ResetTimestampUpdated();
353 player_.OnDemuxerDataAvailable(
354 CreateReadFromDemuxerAckForAudio(i > 3 ? 3 : i));
355 WaitForAudioDecodeDone();
356 base::TimeDelta new_current_time = player_.GetCurrentTime();
357 EXPECT_LE(current_time.InMilliseconds(),
358 new_current_time.InMilliseconds());
359 current_time = new_current_time;
360 if (manager_.timestamp_updated()) {
361 // TODO(qinmin): the current time is from the decoder thread and it does
362 // not take the delay from posting the task into consideration.
363 // http://crbug.com/421616.
364 EXPECT_LE(start_timestamp.InMillisecondsF(),
365 new_current_time.InMillisecondsF());
366 return;
367 }
368 }
369 EXPECT_TRUE(false);
370 }
371
372 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id,
373 bool use_large_size_video) {
374 AccessUnit unit;
375
376 unit.status = DemuxerStream::kOk;
377 scoped_refptr<DecoderBuffer> buffer;
378 if (is_audio) {
379 buffer = ReadTestDataFile(
380 base::StringPrintf("vorbis-packet-%d", audio_packet_id));
381 } else {
382 buffer = ReadTestDataFile(
383 use_large_size_video ? "vp8-I-frame-640x240" : "vp8-I-frame-320x240");
384 }
385 unit.data = std::vector<uint8_t>(buffer->data(),
386 buffer->data() + buffer->data_size());
387
388 if (is_audio) {
389 // Vorbis needs 4 extra bytes padding on Android to decode properly. Check
390 // NuMediaExtractor.cpp in Android source code.
391 uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
392 unit.data.insert(unit.data.end(), padding, padding + 4);
393 }
394
395 return unit;
396 }
397
398 DemuxerData CreateReadFromDemuxerAckForAudio(int packet_id) {
399 DemuxerData data;
400 data.type = DemuxerStream::AUDIO;
401 data.access_units.resize(1);
402 data.access_units[0] = CreateAccessUnitWithData(true, packet_id, false);
403
404 return data;
405 }
406
407 DemuxerData CreateReadFromDemuxerAckForVideo(bool use_large_size) {
408 DemuxerData data;
409 data.type = DemuxerStream::VIDEO;
410 data.access_units.resize(1);
411 data.access_units[0] = CreateAccessUnitWithData(false, 0, use_large_size);
412 return data;
413 }
414
415 DemuxerData CreateEOSAck(bool is_audio) {
416 DemuxerData data;
417 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
418 data.access_units.resize(1);
419 data.access_units[0].status = DemuxerStream::kOk;
420 data.access_units[0].is_end_of_stream = true;
421 return data;
422 }
423
424 DemuxerData CreateAbortedAck(bool is_audio) {
425 DemuxerData data;
426 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
427 data.access_units.resize(1);
428 data.access_units[0].status = DemuxerStream::kAborted;
429 return data;
430 }
431
432 bool HasData(bool is_audio) {
433 return GetMediaDecoderJob(is_audio)->HasData();
434 }
435
436 // Helper method for use at test start. It starts an audio decoder job and
437 // immediately feeds it some data to decode. Then, without letting the decoder
438 // job complete a decode cycle, it also starts player SeekTo(). Upon return,
439 // the player should not yet have sent the DemuxerSeek IPC request, though
440 // seek event should be pending. The audio decoder job will also still be
441 // decoding.
442 void StartAudioDecoderJobAndSeekToWhileDecoding(
443 const base::TimeDelta& seek_time) {
444 EXPECT_FALSE(GetMediaCodecBridge(true));
445 EXPECT_FALSE(player_.IsPlaying());
446 EXPECT_EQ(0, demuxer_->num_data_requests());
447 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
448 EXPECT_EQ(player_.GetCurrentTime(), GetPrerollTimestamp());
449 StartAudioDecoderJob();
450 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
451 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
452 EXPECT_EQ(2, demuxer_->num_data_requests());
453 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
454 player_.SeekTo(seek_time);
455 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF());
456 EXPECT_EQ(0, demuxer_->num_seek_requests());
457 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
458 }
459
460 // Seek, including simulated receipt of |kAborted| read between SeekTo() and
461 // OnDemuxerSeekDone(). Use this helper method only when the player already
462 // has created the media codec bridge. Exactly one request for more data is
463 // expected following the seek, so use this helper for players with only audio
464 // or only video.
465 void SeekPlayerWithAbort(bool is_audio, const base::TimeDelta& seek_time) {
466 int original_num_seeks = demuxer_->num_seek_requests();
467 int original_num_data_requests = demuxer_->num_data_requests();
468
469 // Initiate a seek. Skip the round-trip of requesting seek from renderer.
470 // Instead behave as if the renderer has asked us to seek.
471 player_.SeekTo(seek_time);
472
473 // Verify that the seek does not occur until previously outstanding data
474 // request is satisfied.
475 EXPECT_EQ(original_num_seeks, demuxer_->num_seek_requests());
476
477 // Simulate seeking causes the demuxer to abort the outstanding read
478 // caused by the seek.
479 player_.OnDemuxerDataAvailable(CreateAbortedAck(is_audio));
480
481 // Wait for the decode job to finish so we can process the seek request.
482 WaitForDecodeDone(is_audio, !is_audio);
483
484 // Verify that the seek is requested.
485 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests());
486
487 // Send back the seek done notification. This should trigger the player to
488 // call OnReadFromDemuxer() again.
489 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests());
490 player_.OnDemuxerSeekDone(kNoTimestamp);
491 EXPECT_EQ(original_num_data_requests + 1, demuxer_->num_data_requests());
492
493 // No other seek should have been requested.
494 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests());
495 }
496
497 // Preroll the decoder job to |target_timestamp|. The first access unit
498 // to decode will have a timestamp equal to |start_timestamp|.
499 // |is_clock_manager| indicates whether the decoder serves as the clock
500 // manager for the player.
501 // TODO(qinmin): Add additional test cases for out-of-order decodes.
502 // See http://crbug.com/331421.
503 void PrerollDecoderToTime(bool is_audio,
504 const base::TimeDelta& start_timestamp,
505 const base::TimeDelta& target_timestamp,
506 bool is_clock_manager) {
507 // For streams with both audio and video, it is possible that audio rolls
508 // past the |target_timestamp|. As a result, the current time may be larger
509 // than the |target_timestamp| for video as it may not be the clock manager.
510 EXPECT_TRUE(!is_clock_manager ||
511 target_timestamp == player_.GetCurrentTime());
512 // |start_timestamp| must be smaller than |target_timestamp|.
513 EXPECT_LE(start_timestamp, target_timestamp);
514 DemuxerData data = is_audio ? CreateReadFromDemuxerAckForAudio(1) :
515 CreateReadFromDemuxerAckForVideo(false);
516 int current_timestamp = start_timestamp.InMilliseconds();
517
518 // Send some data with access unit timestamps before the |target_timestamp|,
519 // and continue sending the data until preroll finishes.
520 // This simulates the common condition that AUs received after browser
521 // seek begin with timestamps before the seek target, and don't
522 // immediately complete preroll.
523 while (IsPrerolling(is_audio)) {
524 data.access_units[0].timestamp =
525 base::TimeDelta::FromMilliseconds(current_timestamp);
526 player_.OnDemuxerDataAvailable(data);
527 EXPECT_TRUE(GetMediaDecoderJob(is_audio)->is_decoding());
528 EXPECT_TRUE(GetMediaCodecBridge(is_audio));
529 EXPECT_TRUE(!is_clock_manager ||
530 target_timestamp == player_.GetCurrentTime());
531 current_timestamp += 30;
532 WaitForDecodeDone(is_audio, !is_audio);
533 }
534 EXPECT_LE(target_timestamp, player_.GetCurrentTime());
535 }
536
537 DemuxerData CreateReadFromDemuxerAckWithConfigChanged(
538 bool is_audio,
539 int config_unit_index,
540 const DemuxerConfigs& configs) {
541 DemuxerData data;
542 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO;
543 data.access_units.resize(config_unit_index + 1);
544
545 for (int i = 0; i < config_unit_index; ++i)
546 data.access_units[i] = CreateAccessUnitWithData(is_audio, i, false);
547
548 data.access_units[config_unit_index].status = DemuxerStream::kConfigChanged;
549 data.demuxer_configs.resize(1);
550 data.demuxer_configs[0] = configs;
551 return data;
552 }
553
554 // Valid only for video-only player tests. If |trigger_with_release_start| is
555 // true, triggers the browser seek with a Release() + video data received +
556 // Start() with a new surface. If false, triggers the browser seek by
557 // setting a new video surface after beginning decode of received video data.
558 // Such data receipt causes possibility that an I-frame is not next, and
559 // browser seek results once decode completes and surface change processing
560 // begins.
561 void BrowserSeekPlayer(bool trigger_with_release_start) {
562 int expected_num_data_requests = demuxer_->num_data_requests() + 2;
563 int expected_num_seek_requests = demuxer_->num_seek_requests();
564 int expected_num_browser_seek_requests =
565 demuxer_->num_browser_seek_requests();
566
567 CreateNextTextureAndSetVideoSurface();
568 StartVideoDecoderJob();
569 if (trigger_with_release_start) {
570 // Consume the first frame, so that the next VideoDecoderJob will not
571 // inherit the I-frame from the previous decoder.
572 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
573 ReleasePlayer();
574 WaitForVideoDecodeDone();
575
576 // Simulate demuxer's response to the video data request. The data will be
577 // passed to the next MediaCodecBridge.
578 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
579 EXPECT_FALSE(GetMediaCodecBridge(false));
580 EXPECT_FALSE(player_.IsPlaying());
581 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
582
583 CreateNextTextureAndSetVideoSurface();
584 Resume(false, false);
585 EXPECT_FALSE(GetMediaCodecBridge(false));
586
587 // Run the message loop so that prefetch will complete.
588 while (expected_num_seek_requests == demuxer_->num_seek_requests())
589 base::RunLoop().RunUntilIdle();
590 } else {
591 // Simulate demuxer's response to the video data request.
592 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
593
594 // While the decoder is decoding, trigger a browser seek by changing
595 // surface. Demuxer does not know of browser seek in advance, so no
596 // |kAborted| data is required (though |kAborted| can certainly occur for
597 // any pending read in reality due to renderer preparing for a regular
598 // seek).
599 CreateNextTextureAndSetVideoSurface();
600
601 // Browser seek should not begin until decoding has completed.
602 EXPECT_TRUE(GetMediaCodecBridge(false));
603 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
604
605 // Wait for the media codec bridge to finish decoding and be reset pending
606 // the browser seek.
607 WaitForVideoDecodeDone();
608 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
609 }
610
611 // Only one browser seek should have been initiated, and no further data
612 // should have been requested.
613 expected_num_seek_requests++;
614 expected_num_browser_seek_requests++;
615 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests());
616 EXPECT_EQ(expected_num_browser_seek_requests,
617 demuxer_->num_browser_seek_requests());
618 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
619 }
620
621 // Creates a new media codec bridge and feeds it data ending with a
622 // |kConfigChanged| access unit. If |config_unit_in_prefetch| is true, sends
623 // feeds the config change AU in response to the job's first read request
624 // (prefetch). If false, regular data is fed and decoded prior to feeding the
625 // config change AU in response to the second data request (after prefetch
626 // completed). |config_unit_index| controls which access unit is
627 // |kConfigChanged|. If |enable_adaptive_playback| is true, config change will
628 // not cause the decoder to recreate the media codec bridge. Otherwise, the
629 // decoder has to drain all its data before recreating the new codec.
630 void SendConfigChangeToDecoder(bool is_audio,
631 bool config_unit_in_prefetch,
632 int config_unit_index,
633 bool enable_adaptive_playback) {
634 EXPECT_FALSE(GetMediaCodecBridge(is_audio));
635 if (is_audio) {
636 StartAudioDecoderJob();
637 } else {
638 CreateNextTextureAndSetVideoSurface();
639 StartVideoDecoderJob();
640 }
641
642 int expected_num_data_requests = demuxer_->num_data_requests();
643 // Feed and decode a standalone access unit so the player exits prefetch.
644 if (!config_unit_in_prefetch) {
645 if (is_audio) {
646 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
647 } else {
648 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
649 EnableAdaptiveVideoPlayback(enable_adaptive_playback);
650 }
651
652 WaitForDecodeDone(is_audio, !is_audio);
653
654 // We should have completed the prefetch phase at this point.
655 expected_num_data_requests++;
656 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
657 }
658
659 DemuxerConfigs configs = is_audio ?
660 CreateAudioDemuxerConfigs(kCodecVorbis, true) :
661 CreateVideoDemuxerConfigs(true);
662 // Feed and decode access units with data for any units prior to
663 // |config_unit_index|, and a |kConfigChanged| unit at that index.
664 // Player should prepare to reconfigure the decoder job, and should request
665 // new demuxer configs.
666 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
667 is_audio, config_unit_index, configs));
668
669 expected_num_data_requests++;
670 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests());
671 if (is_audio)
672 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
673 else
674 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(true));
675
676 // If the adaptive playback setting was not passed to the MediaCodecBridge
677 // earlier, do it here.
678 if (config_unit_in_prefetch && !is_audio)
679 EnableAdaptiveVideoPlayback(enable_adaptive_playback);
680 }
681
682 // Send a config change to the decoder job and drain the decoder so that the
683 // config change is processed.
684 void StartConfigChange(bool is_audio,
685 bool config_unit_in_prefetch,
686 int config_unit_index,
687 bool enable_adaptive_playback) {
688 SendConfigChangeToDecoder(is_audio, config_unit_in_prefetch,
689 config_unit_index, enable_adaptive_playback);
690
691 EXPECT_EQ(!config_unit_in_prefetch && !enable_adaptive_playback &&
692 config_unit_index == 0, IsDrainingDecoder(is_audio));
693 int expected_num_data_requests = demuxer_->num_data_requests();
694 // Run until decoder starts to request new data.
695 while (demuxer_->num_data_requests() == expected_num_data_requests)
696 base::RunLoop().RunUntilIdle();
697 EXPECT_FALSE(IsDrainingDecoder(is_audio));
698 }
699
700 void EnableAdaptiveVideoPlayback(bool enable) {
701 EXPECT_TRUE(GetMediaCodecBridge(false));
702 static_cast<VideoCodecBridge*>(GetMediaCodecBridge(false))->
703 set_adaptive_playback_supported_for_testing(
704 enable ? 1 : 0);
705 }
706
707 void CreateNextTextureAndSetVideoSurface() {
708 gl::SurfaceTexture* surface_texture;
709 if (surface_texture_a_is_next_) {
710 surface_texture_a_ = gl::SurfaceTexture::Create(next_texture_id_++);
711 surface_texture = surface_texture_a_.get();
712 } else {
713 surface_texture_b_ = gl::SurfaceTexture::Create(next_texture_id_++);
714 surface_texture = surface_texture_b_.get();
715 }
716
717 surface_texture_a_is_next_ = !surface_texture_a_is_next_;
718 gl::ScopedJavaSurface surface = gl::ScopedJavaSurface(surface_texture);
719 player_.SetVideoSurface(std::move(surface));
720 }
721
722 // Wait for one or both of the jobs to complete decoding. Media codec bridges
723 // are assumed to exist for any stream whose decode completion is awaited.
724 void WaitForDecodeDone(bool wait_for_audio, bool wait_for_video) {
725 DCHECK(wait_for_audio || wait_for_video);
726 while ((wait_for_audio && GetMediaCodecBridge(true) &&
727 GetMediaDecoderJob(true)->HasData() &&
728 GetMediaDecoderJob(true)->is_decoding()) ||
729 (wait_for_video && GetMediaCodecBridge(false) &&
730 GetMediaDecoderJob(false)->HasData() &&
731 GetMediaDecoderJob(false)->is_decoding())) {
732 base::RunLoop().RunUntilIdle();
733 }
734 }
735
736 void WaitForAudioDecodeDone() {
737 WaitForDecodeDone(true, false);
738 }
739
740 void WaitForVideoDecodeDone() {
741 WaitForDecodeDone(false, true);
742 }
743
744 void WaitForAudioVideoDecodeDone() {
745 WaitForDecodeDone(true, true);
746 }
747
748 // If |send_eos| is true, generates EOS for the stream corresponding to
749 // |eos_for_audio|. Verifies that playback completes and no further data
750 // is requested.
751 // If |send_eos| is false, then it is assumed that caller previously arranged
752 // for player to receive EOS for each stream, but the player has not yet
753 // decoded all of them. In this case, |eos_for_audio| is ignored.
754 void VerifyPlaybackCompletesOnEOSDecode(bool send_eos, bool eos_for_audio) {
755 int original_num_data_requests = demuxer_->num_data_requests();
756 if (send_eos)
757 player_.OnDemuxerDataAvailable(CreateEOSAck(eos_for_audio));
758 EXPECT_FALSE(manager_.playback_completed());
759 base::RunLoop().Run();
760 EXPECT_TRUE(manager_.playback_completed());
761 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests());
762 }
763
764 void VerifyCompletedPlaybackResumesOnSeekPlusStart(bool have_audio,
765 bool have_video) {
766 DCHECK(have_audio || have_video);
767
768 EXPECT_TRUE(manager_.playback_completed());
769
770 player_.SeekTo(base::TimeDelta());
771 player_.OnDemuxerSeekDone(kNoTimestamp);
772 Resume(have_audio, have_video);
773 }
774
775 // Starts the appropriate decoder jobs according to |have_audio| and
776 // |have_video|. Then starts seek during decode of EOS or non-EOS according to
777 // |eos_audio| and |eos_video|. Simulates seek completion and verifies that
778 // playback never completed. |eos_{audio,video}| is ignored if the
779 // corresponding |have_{audio,video}| is false.
780 void VerifySeekDuringEOSDecodePreventsPlaybackCompletion(bool have_audio,
781 bool have_video,
782 bool eos_audio,
783 bool eos_video) {
784 DCHECK(have_audio || have_video);
785
786 if (have_video)
787 CreateNextTextureAndSetVideoSurface();
788
789 Start(CreateDemuxerConfigs(have_audio, have_video));
790
791 if (have_audio)
792 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
793
794 if (have_video)
795 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
796
797 // Run until more data is requested a number of times equal to the number of
798 // media types configured. Since prefetching may be in progress, we cannot
799 // reliably expect Run() to complete until we have sent demuxer data for all
800 // configured media types, above.
801 WaitForDecodeDone(have_audio, have_video);
802
803 // Simulate seek while decoding EOS or non-EOS for the appropriate
804 // stream(s).
805 if (have_audio) {
806 if (eos_audio)
807 player_.OnDemuxerDataAvailable(CreateEOSAck(true));
808 else
809 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
810 }
811
812 if (have_video) {
813 if (eos_video)
814 player_.OnDemuxerDataAvailable(CreateEOSAck(false));
815 else
816 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
817 }
818
819 player_.SeekTo(base::TimeDelta());
820 EXPECT_EQ(0, demuxer_->num_seek_requests());
821 WaitForDecodeDone(have_audio, have_video);
822 EXPECT_EQ(1, demuxer_->num_seek_requests());
823
824 player_.OnDemuxerSeekDone(kNoTimestamp);
825 EXPECT_FALSE(manager_.playback_completed());
826 }
827
828 base::TimeTicks StartTimeTicks() {
829 return player_.start_time_ticks_;
830 }
831
832 bool IsRequestingDemuxerData(bool is_audio) {
833 return GetMediaDecoderJob(is_audio)->is_requesting_demuxer_data_;
834 }
835
836 bool IsDrainingDecoder(bool is_audio) {
837 return GetMediaDecoderJob(is_audio)->drain_decoder_;
838 }
839
840 protected:
841 base::MessageLoop message_loop_;
842 MockMediaPlayerManager manager_;
843 MockDemuxerAndroid* demuxer_; // Owned by |player_|.
844 MediaSourcePlayer player_;
845
846 // Track whether a possibly async decoder callback test hook has run.
847 bool decoder_callback_hook_executed_;
848
849 // We need to keep the surface texture while the decoder is actively decoding.
850 // Otherwise, it may trigger unexpected crashes on some devices. To switch
851 // surfaces, tests need to create a new surface texture without releasing
852 // their previous one. In CreateNextTextureAndSetVideoSurface(), we toggle
853 // between two surface textures, only replacing the N-2 texture. Assumption is
854 // that no more than N-1 texture is in use by decoder when
855 // CreateNextTextureAndSetVideoSurface() is called.
856 scoped_refptr<gl::SurfaceTexture> surface_texture_a_;
857 scoped_refptr<gl::SurfaceTexture> surface_texture_b_;
858 bool surface_texture_a_is_next_;
859 int next_texture_id_;
860
861 DISALLOW_COPY_AND_ASSIGN(MediaSourcePlayerTest);
862 };
863
864 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithValidConfig) {
865 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
866
867 // Test audio codec will be created when valid configs and data are passed to
868 // the audio decoder job.
869 StartAudioDecoderJob();
870 EXPECT_EQ(0, demuxer_->num_seek_requests());
871 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
872 EXPECT_TRUE(GetMediaCodecBridge(true));
873 }
874
875 TEST_F(MediaSourcePlayerTest, StartAudioDecoderWithInvalidConfig) {
876 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
877
878 // Test audio decoder job will not be created when failed to start the codec.
879 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, false);
880 // Replace with invalid |audio_extra_data|
881 configs.audio_extra_data.clear();
882 uint8_t invalid_codec_data[] = {0x00, 0xff, 0xff, 0xff, 0xff};
883 configs.audio_extra_data.insert(configs.audio_extra_data.begin(),
884 invalid_codec_data, invalid_codec_data + 4);
885 Start(configs);
886
887 // Decoder is not created after data is received.
888 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
889 EXPECT_FALSE(GetMediaCodecBridge(true));
890 }
891
892 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithValidSurface) {
893 // crbug.com/604602 and crbug.com/597836
894 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
895
896 // Test video codec will not be created until data is received.
897 StartVideoDecoderJob();
898
899 // Set both an initial and a later video surface without receiving any
900 // demuxed data yet.
901 CreateNextTextureAndSetVideoSurface();
902 EXPECT_FALSE(GetMediaCodecBridge(false));
903 CreateNextTextureAndSetVideoSurface();
904 EXPECT_FALSE(GetMediaCodecBridge(false));
905
906 // No seeks, even on setting surface, should have occurred. (Browser seeks can
907 // occur on setting surface, but only after previously receiving video data.)
908 EXPECT_EQ(0, demuxer_->num_seek_requests());
909
910 // Send the first input chunk and verify that decoder will be created.
911 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
912 EXPECT_TRUE(GetMediaCodecBridge(false));
913 WaitForVideoDecodeDone();
914 }
915
916 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithInvalidSurface) {
917 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
918
919 // Test video codec will not be created when surface is invalid.
920 scoped_refptr<gl::SurfaceTexture> surface_texture(
921 gl::SurfaceTexture::Create(0));
922 gl::ScopedJavaSurface surface(surface_texture.get());
923 StartVideoDecoderJob();
924
925 // Release the surface texture.
926 surface_texture = NULL;
927 player_.SetVideoSurface(std::move(surface));
928
929 // Player should not seek the demuxer on setting initial surface.
930 EXPECT_EQ(0, demuxer_->num_seek_requests());
931 EXPECT_EQ(1, demuxer_->num_data_requests());
932
933 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
934 EXPECT_FALSE(GetMediaCodecBridge(false));
935 }
936
937 TEST_F(MediaSourcePlayerTest, ReadFromDemuxerAfterSeek) {
938 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
939
940 // Test decoder job will resend a ReadFromDemuxer request after seek.
941 StartAudioDecoderJob();
942 SeekPlayerWithAbort(true, base::TimeDelta());
943 }
944
945 TEST_F(MediaSourcePlayerTest, SetSurfaceWhileSeeking) {
946 // crbug.com/604602 and crbug.com/597836
947 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
948
949 // Test SetVideoSurface() will not cause an extra seek while the player is
950 // waiting for demuxer to indicate seek is done.
951 player_.OnDemuxerConfigsAvailable(
952 CreateVideoDemuxerConfigs(false));
953
954 // Initiate a seek. Skip requesting element seek of renderer.
955 // Instead behave as if the renderer has asked us to seek.
956 player_.SeekTo(base::TimeDelta());
957 EXPECT_EQ(1, demuxer_->num_seek_requests());
958
959 CreateNextTextureAndSetVideoSurface();
960 EXPECT_EQ(1, demuxer_->num_seek_requests());
961 player_.Start();
962
963 // Send the seek done notification. The player should start requesting data.
964 player_.OnDemuxerSeekDone(kNoTimestamp);
965 EXPECT_FALSE(GetMediaCodecBridge(false));
966 EXPECT_EQ(1, demuxer_->num_data_requests());
967 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
968 EXPECT_TRUE(GetMediaCodecBridge(false));
969
970 // Reconfirm exactly 1 seek request has been made of demuxer, and that it
971 // was not a browser seek request.
972 EXPECT_EQ(1, demuxer_->num_seek_requests());
973 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
974 WaitForVideoDecodeDone();
975 }
976
977 TEST_F(MediaSourcePlayerTest, ChangeMultipleSurfaceWhileDecoding) {
978 // crbug.com/604602 and crbug.com/597836
979 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
980
981 // Test MediaSourcePlayer can switch multiple surfaces during decoding.
982 CreateNextTextureAndSetVideoSurface();
983 StartVideoDecoderJob();
984 EXPECT_EQ(0, demuxer_->num_seek_requests());
985
986 // Send the first input chunk.
987 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
988
989 // While the decoder is decoding, change multiple surfaces. Pass an empty
990 // surface first.
991 gl::ScopedJavaSurface empty_surface;
992 player_.SetVideoSurface(std::move(empty_surface));
993 // Next, pass a new non-empty surface.
994 CreateNextTextureAndSetVideoSurface();
995
996 // Wait for the media codec bridge to finish decoding and be reset pending a
997 // browser seek.
998 WaitForVideoDecodeDone();
999 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1000
1001 // Only one browser seek should have been initiated. No further data request
1002 // should have been processed on |message_loop_| before surface change event
1003 // became pending, above.
1004 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
1005 EXPECT_EQ(2, demuxer_->num_data_requests());
1006
1007 // Simulate browser seek is done and confirm player requests more data for new
1008 // video codec.
1009 player_.OnDemuxerSeekDone(player_.GetCurrentTime());
1010 EXPECT_FALSE(GetMediaCodecBridge(false));
1011 EXPECT_EQ(3, demuxer_->num_data_requests());
1012 EXPECT_EQ(1, demuxer_->num_seek_requests());
1013
1014 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1015 EXPECT_TRUE(GetMediaCodecBridge(false));
1016 WaitForVideoDecodeDone();
1017 }
1018
1019 TEST_F(MediaSourcePlayerTest, SetEmptySurfaceAndStarveWhileDecoding) {
1020 // crbug.com/604602 and crbug.com/597836
1021 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1022
1023 // Test player pauses if an empty surface is passed.
1024 CreateNextTextureAndSetVideoSurface();
1025 StartVideoDecoderJob();
1026 EXPECT_EQ(1, demuxer_->num_data_requests());
1027
1028 // Send the first input chunk.
1029 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1030
1031 // While the decoder is decoding, pass an empty surface.
1032 gl::ScopedJavaSurface empty_surface;
1033 player_.SetVideoSurface(std::move(empty_surface));
1034 // Let the player starve. However, it should not issue any new data request in
1035 // this case.
1036 TriggerPlayerStarvation();
1037 // Wait for the media codec bridge to finish decoding and be reset.
1038 while (GetMediaDecoderJob(false)->is_decoding())
1039 base::RunLoop().RunUntilIdle();
1040
1041 // No further seek or data requests should have been received since the
1042 // surface is empty.
1043 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
1044 EXPECT_EQ(2, demuxer_->num_data_requests());
1045 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1046
1047 // Playback resumes once a non-empty surface is passed.
1048 CreateNextTextureAndSetVideoSurface();
1049 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
1050 while(demuxer_->num_browser_seek_requests() != 1)
1051 base::RunLoop().RunUntilIdle();
1052 WaitForVideoDecodeDone();
1053 }
1054
1055 TEST_F(MediaSourcePlayerTest, ReleaseVideoDecoderResourcesWhileDecoding) {
1056 // crbug.com/604602 and crbug.com/597836
1057 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1058
1059 // Test that if video decoder is released while decoding, the resources will
1060 // not be immediately released.
1061 CreateNextTextureAndSetVideoSurface();
1062 StartVideoDecoderJob();
1063 ReleasePlayer();
1064 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1065
1066 // Recreate the video decoder.
1067 CreateNextTextureAndSetVideoSurface();
1068 player_.Start();
1069 while (!GetMediaDecoderJob(false)->is_decoding())
1070 base::RunLoop().RunUntilIdle();
1071 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
1072 ReleasePlayer();
1073 // Wait for the media codec bridge to finish decoding and be reset.
1074 while (GetMediaDecoderJob(false)->is_decoding())
1075 base::RunLoop().RunUntilIdle();
1076 }
1077
1078 TEST_F(MediaSourcePlayerTest, AudioOnlyStartAfterSeekFinish) {
1079 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1080
1081 // Test audio decoder job will not start until pending seek event is handled.
1082 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, false);
1083 player_.OnDemuxerConfigsAvailable(configs);
1084
1085 // Initiate a seek. Skip requesting element seek of renderer.
1086 // Instead behave as if the renderer has asked us to seek.
1087 player_.SeekTo(base::TimeDelta());
1088 EXPECT_EQ(1, demuxer_->num_seek_requests());
1089
1090 player_.Start();
1091 EXPECT_EQ(0, demuxer_->num_data_requests());
1092
1093 // Sending back the seek done notification.
1094 player_.OnDemuxerSeekDone(kNoTimestamp);
1095 EXPECT_FALSE(GetMediaCodecBridge(true));
1096 EXPECT_EQ(1, demuxer_->num_data_requests());
1097
1098 // Reconfirm exactly 1 seek request has been made of demuxer.
1099 EXPECT_EQ(1, demuxer_->num_seek_requests());
1100
1101 // Decoder is created after data is received.
1102 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1103 EXPECT_TRUE(GetMediaCodecBridge(true));
1104 }
1105
1106 TEST_F(MediaSourcePlayerTest, VideoOnlyStartAfterSeekFinish) {
1107 // crbug.com/604602 and crbug.com/597836
1108 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1109
1110 // Test video decoder job will not start until pending seek event is handled.
1111 CreateNextTextureAndSetVideoSurface();
1112 DemuxerConfigs configs = CreateVideoDemuxerConfigs(false);
1113 player_.OnDemuxerConfigsAvailable(configs);
1114
1115 // Initiate a seek. Skip requesting element seek of renderer.
1116 // Instead behave as if the renderer has asked us to seek.
1117 player_.SeekTo(base::TimeDelta());
1118 EXPECT_EQ(1, demuxer_->num_seek_requests());
1119
1120 player_.Start();
1121 EXPECT_EQ(0, demuxer_->num_data_requests());
1122
1123 // Sending back the seek done notification.
1124 player_.OnDemuxerSeekDone(kNoTimestamp);
1125 EXPECT_FALSE(GetMediaCodecBridge(false));
1126 EXPECT_EQ(1, demuxer_->num_data_requests());
1127
1128 // Reconfirm exactly 1 seek request has been made of demuxer.
1129 EXPECT_EQ(1, demuxer_->num_seek_requests());
1130
1131 // Decoder is created after data is received.
1132 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1133 EXPECT_TRUE(GetMediaCodecBridge(false));
1134 WaitForVideoDecodeDone();
1135 }
1136
1137 TEST_F(MediaSourcePlayerTest, StartImmediatelyAfterPause) {
1138 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1139
1140 // Test that if the decoding job is not fully stopped after Pause(),
1141 // calling Start() will be a noop.
1142 StartAudioDecoderJob();
1143
1144 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
1145 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
1146
1147 // Sending data to player.
1148 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1149 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1150 EXPECT_EQ(2, demuxer_->num_data_requests());
1151
1152 // Decoder job will not immediately stop after Pause() since it is
1153 // running on another thread.
1154 player_.Pause(true);
1155 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1156
1157 // Nothing happens when calling Start() again.
1158 player_.Start();
1159 // Verify that Start() will not destroy and recreate the media codec bridge.
1160 EXPECT_EQ(decoder_job, GetMediaDecoderJob(true));
1161
1162 while (GetMediaDecoderJob(true)->is_decoding())
1163 base::RunLoop().RunUntilIdle();
1164 // The decoder job should finish and wait for data.
1165 EXPECT_EQ(2, demuxer_->num_data_requests());
1166 EXPECT_TRUE(IsRequestingDemuxerData(true));
1167 }
1168
1169 TEST_F(MediaSourcePlayerTest, DecoderJobsCannotStartWithoutAudio) {
1170 // crbug.com/604602 and crbug.com/597836
1171 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1172
1173 // Test that when Start() is called, video decoder job will wait for audio
1174 // decoder job before start decoding the data.
1175 CreateNextTextureAndSetVideoSurface();
1176 Start(CreateAudioVideoDemuxerConfigs());
1177 MediaDecoderJob* audio_decoder_job = GetMediaDecoderJob(true);
1178 MediaDecoderJob* video_decoder_job = GetMediaDecoderJob(false);
1179
1180 EXPECT_FALSE(audio_decoder_job->is_decoding());
1181 EXPECT_FALSE(video_decoder_job->is_decoding());
1182
1183 // Sending video data to player, video decoder should not start.
1184 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1185 EXPECT_FALSE(video_decoder_job->is_decoding());
1186
1187 // Sending audio data to player, both decoders should start now.
1188 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1189 EXPECT_TRUE(audio_decoder_job->is_decoding());
1190 EXPECT_TRUE(video_decoder_job->is_decoding());
1191
1192 // No seeks should have occurred.
1193 EXPECT_EQ(0, demuxer_->num_seek_requests());
1194 WaitForVideoDecodeDone();
1195 }
1196
1197 TEST_F(MediaSourcePlayerTest, StartTimeTicksResetAfterDecoderUnderruns) {
1198 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1199
1200 // Test start time ticks will reset after decoder job underruns.
1201 StartAudioDecoderJob();
1202
1203 DecodeAudioDataUntilOutputBecomesAvailable();
1204
1205 // The decoder job should finish prerolling and start prefetching.
1206 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1207 base::TimeTicks previous = StartTimeTicks();
1208
1209 // Let the decoder starve.
1210 TriggerPlayerStarvation();
1211 WaitForAudioDecodeDone();
1212 EXPECT_TRUE(StartTimeTicks() == previous);
1213
1214 // Send new data to the decoder so it can finish prefetching. This should
1215 // reset the start time ticks.
1216 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
1217 EXPECT_TRUE(StartTimeTicks() != previous);
1218
1219 base::TimeTicks current = StartTimeTicks();
1220 EXPECT_LE(0, (current - previous).InMillisecondsF());
1221 }
1222
1223 TEST_F(MediaSourcePlayerTest, V_SecondAccessUnitIsEOSAndResumePlayAfterSeek) {
1224 // crbug.com/604602 and crbug.com/597836
1225 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1226
1227 // Test MediaSourcePlayer can replay video after input EOS is reached.
1228 CreateNextTextureAndSetVideoSurface();
1229 StartVideoDecoderJob();
1230
1231 // Send the first input chunk.
1232 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1233 WaitForVideoDecodeDone();
1234
1235 VerifyPlaybackCompletesOnEOSDecode(true, false);
1236 VerifyCompletedPlaybackResumesOnSeekPlusStart(false, true);
1237 }
1238
1239 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitIsEOSAndResumePlayAfterSeek) {
1240 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1241
1242 // Test decode of audio EOS buffer without any prior decode. See also
1243 // http://b/11696552.
1244 // Also tests that seeking+Start() after completing audio playback resumes
1245 // playback.
1246 Start(CreateAudioDemuxerConfigs(kCodecAAC, false));
1247 VerifyPlaybackCompletesOnEOSDecode(true, true);
1248 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, false);
1249 }
1250
1251 TEST_F(MediaSourcePlayerTest, V_FirstAccessUnitAfterSeekIsEOS) {
1252 // crbug.com/604602 and crbug.com/597836
1253 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1254
1255 // Test decode of video EOS buffer, just after seeking, without any prior
1256 // decode (other than the simulated |kAborted| resulting from the seek
1257 // process.)
1258 CreateNextTextureAndSetVideoSurface();
1259 StartVideoDecoderJob();
1260 SeekPlayerWithAbort(false, base::TimeDelta());
1261 VerifyPlaybackCompletesOnEOSDecode(true, false);
1262 }
1263
1264 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitAfterSeekIsEOS) {
1265 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1266
1267 // Test decode of audio EOS buffer, just after seeking, without any prior
1268 // decode (other than the simulated |kAborted| resulting from the seek
1269 // process.) See also http://b/11696552.
1270 Start(CreateAudioDemuxerConfigs(kCodecAAC, false));
1271 SeekPlayerWithAbort(true, base::TimeDelta());
1272 VerifyPlaybackCompletesOnEOSDecode(true, true);
1273 }
1274
1275 TEST_F(MediaSourcePlayerTest, AV_PlaybackCompletionAcrossConfigChange) {
1276 // crbug.com/604602 and crbug.com/597836
1277 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1278
1279 // Test that if one stream (audio) has completed decode of EOS and the other
1280 // stream (video) processes config change, that subsequent video EOS completes
1281 // A/V playback.
1282 // Also tests that seeking+Start() after completing playback resumes playback.
1283 CreateNextTextureAndSetVideoSurface();
1284 Start(CreateAudioVideoDemuxerConfigs());
1285
1286 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1287 DemuxerConfigs configs = CreateVideoDemuxerConfigs(true);
1288 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1289 false, 0, configs)); // Video |kConfigChanged| as first unit.
1290
1291 WaitForAudioVideoDecodeDone();
1292
1293 EXPECT_EQ(3, demuxer_->num_data_requests());
1294
1295 // At no time after completing audio EOS decode, above, should the
1296 // audio decoder job resume decoding. Send and decode video EOS.
1297 VerifyPlaybackCompletesOnEOSDecode(true, false);
1298 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1299 }
1300
1301 TEST_F(MediaSourcePlayerTest, VA_PlaybackCompletionAcrossConfigChange) {
1302 // crbug.com/604602 and crbug.com/597836
1303 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1304
1305 // Test that if one stream (video) has completed decode of EOS and the other
1306 // stream (audio) processes config change, that subsequent audio EOS completes
1307 // A/V playback.
1308 // Also tests that seeking+Start() after completing playback resumes playback.
1309 CreateNextTextureAndSetVideoSurface();
1310 Start(CreateAudioVideoDemuxerConfigs());
1311
1312 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1313 // Audio |kConfigChanged| as first unit.
1314 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged(
1315 true, 0, CreateAudioDemuxerConfigs(kCodecVorbis, false)));
1316
1317 WaitForAudioVideoDecodeDone();
1318
1319 EXPECT_EQ(3, demuxer_->num_data_requests());
1320
1321 // At no time after completing video EOS decode, above, should the
1322 // video decoder job resume decoding. Send and decode audio EOS.
1323 VerifyPlaybackCompletesOnEOSDecode(true, true);
1324 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true);
1325 }
1326
1327 TEST_F(MediaSourcePlayerTest, AV_NoPrefetchForFinishedVideoOnAudioStarvation) {
1328 // crbug.com/604602 and crbug.com/597836
1329 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1330
1331 // Test that if one stream (video) has completed decode of EOS, prefetch
1332 // resulting from player starvation occurs only for the other stream (audio),
1333 // and responding to that prefetch with EOS completes A/V playback, even if
1334 // another starvation occurs during the latter EOS's decode.
1335 CreateNextTextureAndSetVideoSurface();
1336 Start(CreateAudioVideoDemuxerConfigs());
1337
1338 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1339 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1340
1341 // Wait until video EOS is processed and more data (assumed to be audio) is
1342 // requested.
1343 WaitForAudioVideoDecodeDone();
1344 EXPECT_EQ(3, demuxer_->num_data_requests());
1345
1346 // Simulate decoder underrun to trigger prefetch while still decoding audio.
1347 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1));
1348 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding() &&
1349 !GetMediaDecoderJob(false)->is_decoding());
1350 TriggerPlayerStarvation();
1351
1352 // Complete the audio decode that was in progress when simulated player
1353 // starvation was triggered.
1354 WaitForAudioDecodeDone();
1355 EXPECT_EQ(4, demuxer_->num_data_requests());
1356 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1357 EXPECT_FALSE(GetMediaDecoderJob(false)->is_decoding());
1358 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1359
1360 // Simulate another decoder underrun to trigger prefetch while decoding EOS.
1361 TriggerPlayerStarvation();
1362 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1363 }
1364
1365 TEST_F(MediaSourcePlayerTest, V_StarvationDuringEOSDecode) {
1366 // crbug.com/604602 and crbug.com/597836
1367 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1368
1369 // Test that video-only playback completes without further data requested when
1370 // starvation occurs during EOS decode.
1371 CreateNextTextureAndSetVideoSurface();
1372 StartVideoDecoderJob();
1373 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1374 WaitForVideoDecodeDone();
1375
1376 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1377 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS
1378 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1379 TriggerPlayerStarvation();
1380 VerifyPlaybackCompletesOnEOSDecode(false, false /* ignored */);
1381 }
1382
1383 TEST_F(MediaSourcePlayerTest, A_StarvationDuringEOSDecode) {
1384 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1385
1386 // Test that audio-only playback completes without further data requested when
1387 // starvation occurs during EOS decode.
1388 StartAudioDecoderJob();
1389 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1390 WaitForAudioDecodeDone();
1391
1392 // Simulate decoder underrun to trigger prefetch while decoding EOS.
1393 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS
1394 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1395 TriggerPlayerStarvation();
1396 VerifyPlaybackCompletesOnEOSDecode(false, true /* ignored */);
1397 }
1398
1399 TEST_F(MediaSourcePlayerTest, AV_SeekDuringEOSDecodePreventsCompletion) {
1400 // crbug.com/604602 and crbug.com/597836
1401 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1402
1403 // Test that seek supercedes audio+video playback completion on simultaneous
1404 // audio and video EOS decode, if SeekTo() occurs during these EOS decodes.
1405 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, true);
1406 }
1407
1408 TEST_F(MediaSourcePlayerTest, AV_SeekDuringAudioEOSDecodePreventsCompletion) {
1409 // crbug.com/604602 and crbug.com/597836
1410 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1411
1412 // Test that seek supercedes audio+video playback completion on simultaneous
1413 // audio EOS and video non-EOS decode, if SeekTo() occurs during these
1414 // decodes.
1415 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, false);
1416 }
1417
1418 TEST_F(MediaSourcePlayerTest, AV_SeekDuringVideoEOSDecodePreventsCompletion) {
1419 // crbug.com/604602 and crbug.com/597836
1420 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1421
1422 // Test that seek supercedes audio+video playback completion on simultaneous
1423 // audio non-EOS and video EOS decode, if SeekTo() occurs during these
1424 // decodes.
1425 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, false, true);
1426 }
1427
1428 TEST_F(MediaSourcePlayerTest, V_SeekDuringEOSDecodePreventsCompletion) {
1429 // crbug.com/604602 and crbug.com/597836
1430 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1431
1432 // Test that seek supercedes video-only playback completion on EOS decode, if
1433 // SeekTo() occurs during EOS decode.
1434 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(false, true, false, true);
1435 }
1436
1437 TEST_F(MediaSourcePlayerTest, A_SeekDuringEOSDecodePreventsCompletion) {
1438 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1439
1440 // Test that seek supercedes audio-only playback completion on EOS decode, if
1441 // SeekTo() occurs during EOS decode.
1442 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, false, true, false);
1443 }
1444
1445 TEST_F(MediaSourcePlayerTest, NoRequestForDataAfterAbort) {
1446 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1447
1448 // Test that the decoder will not request new data after receiving an aborted
1449 // access unit.
1450 StartAudioDecoderJob();
1451
1452 // Send an aborted access unit.
1453 player_.OnDemuxerDataAvailable(CreateAbortedAck(true));
1454 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1455 WaitForAudioDecodeDone();
1456
1457 // No request will be sent for new data.
1458 EXPECT_EQ(1, demuxer_->num_data_requests());
1459
1460 // No seek requests should have occurred.
1461 EXPECT_EQ(0, demuxer_->num_seek_requests());
1462 }
1463
1464 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) {
1465 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1466
1467 // Test that the decoder should not crash if demuxer data arrives after
1468 // Release().
1469 StartAudioDecoderJob();
1470
1471 ReleasePlayer();
1472 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1473
1474 // The media codec bridge should have been released.
1475 EXPECT_FALSE(player_.IsPlaying());
1476
1477 // No further data should have been requested.
1478 EXPECT_EQ(1, demuxer_->num_data_requests());
1479
1480 // No seek requests should have occurred.
1481 EXPECT_EQ(0, demuxer_->num_seek_requests());
1482 }
1483
1484 TEST_F(MediaSourcePlayerTest, BrowserSeek_RegularSeekPendsBrowserSeekDone) {
1485 // crbug.com/604602 and crbug.com/597836
1486 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1487
1488 // Test that a browser seek, once started, delays a newly arrived regular
1489 // SeekTo() request's demuxer seek until the browser seek is done.
1490 BrowserSeekPlayer(false);
1491
1492 // Simulate renderer requesting a regular seek while browser seek in progress.
1493 player_.SeekTo(base::TimeDelta());
1494
1495 // Simulate browser seek is done. Confirm player requests the regular seek,
1496 // still has no video codec configured, and has not requested any
1497 // further data since the surface change event became pending in
1498 // BrowserSeekPlayer().
1499 EXPECT_EQ(1, demuxer_->num_seek_requests());
1500 player_.OnDemuxerSeekDone(base::TimeDelta());
1501 EXPECT_EQ(2, demuxer_->num_seek_requests());
1502 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
1503
1504 // Simulate regular seek is done and confirm player requests more data for
1505 // new video codec.
1506 player_.OnDemuxerSeekDone(kNoTimestamp);
1507 EXPECT_FALSE(GetMediaCodecBridge(false));
1508 EXPECT_EQ(3, demuxer_->num_data_requests());
1509 EXPECT_EQ(2, demuxer_->num_seek_requests());
1510 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1511 EXPECT_TRUE(GetMediaCodecBridge(false));
1512 WaitForVideoDecodeDone();
1513 }
1514
1515 TEST_F(MediaSourcePlayerTest, BrowserSeek_InitialReleaseAndStart) {
1516 // crbug.com/604602 and crbug.com/597836
1517 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1518
1519 // Test that no browser seek is requested if player Release() + Start() occurs
1520 // prior to receiving any data.
1521 CreateNextTextureAndSetVideoSurface();
1522 StartVideoDecoderJob();
1523 ReleasePlayer();
1524
1525 // Pass a new non-empty surface.
1526 CreateNextTextureAndSetVideoSurface();
1527
1528 player_.Start();
1529
1530 // No data request is issued since there is still one pending.
1531 EXPECT_EQ(1, demuxer_->num_data_requests());
1532 EXPECT_FALSE(GetMediaCodecBridge(false));
1533
1534 // No browser seek is needed.
1535 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1536 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
1537 EXPECT_EQ(2, demuxer_->num_data_requests());
1538 WaitForVideoDecodeDone();
1539 }
1540
1541 TEST_F(MediaSourcePlayerTest, BrowserSeek_MidStreamReleaseAndStart) {
1542 // crbug.com/604602 and crbug.com/597836
1543 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1544
1545 // Test that one browser seek is requested if player Release() + Start(), with
1546 // video data received between Release() and Start().
1547 BrowserSeekPlayer(true);
1548
1549 // Simulate browser seek is done and confirm player requests more data.
1550 player_.OnDemuxerSeekDone(base::TimeDelta());
1551 EXPECT_EQ(3, demuxer_->num_data_requests());
1552 EXPECT_EQ(1, demuxer_->num_seek_requests());
1553 }
1554
1555 TEST_F(MediaSourcePlayerTest, NoBrowserSeekWithKeyFrameInCache) {
1556 // crbug.com/604602 and crbug.com/597836
1557 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1558
1559 // Test that browser seek is not needed if a key frame is found in data
1560 // cache.
1561 CreateNextTextureAndSetVideoSurface();
1562 StartVideoDecoderJob();
1563 DemuxerData data = CreateReadFromDemuxerAckForVideo(false);
1564 data.access_units[0].is_key_frame = true;
1565
1566 // Simulate demuxer's response to the video data request.
1567 player_.OnDemuxerDataAvailable(data);
1568
1569 // Trigger decoder recreation later by changing surfaces.
1570 CreateNextTextureAndSetVideoSurface();
1571
1572 // Wait for the media codec bridge to finish decoding and be reset.
1573 WaitForVideoDecodeDone();
1574 EXPECT_FALSE(HasData(false));
1575
1576 // Send a non key frame to decoder so that decoder can continue. This will
1577 // not trigger any browser seeks as the previous key frame is still in the
1578 // buffer.
1579 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1580 WaitForVideoDecodeDone();
1581 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
1582 }
1583
1584 TEST_F(MediaSourcePlayerTest, PrerollAudioAfterSeek) {
1585 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1586
1587 // Test decoder job will preroll the media to the seek position.
1588 StartAudioDecoderJob();
1589
1590 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1591 EXPECT_TRUE(IsPrerolling(true));
1592 PrerollDecoderToTime(
1593 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1594 }
1595
1596 TEST_F(MediaSourcePlayerTest, PrerollVideoAfterSeek) {
1597 // crbug.com/604602 and crbug.com/597836
1598 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1599
1600 // Test decoder job will preroll the media to the seek position.
1601 CreateNextTextureAndSetVideoSurface();
1602 StartVideoDecoderJob();
1603
1604 SeekPlayerWithAbort(false, base::TimeDelta::FromMilliseconds(100));
1605 EXPECT_TRUE(IsPrerolling(false));
1606 PrerollDecoderToTime(
1607 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1608 }
1609
1610 TEST_F(MediaSourcePlayerTest, SeekingAfterCompletingPrerollRestartsPreroll) {
1611 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1612
1613 // Test decoder job will begin prerolling upon seek, when it was not
1614 // prerolling prior to the seek.
1615 StartAudioDecoderJob();
1616 MediaDecoderJob* decoder_job = GetMediaDecoderJob(true);
1617 EXPECT_TRUE(IsPrerolling(true));
1618
1619 // Complete the initial preroll by feeding data to the decoder.
1620 DecodeAudioDataUntilOutputBecomesAvailable();
1621 EXPECT_FALSE(IsPrerolling(true));
1622
1623 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(500));
1624
1625 // Prerolling should have begun again.
1626 EXPECT_TRUE(IsPrerolling(true));
1627 EXPECT_EQ(500.0, GetPrerollTimestamp().InMillisecondsF());
1628
1629 // Send data at and after the seek position. Prerolling should complete.
1630 for (int i = 0; i < 4; ++i) {
1631 DemuxerData data = CreateReadFromDemuxerAckForAudio(i);
1632 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(
1633 500 + 30 * (i - 1));
1634 player_.OnDemuxerDataAvailable(data);
1635 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1636 WaitForAudioDecodeDone();
1637 }
1638 EXPECT_LT(500.0, player_.GetCurrentTime().InMillisecondsF());
1639 EXPECT_FALSE(IsPrerolling(true));
1640
1641 // Throughout this test, we should have not re-created the media codec bridge,
1642 // so IsPrerolling() transition from false to true was not due to constructor
1643 // initialization. It was due to BeginPrerolling().
1644 EXPECT_EQ(decoder_job, GetMediaDecoderJob(true));
1645 }
1646
1647 TEST_F(MediaSourcePlayerTest, PrerollContinuesAcrossReleaseAndStart) {
1648 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1649
1650 // Test decoder job will resume media prerolling if interrupted by Release()
1651 // and Start().
1652 StartAudioDecoderJob();
1653
1654 base::TimeDelta target_timestamp = base::TimeDelta::FromMilliseconds(100);
1655 SeekPlayerWithAbort(true, target_timestamp);
1656 EXPECT_TRUE(IsPrerolling(true));
1657 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1658
1659 // Send some data before the seek position.
1660 // Test uses 'large' number of iterations because decoder job may not get
1661 // MEDIA_CODEC_OK output status until after a few dequeue output attempts.
1662 // This allows decoder status to stabilize prior to AU timestamp reaching
1663 // the preroll target.
1664 DemuxerData data;
1665 for (int i = 0; i < 10; ++i) {
1666 data = CreateReadFromDemuxerAckForAudio(3);
1667 data.access_units[0].timestamp = base::TimeDelta::FromMilliseconds(i * 10);
1668 if (i == 1) {
1669 // While still prerolling, Release() and Start() the player.
1670 ReleasePlayer();
1671 // The decoder is still decoding and will not be immediately released.
1672 EXPECT_TRUE(GetMediaCodecBridge(true));
1673 Resume(false, false);
1674 } else {
1675 player_.OnDemuxerDataAvailable(data);
1676 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1677 WaitForAudioDecodeDone();
1678 }
1679 EXPECT_TRUE(IsPrerolling(true));
1680 }
1681 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1682 EXPECT_TRUE(IsPrerolling(true));
1683
1684 // Send data after the seek position.
1685 PrerollDecoderToTime(true, target_timestamp, target_timestamp, true);
1686 }
1687
1688 // Flaky on Android: crbug.com/419122.
1689 #if defined(OS_ANDROID)
1690 #define MAYBE_PrerollContinuesAcrossConfigChange \
1691 DISABLED_PrerollContinuesAcrossConfigChange
1692 #else
1693 #define MAYBE_PrerollContinuesAcrossConfigChange \
1694 PrerollContinuesAcrossConfigChange
1695 #endif
1696 TEST_F(MediaSourcePlayerTest, MAYBE_PrerollContinuesAcrossConfigChange) {
1697 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1698
1699 // Test decoder job will resume media prerolling if interrupted by
1700 // |kConfigChanged| and OnDemuxerConfigsAvailable().
1701 StartAudioDecoderJob();
1702
1703 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1704 EXPECT_TRUE(IsPrerolling(true));
1705 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1706
1707 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, true);
1708
1709 // In response to data request, simulate that demuxer signals config change by
1710 // sending an AU with |kConfigChanged|.
1711 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(
1712 true, 0, configs);
1713 player_.OnDemuxerDataAvailable(data);
1714
1715 PrerollDecoderToTime(
1716 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1717 }
1718
1719 TEST_F(MediaSourcePlayerTest, PrerollContinuesAfterUnchangedConfigs) {
1720 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1721
1722 // Test decoder job will resume media prerolling if interrupted by a config
1723 // change access unit with unchanged configs.
1724 StartAudioDecoderJob();
1725
1726 SeekPlayerWithAbort(true, base::TimeDelta::FromMilliseconds(100));
1727 EXPECT_TRUE(IsPrerolling(true));
1728 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1729
1730 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, false);
1731
1732 // In response to data request, simulate that demuxer signals config change by
1733 // sending an AU with |kConfigChanged|.
1734 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(
1735 true, 0, configs);
1736 player_.OnDemuxerDataAvailable(data);
1737 PrerollDecoderToTime(
1738 true, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1739 }
1740
1741 TEST_F(MediaSourcePlayerTest, AudioPrerollFinishesBeforeVideo) {
1742 // crbug.com/604602 and crbug.com/597836
1743 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1744
1745 // Test that after audio finishes prerolling, it will wait for video to finish
1746 // prerolling before advancing together.
1747 CreateNextTextureAndSetVideoSurface();
1748 Start(CreateAudioVideoDemuxerConfigs());
1749
1750 // Initiate a seek.
1751 base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(100);
1752 player_.SeekTo(seek_position);
1753 player_.OnDemuxerDataAvailable(CreateAbortedAck(true));
1754 player_.OnDemuxerDataAvailable(CreateAbortedAck(false));
1755 WaitForDecodeDone(true, true);
1756
1757 // Verify that the seek is requested.
1758 EXPECT_EQ(1, demuxer_->num_seek_requests());
1759 player_.OnDemuxerSeekDone(kNoTimestamp);
1760 EXPECT_EQ(4, demuxer_->num_data_requests());
1761 EXPECT_EQ(player_.GetCurrentTime().InMillisecondsF(), 100.0);
1762 EXPECT_EQ(GetPrerollTimestamp().InMillisecondsF(), 100.0);
1763
1764 // Send both audio and video data to finish prefetching.
1765 base::TimeDelta seek_ack_position = base::TimeDelta::FromMilliseconds(70);
1766 DemuxerData audio_data = CreateReadFromDemuxerAckForAudio(0);
1767 audio_data.access_units[0].timestamp = seek_ack_position;
1768 DemuxerData video_data = CreateReadFromDemuxerAckForVideo(false);
1769 video_data.access_units[0].timestamp = seek_ack_position;
1770 player_.OnDemuxerDataAvailable(audio_data);
1771 player_.OnDemuxerDataAvailable(video_data);
1772 WaitForAudioDecodeDone();
1773 WaitForVideoDecodeDone();
1774
1775 // Send audio data at and after the seek position. Audio should finish
1776 // prerolling and stop decoding.
1777 EXPECT_EQ(6, demuxer_->num_data_requests());
1778 PrerollDecoderToTime(true, seek_position, seek_position, true);
1779 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding());
1780 EXPECT_FALSE(IsPrerolling(true));
1781 EXPECT_TRUE(IsPrerolling(false));
1782
1783 // Send video data to let video finish prerolling.
1784 PrerollDecoderToTime(false, seek_position, seek_position, false);
1785 EXPECT_FALSE(IsPrerolling(false));
1786
1787 // Both audio and video decoders should start decoding again.
1788 player_.OnDemuxerDataAvailable(audio_data);
1789 player_.OnDemuxerDataAvailable(video_data);
1790 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
1791 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding());
1792 }
1793
1794 TEST_F(MediaSourcePlayerTest, SimultaneousAudioVideoConfigChange) {
1795 // crbug.com/604602 and crbug.com/597836
1796 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1797
1798 // Test that the player allows simultaneous audio and video config change,
1799 // such as might occur during OnPrefetchDone() if next access unit for both
1800 // audio and video jobs is |kConfigChanged|.
1801 CreateNextTextureAndSetVideoSurface();
1802 Start(CreateAudioVideoDemuxerConfigs());
1803 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1804 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1805 EXPECT_TRUE(GetMediaCodecBridge(true));
1806 EXPECT_TRUE(GetMediaCodecBridge(false));
1807 EnableAdaptiveVideoPlayback(false);
1808 WaitForAudioVideoDecodeDone();
1809
1810 // If audio or video hasn't finished prerolling, let them finish it.
1811 if (IsPrerolling(true))
1812 PrerollDecoderToTime(true, base::TimeDelta(), base::TimeDelta(), true);
1813 if (IsPrerolling(false))
1814 PrerollDecoderToTime(false, base::TimeDelta(), base::TimeDelta(), false);
1815 int expected_num_data_requests = demuxer_->num_data_requests();
1816
1817 // Simulate audio |kConfigChanged| prefetched as standalone access unit.
1818 DemuxerConfigs audio_configs = CreateAudioDemuxerConfigs(kCodecVorbis, true);
1819 player_.OnDemuxerDataAvailable(
1820 CreateReadFromDemuxerAckWithConfigChanged(true, 0, audio_configs));
1821
1822 // Simulate video |kConfigChanged| prefetched as standalone access unit.
1823 player_.OnDemuxerDataAvailable(
1824 CreateReadFromDemuxerAckWithConfigChanged(
1825 false, 0, CreateVideoDemuxerConfigs(true)));
1826 EXPECT_EQ(expected_num_data_requests + 2, demuxer_->num_data_requests());
1827 EXPECT_TRUE(IsDrainingDecoder(true));
1828 EXPECT_TRUE(IsDrainingDecoder(false));
1829
1830 // Waiting for decoder to finish draining.
1831 while (IsDrainingDecoder(true) || IsDrainingDecoder(false))
1832 base::RunLoop().RunUntilIdle();
1833 }
1834
1835 TEST_F(MediaSourcePlayerTest,
1836 SimultaneousAudioVideoConfigChangeWithAdaptivePlayback) {
1837 // crbug.com/604602 and crbug.com/597836
1838 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1839
1840 // Test that the player allows simultaneous audio and video config change with
1841 // adaptive video playback enabled.
1842 CreateNextTextureAndSetVideoSurface();
1843 Start(CreateAudioVideoDemuxerConfigs());
1844 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
1845 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
1846 EXPECT_EQ(4, demuxer_->num_data_requests());
1847 EXPECT_TRUE(GetMediaCodecBridge(true));
1848 EXPECT_TRUE(GetMediaCodecBridge(false));
1849 EnableAdaptiveVideoPlayback(true);
1850 WaitForAudioVideoDecodeDone();
1851
1852 // If audio or video hasn't finished prerolling, let them finish it.
1853 if (IsPrerolling(true))
1854 PrerollDecoderToTime(true, base::TimeDelta(), base::TimeDelta(), true);
1855 if (IsPrerolling(false))
1856 PrerollDecoderToTime(false, base::TimeDelta(), base::TimeDelta(), false);
1857 int expected_num_data_requests = demuxer_->num_data_requests();
1858
1859 // Simulate audio |kConfigChanged| prefetched as standalone access unit.
1860 DemuxerConfigs audio_configs = CreateAudioDemuxerConfigs(kCodecVorbis, true);
1861 player_.OnDemuxerDataAvailable(
1862 CreateReadFromDemuxerAckWithConfigChanged(true, 0, audio_configs));
1863
1864 // Simulate video |kConfigChanged| prefetched as standalone access unit.
1865 player_.OnDemuxerDataAvailable(
1866 CreateReadFromDemuxerAckWithConfigChanged(
1867 false, 0, CreateVideoDemuxerConfigs(true)));
1868 EXPECT_EQ(expected_num_data_requests + 2, demuxer_->num_data_requests());
1869 EXPECT_TRUE(IsDrainingDecoder(true));
1870 EXPECT_FALSE(IsDrainingDecoder(false));
1871
1872 // Waiting for audio decoder to finish draining.
1873 while (IsDrainingDecoder(true))
1874 base::RunLoop().RunUntilIdle();
1875 }
1876
1877 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInPrefetchUnit0) {
1878 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1879
1880 // Test that the player detects need for and requests demuxer configs if
1881 // the |kConfigChanged| unit is the very first unit in the set of units
1882 // received in OnDemuxerDataAvailable() ostensibly while
1883 // |PREFETCH_DONE_EVENT_PENDING|.
1884 StartConfigChange(true, true, 0, false);
1885 WaitForAudioDecodeDone();
1886 }
1887
1888 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInPrefetchUnit1) {
1889 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1890
1891 // Test that the player detects need for and requests demuxer configs if
1892 // the |kConfigChanged| unit is not the first unit in the set of units
1893 // received in OnDemuxerDataAvailable() ostensibly while
1894 // |PREFETCH_DONE_EVENT_PENDING|.
1895 StartConfigChange(true, true, 1, false);
1896 WaitForAudioDecodeDone();
1897 }
1898
1899 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInUnit0AfterPrefetch) {
1900 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1901
1902 // Test that the player detects need for and requests demuxer configs if
1903 // the |kConfigChanged| unit is the very first unit in the set of units
1904 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1905 // not prefetching.
1906 StartConfigChange(true, false, 0, false);
1907 WaitForAudioDecodeDone();
1908 }
1909
1910 TEST_F(MediaSourcePlayerTest, DemuxerConfigRequestedIfInUnit1AfterPrefetch) {
1911 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1912
1913 // Test that the player detects need for and requests demuxer configs if
1914 // the |kConfigChanged| unit is not the first unit in the set of units
1915 // received in OnDemuxerDataAvailable() from data requested ostensibly while
1916 // not prefetching.
1917 StartConfigChange(true, false, 1, false);
1918 WaitForAudioDecodeDone();
1919 }
1920
1921 TEST_F(MediaSourcePlayerTest, BrowserSeek_PrerollAfterBrowserSeek) {
1922 // crbug.com/604602 and crbug.com/597836
1923 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1924
1925 // Test decoder job will preroll the media to the actual seek position
1926 // resulting from a browser seek.
1927 BrowserSeekPlayer(false);
1928
1929 // Simulate browser seek is done, but to a later time than was requested.
1930 EXPECT_LT(player_.GetCurrentTime().InMillisecondsF(), 100);
1931 player_.OnDemuxerSeekDone(base::TimeDelta::FromMilliseconds(100));
1932 // Because next AU is not I-frame, MediaCodecBridge will not be recreated.
1933 EXPECT_FALSE(GetMediaCodecBridge(false));
1934 EXPECT_EQ(100.0, player_.GetCurrentTime().InMillisecondsF());
1935 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
1936 EXPECT_EQ(3, demuxer_->num_data_requests());
1937
1938 PrerollDecoderToTime(
1939 false, base::TimeDelta(), base::TimeDelta::FromMilliseconds(100), true);
1940 }
1941
1942 TEST_F(MediaSourcePlayerTest, VideoDemuxerConfigChange) {
1943 // crbug.com/604602 and crbug.com/597836
1944 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1945
1946 // Test that video config change notification results in creating a new
1947 // video codec without any browser seek.
1948 StartConfigChange(false, true, 1, false);
1949
1950 // New video codec should have been created and configured, without any
1951 // browser seek.
1952 EXPECT_TRUE(GetMediaCodecBridge(false));
1953 EXPECT_EQ(3, demuxer_->num_data_requests());
1954 EXPECT_EQ(0, demuxer_->num_seek_requests());
1955 WaitForVideoDecodeDone();
1956 }
1957
1958 TEST_F(MediaSourcePlayerTest, VideoDemuxerConfigChangeWithAdaptivePlayback) {
1959 // crbug.com/604602 and crbug.com/597836
1960 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
1961
1962 // Test that if codec supports adaptive playback, no new codec should be
1963 // created beyond the one used to decode the prefetch media data prior to
1964 // the kConfigChanged.
1965 StartConfigChange(false, true, 1, true);
1966
1967 // No browser seek should be needed.
1968 EXPECT_TRUE(GetMediaCodecBridge(false));
1969 EXPECT_EQ(3, demuxer_->num_data_requests());
1970 EXPECT_EQ(0, demuxer_->num_seek_requests());
1971 WaitForVideoDecodeDone();
1972 }
1973
1974 TEST_F(MediaSourcePlayerTest, DecoderDrainInterruptedBySeek) {
1975 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1976
1977 // Test if a decoder is being drained while receiving a seek request, draining
1978 // is canceled.
1979 SendConfigChangeToDecoder(true, false, 0, false);
1980 EXPECT_TRUE(IsDrainingDecoder(true));
1981
1982 player_.SeekTo(base::TimeDelta::FromMilliseconds(100));
1983 WaitForAudioDecodeDone();
1984 EXPECT_FALSE(IsDrainingDecoder(true));
1985 player_.OnDemuxerSeekDone(kNoTimestamp);
1986
1987 EXPECT_EQ(1, demuxer_->num_seek_requests());
1988 EXPECT_EQ(4, demuxer_->num_data_requests());
1989 }
1990
1991 TEST_F(MediaSourcePlayerTest, DecoderDrainInterruptedByRelease) {
1992 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
1993
1994 // Test if a decoder is being drained while receiving a release request,
1995 // draining is canceled.
1996 SendConfigChangeToDecoder(true, false, 0, false);
1997 EXPECT_TRUE(IsDrainingDecoder(true));
1998
1999 ReleasePlayer();
2000 WaitForAudioDecodeDone();
2001 EXPECT_EQ(3, demuxer_->num_data_requests());
2002 EXPECT_FALSE(IsDrainingDecoder(true));
2003
2004 EXPECT_FALSE(GetMediaCodecBridge(true));
2005 EXPECT_FALSE(player_.IsPlaying());
2006
2007 player_.Start();
2008 EXPECT_TRUE(player_.IsPlaying());
2009 EXPECT_EQ(3, demuxer_->num_data_requests());
2010 }
2011
2012 TEST_F(MediaSourcePlayerTest, DecoderDrainInterruptedBySurfaceChange) {
2013 // crbug.com/604602 and crbug.com/597836
2014 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
2015
2016 // Test if a video decoder is being drained while surface changes, draining
2017 // is canceled.
2018 SendConfigChangeToDecoder(false, false, 0, false);
2019 EXPECT_TRUE(IsDrainingDecoder(false));
2020
2021 CreateNextTextureAndSetVideoSurface();
2022 WaitForVideoDecodeDone();
2023
2024 EXPECT_FALSE(IsDrainingDecoder(false));
2025 EXPECT_TRUE(player_.IsPlaying());
2026
2027 // The frame after the config change should always be an iframe, so no browser
2028 // seek is needed when recreating the video decoder due to surface change.
2029 EXPECT_TRUE(GetMediaCodecBridge(false));
2030 EXPECT_EQ(4, demuxer_->num_data_requests());
2031 EXPECT_EQ(0, demuxer_->num_seek_requests());
2032 }
2033
2034 TEST_F(MediaSourcePlayerTest,
2035 BrowserSeek_DecoderStarvationWhilePendingSurfaceChange) {
2036 // crbug.com/604602 and crbug.com/597836
2037 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
2038
2039 // Test video decoder starvation while handling a pending surface change
2040 // should not cause any crashes.
2041 CreateNextTextureAndSetVideoSurface();
2042 StartVideoDecoderJob();
2043 DemuxerData data = CreateReadFromDemuxerAckForVideo(false);
2044 player_.OnDemuxerDataAvailable(data);
2045
2046 // Trigger a surface change and decoder starvation.
2047 CreateNextTextureAndSetVideoSurface();
2048 TriggerPlayerStarvation();
2049 WaitForVideoDecodeDone();
2050 EXPECT_EQ(0, demuxer_->num_browser_seek_requests());
2051
2052 // Surface change should trigger a seek.
2053 player_.OnDemuxerDataAvailable(data);
2054 EXPECT_EQ(1, demuxer_->num_browser_seek_requests());
2055 player_.OnDemuxerSeekDone(base::TimeDelta());
2056 // After seek is done, prefetch is handled first. MediaCodecBridge is not
2057 // created at this moment.
2058 EXPECT_FALSE(GetMediaCodecBridge(false));
2059
2060 // A new data request should be sent.
2061 EXPECT_EQ(3, demuxer_->num_data_requests());
2062 }
2063
2064 TEST_F(MediaSourcePlayerTest, ReleaseWithOnPrefetchDoneAlreadyPosted) {
2065 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2066
2067 // Test if OnPrefetchDone() had already been posted before and is executed
2068 // after Release(), then player does not DCHECK. This test is fragile to
2069 // change to MediaDecoderJob::Prefetch() implementation; it assumes task
2070 // is posted to run |prefetch_cb| if the job already HasData().
2071 // TODO(wolenetz): Remove MSP::set_decode_callback_for_testing() if this test
2072 // becomes obsolete. See http://crbug.com/304234.
2073 StartAudioDecoderJob();
2074
2075 // Escape the original prefetch by decoding a single access unit.
2076 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0));
2077 WaitForAudioDecodeDone();
2078
2079 // Prime the job with a few more access units, so that a later prefetch,
2080 // triggered by starvation to simulate decoder underrun, can trivially
2081 // post task to run OnPrefetchDone().
2082 player_.OnDemuxerDataAvailable(
2083 CreateReadFromDemuxerAckWithConfigChanged(
2084 true, 4, CreateAudioDemuxerConfigs(kCodecVorbis, false)));
2085 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding());
2086
2087 // Simulate decoder underrun, so trivial prefetch starts while still decoding.
2088 // The prefetch and posting of OnPrefetchDone() will not occur until next
2089 // MediaDecoderCallBack() occurs.
2090 TriggerPlayerStarvation();
2091
2092 // Upon the next successful decode callback, post a task to call Release() on
2093 // the |player_|, such that the trivial OnPrefetchDone() task posting also
2094 // occurs and should execute after the Release().
2095 OnNextTestDecodeCallbackPostTaskToReleasePlayer();
2096
2097 WaitForAudioDecodeDone();
2098 EXPECT_TRUE(decoder_callback_hook_executed_);
2099
2100 EXPECT_EQ(3, demuxer_->num_data_requests());
2101
2102 // Player should not request any new data since the access units haven't
2103 // been fully decoded yet.
2104 Resume(false, false);
2105 }
2106
2107 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekAndDone) {
2108 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2109
2110 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
2111 // has not yet been sent, then the seek request is sent after Release(). Also,
2112 // test if OnDemuxerSeekDone() occurs prior to next Start(), then the player
2113 // will resume correct post-seek preroll upon Start().
2114 StartAudioDecoderJobAndSeekToWhileDecoding(
2115 base::TimeDelta::FromMilliseconds(100));
2116 ReleasePlayer();
2117 EXPECT_EQ(0, demuxer_->num_seek_requests());
2118 WaitForAudioDecodeDone();
2119 EXPECT_EQ(1, demuxer_->num_seek_requests());
2120
2121 player_.OnDemuxerSeekDone(kNoTimestamp);
2122 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2123 EXPECT_FALSE(GetMediaCodecBridge(true));
2124 EXPECT_FALSE(player_.IsPlaying());
2125
2126 // Player should begin prefetch and resume preroll upon Start().
2127 EXPECT_EQ(2, demuxer_->num_data_requests());
2128 Resume(true, false);
2129 EXPECT_TRUE(IsPrerolling(true));
2130 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2131
2132 // No further seek should have been requested since Release(), above.
2133 EXPECT_EQ(1, demuxer_->num_seek_requests());
2134 }
2135
2136 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenDemuxerSeekThenStart) {
2137 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2138
2139 // Test if Release() occurs after SeekTo(), but the DemuxerSeek IPC request
2140 // has not yet been sent, then the seek request is sent after Release(). Also,
2141 // test if OnDemuxerSeekDone() does not occur until after the next Start(),
2142 // then the player remains pending seek done until (and resumes correct
2143 // post-seek preroll after) OnDemuxerSeekDone().
2144 StartAudioDecoderJobAndSeekToWhileDecoding(
2145 base::TimeDelta::FromMilliseconds(100));
2146 ReleasePlayer();
2147 EXPECT_EQ(0, demuxer_->num_seek_requests());
2148
2149 // Player should not prefetch upon Start() nor create the media codec bridge,
2150 // due to awaiting DemuxerSeekDone.
2151 EXPECT_EQ(2, demuxer_->num_data_requests());
2152 Resume(false, false);
2153
2154 WaitForAudioDecodeDone();
2155 EXPECT_EQ(1, demuxer_->num_seek_requests());
2156 player_.OnDemuxerSeekDone(kNoTimestamp);
2157 EXPECT_TRUE(GetMediaDecoderJob(true));
2158 EXPECT_TRUE(IsPrerolling(true));
2159 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2160 EXPECT_EQ(3, demuxer_->num_data_requests());
2161
2162 // No further seek should have been requested since Release(), above.
2163 EXPECT_EQ(1, demuxer_->num_seek_requests());
2164 }
2165
2166 TEST_F(MediaSourcePlayerTest, SeekToThenDemuxerSeekThenReleaseThenSeekDone) {
2167 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2168
2169 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC
2170 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the
2171 // player will resume correct post-seek preroll upon Start().
2172 StartAudioDecoderJobAndSeekToWhileDecoding(
2173 base::TimeDelta::FromMilliseconds(100));
2174 WaitForAudioDecodeDone();
2175 EXPECT_EQ(1, demuxer_->num_seek_requests());
2176
2177 ReleasePlayer();
2178 player_.OnDemuxerSeekDone(kNoTimestamp);
2179 EXPECT_FALSE(player_.IsPlaying());
2180 EXPECT_FALSE(GetMediaCodecBridge(true));
2181 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2182
2183 // Player should begin prefetch and resume preroll upon Start().
2184 EXPECT_EQ(2, demuxer_->num_data_requests());
2185 Resume(true, false);
2186 EXPECT_TRUE(IsPrerolling(true));
2187 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2188
2189 // No further seek should have been requested since before Release(), above.
2190 EXPECT_EQ(1, demuxer_->num_seek_requests());
2191 }
2192
2193 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenStart) {
2194 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2195
2196 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC
2197 // request and OnDemuxerSeekDone() does not occur until after the next
2198 // Start(), then the player remains pending seek done until (and resumes
2199 // correct post-seek preroll after) OnDemuxerSeekDone().
2200 StartAudioDecoderJobAndSeekToWhileDecoding(
2201 base::TimeDelta::FromMilliseconds(100));
2202 WaitForAudioDecodeDone();
2203 EXPECT_EQ(1, demuxer_->num_seek_requests());
2204
2205 ReleasePlayer();
2206 EXPECT_EQ(2, demuxer_->num_data_requests());
2207 Resume(false, false);
2208
2209 player_.OnDemuxerSeekDone(kNoTimestamp);
2210 EXPECT_FALSE(GetMediaCodecBridge(true));
2211 EXPECT_TRUE(IsPrerolling(true));
2212 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF());
2213 EXPECT_EQ(3, demuxer_->num_data_requests());
2214
2215 // No further seek should have been requested since before Release(), above.
2216 EXPECT_EQ(1, demuxer_->num_seek_requests());
2217 }
2218
2219 TEST_F(MediaSourcePlayerTest, ConfigChangedThenReleaseThenStart) {
2220 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2221
2222 // Test if Release() occurs after |kConfigChanged| is processed, new data
2223 // requested of demuxer, and the requested data arrive before the next
2224 // Start(), then the player starts to decode the new data without any seek.
2225 StartConfigChange(true, true, 0, false);
2226 ReleasePlayer();
2227
2228 EXPECT_TRUE(GetMediaCodecBridge(true));
2229 EXPECT_FALSE(player_.IsPlaying());
2230 EXPECT_EQ(3, demuxer_->num_data_requests());
2231 player_.OnDemuxerDataAvailable(
2232 CreateReadFromDemuxerAckWithConfigChanged(
2233 true, 4, CreateAudioDemuxerConfigs(kCodecVorbis, false)));
2234 WaitForAudioDecodeDone();
2235 EXPECT_FALSE(GetMediaCodecBridge(true));
2236
2237 // Player should resume upon Start(), even without further configs supplied.
2238 player_.Start();
2239 EXPECT_TRUE(player_.IsPlaying());
2240 EXPECT_EQ(3, demuxer_->num_data_requests());
2241 EXPECT_EQ(0, demuxer_->num_seek_requests());
2242 WaitForAudioDecodeDone();
2243 }
2244
2245 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenDemuxerSeekDone) {
2246 // crbug.com/604602 and crbug.com/597836
2247 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
2248
2249 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
2250 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() occurs
2251 // before the next Start()+SetVideoSurface(), then the player will resume
2252 // correct post-seek preroll upon Start()+SetVideoSurface().
2253 BrowserSeekPlayer(false);
2254 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
2255 ReleasePlayer();
2256
2257 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
2258 EXPECT_FALSE(player_.IsPlaying());
2259 EXPECT_FALSE(GetMediaCodecBridge(false));
2260 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
2261
2262 // Player should begin prefetch and resume preroll upon Start().
2263 EXPECT_EQ(2, demuxer_->num_data_requests());
2264 CreateNextTextureAndSetVideoSurface();
2265 Resume(false, true);
2266 EXPECT_TRUE(IsPrerolling(false));
2267 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
2268 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
2269
2270 // No further seek should have been requested since BrowserSeekPlayer().
2271 EXPECT_EQ(1, demuxer_->num_seek_requests());
2272 }
2273
2274 TEST_F(MediaSourcePlayerTest, BrowserSeek_ThenReleaseThenStart) {
2275 // crbug.com/604602 and crbug.com/597836
2276 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
2277
2278 // Test that Release() after a browser seek's DemuxerSeek IPC request has been
2279 // sent behaves similar to a regular seek: if OnDemuxerSeekDone() does not
2280 // occur until after the next Start()+SetVideoSurface(), then the player
2281 // remains pending seek done until (and resumes correct post-seek preroll
2282 // after) OnDemuxerSeekDone().
2283 BrowserSeekPlayer(false);
2284 base::TimeDelta expected_preroll_timestamp = player_.GetCurrentTime();
2285 ReleasePlayer();
2286
2287 EXPECT_EQ(2, demuxer_->num_data_requests());
2288 CreateNextTextureAndSetVideoSurface();
2289 Resume(false, false);
2290
2291 player_.OnDemuxerSeekDone(expected_preroll_timestamp);
2292 // Prefetch takes place first, and the decoder is not created yet.
2293 EXPECT_FALSE(GetMediaCodecBridge(false));
2294 EXPECT_TRUE(IsPrerolling(false));
2295 EXPECT_EQ(expected_preroll_timestamp, GetPrerollTimestamp());
2296 EXPECT_EQ(expected_preroll_timestamp, player_.GetCurrentTime());
2297 EXPECT_EQ(3, demuxer_->num_data_requests());
2298
2299 // No further seek should have been requested since BrowserSeekPlayer().
2300 EXPECT_EQ(1, demuxer_->num_seek_requests());
2301
2302 // Decoder will be created once data is received.
2303 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo(false));
2304 EXPECT_TRUE(GetMediaCodecBridge(false));
2305 WaitForVideoDecodeDone();
2306 }
2307
2308 // TODO(xhwang): Once we add tests to cover DrmBridge, update this test to
2309 // also verify that the job is successfully created if SetDrmBridge(), Start()
2310 // and eventually OnMediaCrypto() occur. This would increase test coverage of
2311 // http://crbug.com/313470 and allow us to remove inspection of internal player
2312 // pending event state. See http://crbug.com/313860.
2313 TEST_F(MediaSourcePlayerTest, SurfaceChangeClearedEvenIfMediaCryptoAbsent) {
2314 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2315
2316 // Test that |SURFACE_CHANGE_EVENT_PENDING| is not pending after
2317 // SetVideoSurface() for a player configured for encrypted video, when the
2318 // player has not yet received media crypto.
2319 DemuxerConfigs configs = CreateVideoDemuxerConfigs(false);
2320 configs.is_video_encrypted = true;
2321
2322 player_.OnDemuxerConfigsAvailable(configs);
2323 CreateNextTextureAndSetVideoSurface();
2324 EXPECT_FALSE(GetMediaCodecBridge(false));
2325 }
2326
2327 TEST_F(MediaSourcePlayerTest, CurrentTimeUpdatedWhileDecoderStarved) {
2328 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2329
2330 // Test that current time is updated while decoder is starved.
2331 StartAudioDecoderJob();
2332 DecodeAudioDataUntilOutputBecomesAvailable();
2333
2334 // Trigger starvation while the decoder is decoding.
2335 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3));
2336 manager_.ResetTimestampUpdated();
2337 TriggerPlayerStarvation();
2338 WaitForAudioDecodeDone();
2339
2340 // Current time should be updated.
2341 EXPECT_TRUE(manager_.timestamp_updated());
2342 }
2343
2344 TEST_F(MediaSourcePlayerTest, CurrentTimeKeepsIncreasingAfterConfigChange) {
2345 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2346
2347 // Test current time keep on increasing after audio config change.
2348 // Test that current time is updated while decoder is starved.
2349 StartAudioDecoderJob();
2350
2351 DecodeAudioDataUntilOutputBecomesAvailable();
2352
2353 DemuxerConfigs configs = CreateAudioDemuxerConfigs(kCodecVorbis, true);
2354 DemuxerData data = CreateReadFromDemuxerAckWithConfigChanged(
2355 true, 0, configs);
2356 player_.OnDemuxerDataAvailable(data);
2357 WaitForAudioDecodeDone();
2358 DecodeAudioDataUntilOutputBecomesAvailable();
2359 }
2360
2361 TEST_F(MediaSourcePlayerTest, VideoMetadataChangeAfterConfigChange) {
2362 // crbug.com/604602 and crbug.com/597836
2363 SKIP_TEST_IF_VP8_DECODER_IS_NOT_SUPPORTED();
2364
2365 // Test that after a config change, metadata change will be happen
2366 // after decoder is drained.
2367 StartConfigChange(false, true, 2, false);
2368 EXPECT_EQ(1, manager_.num_metadata_changes());
2369 EXPECT_FALSE(IsDrainingDecoder(false));
2370
2371 // Create video data with new resolutions.
2372 DemuxerData data = CreateReadFromDemuxerAckForVideo(true);
2373
2374 // Wait for the metadata change.
2375 while(manager_.num_metadata_changes() == 1) {
2376 player_.OnDemuxerDataAvailable(data);
2377 WaitForVideoDecodeDone();
2378 }
2379 EXPECT_EQ(2, manager_.num_metadata_changes());
2380 WaitForVideoDecodeDone();
2381 }
2382
2383 TEST_F(MediaSourcePlayerTest, RequestPlayDeniedDontPlay_Audio) {
2384 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2385
2386 EXPECT_EQ(demuxer_->num_data_requests(), 0);
2387 player_.OnDemuxerConfigsAvailable(CreateDemuxerConfigs(true, false));
2388
2389 manager_.set_allow_play(false);
2390 player_.Start();
2391 EXPECT_FALSE(player_.IsPlaying());
2392 }
2393
2394 TEST_F(MediaSourcePlayerTest, RequestPlayDeniedDontPlay_Video) {
2395 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2396
2397 EXPECT_EQ(demuxer_->num_data_requests(), 0);
2398 player_.OnDemuxerConfigsAvailable(CreateDemuxerConfigs(false, true));
2399
2400 manager_.set_allow_play(false);
2401 player_.Start();
2402 EXPECT_FALSE(player_.IsPlaying());
2403 }
2404
2405 TEST_F(MediaSourcePlayerTest, RequestPlayDeniedDontPlay_AV) {
2406 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2407
2408 EXPECT_EQ(demuxer_->num_data_requests(), 0);
2409 player_.OnDemuxerConfigsAvailable(CreateDemuxerConfigs(true, true));
2410
2411 manager_.set_allow_play(false);
2412 player_.Start();
2413 EXPECT_FALSE(player_.IsPlaying());
2414 }
2415
2416 TEST_F(MediaSourcePlayerTest, RequestPlayGrantedPlays) {
2417 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
2418
2419 EXPECT_EQ(demuxer_->num_data_requests(), 0);
2420 player_.OnDemuxerConfigsAvailable(CreateDemuxerConfigs(true, true));
2421
2422 manager_.set_allow_play(true);
2423 player_.Start();
2424 EXPECT_TRUE(player_.IsPlaying());
2425 }
2426
2427 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698