Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "media/base/android/media_codec_bridge.h" | 10 #include "media/base/android/media_codec_bridge.h" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 configs.video_codec = kCodecVP8; | 273 configs.video_codec = kCodecVP8; |
| 274 configs.video_size = gfx::Size(320, 240); | 274 configs.video_size = gfx::Size(320, 240); |
| 275 configs.is_video_encrypted = false; | 275 configs.is_video_encrypted = false; |
| 276 return configs; | 276 return configs; |
| 277 } | 277 } |
| 278 | 278 |
| 279 void StartVideoDecoderJob() { | 279 void StartVideoDecoderJob() { |
| 280 Start(CreateVideoDemuxerConfigs()); | 280 Start(CreateVideoDemuxerConfigs()); |
| 281 } | 281 } |
| 282 | 282 |
| 283 DemuxerConfigs CreateDemuxerConfigs(bool have_audio, bool have_video) { | |
| 284 DCHECK(have_audio || have_video); | |
| 285 | |
| 286 if (have_audio && !have_video) | |
| 287 return CreateAudioDemuxerConfigs(kCodecVorbis); | |
| 288 | |
| 289 if (have_video && !have_audio) | |
| 290 return CreateVideoDemuxerConfigs(); | |
| 291 | |
| 292 return CreateAudioVideoDemuxerConfigs(); | |
| 293 } | |
| 294 | |
| 283 // Starts decoding the data. | 295 // Starts decoding the data. |
| 284 void Start(const DemuxerConfigs& configs) { | 296 void Start(const DemuxerConfigs& configs) { |
| 285 player_.OnDemuxerConfigsAvailable(configs); | 297 player_.OnDemuxerConfigsAvailable(configs); |
| 286 player_.Start(); | 298 player_.Start(); |
| 287 EXPECT_TRUE(player_.IsPlaying()); | 299 EXPECT_TRUE(player_.IsPlaying()); |
| 288 } | 300 } |
| 289 | 301 |
| 290 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { | 302 AccessUnit CreateAccessUnitWithData(bool is_audio, int audio_packet_id) { |
| 291 AccessUnit unit; | 303 AccessUnit unit; |
| 292 | 304 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding()); | 370 EXPECT_FALSE(GetMediaDecoderJob(true)->is_decoding()); |
| 359 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | 371 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); |
| 360 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | 372 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); |
| 361 player_.SeekTo(seek_time); | 373 player_.SeekTo(seek_time); |
| 362 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF()); | 374 EXPECT_EQ(0.0, GetPrerollTimestamp().InMillisecondsF()); |
| 363 EXPECT_EQ(1, demuxer_->num_data_requests()); | 375 EXPECT_EQ(1, demuxer_->num_data_requests()); |
| 364 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 376 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
| 365 } | 377 } |
| 366 | 378 |
| 367 // Seek, including simulated receipt of |kAborted| read between SeekTo() | 379 // Seek, including simulated receipt of |kAborted| read between SeekTo() |
| 368 // and OnDemuxerSeekDone(). Use this helper method only when the player | 380 // and OnDemuxerSeekDone() if |abort| is true. Use this helper method only |
| 369 // already has created the decoder job. | 381 // when the player already has created the decoder job. If |abort| is false, |
| 370 void SeekPlayer(bool is_audio, const base::TimeDelta& seek_time) { | 382 // |is_audio| is ignored. |expected_new_data_requests| is compared to the |
| 371 EXPECT_TRUE(GetMediaDecoderJob(is_audio)); | 383 // actual increase in data request count due to the seek. |
| 372 | 384 void SeekPlayer(bool is_audio, const base::TimeDelta& seek_time, bool abort, |
| 385 int expected_new_data_requests) { | |
| 373 int original_num_seeks = demuxer_->num_seek_requests(); | 386 int original_num_seeks = demuxer_->num_seek_requests(); |
| 374 int original_num_data_requests = demuxer_->num_data_requests(); | 387 int original_num_data_requests = demuxer_->num_data_requests(); |
| 375 | 388 |
| 376 // Initiate a seek. Skip the round-trip of requesting seek from renderer. | 389 // Initiate a seek. Skip the round-trip of requesting seek from renderer. |
| 377 // Instead behave as if the renderer has asked us to seek. | 390 // Instead behave as if the renderer has asked us to seek. |
| 378 player_.SeekTo(seek_time); | 391 player_.SeekTo(seek_time); |
| 379 | 392 |
| 380 // Verify that the seek does not occur until previously outstanding data | 393 if (abort) { |
| 381 // request is satisfied. | 394 // Verify that the seek does not occur until previously outstanding data |
| 382 EXPECT_EQ(original_num_seeks, demuxer_->num_seek_requests()); | 395 // request is satisfied. |
| 396 EXPECT_EQ(original_num_seeks, demuxer_->num_seek_requests()); | |
| 383 | 397 |
| 384 // Simulate seeking causes the demuxer to abort the outstanding read caused | 398 // Simulate seeking causes the demuxer to abort the outstanding read |
| 385 // by the seek. | 399 // caused by the seek. |
| 386 player_.OnDemuxerDataAvailable(CreateAbortedAck(is_audio)); | 400 player_.OnDemuxerDataAvailable(CreateAbortedAck(is_audio)); |
| 401 } | |
| 387 | 402 |
| 388 // Verify that the seek is requested now that the outstanding read is | 403 // Verify that the seek is requested. |
| 389 // completed by aborted access unit. | |
| 390 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests()); | 404 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests()); |
| 391 | 405 |
| 392 // Send back the seek done notification. This should trigger the player to | 406 // Send back the seek done notification. This should trigger the player to |
| 393 // call OnReadFromDemuxer() again. | 407 // call OnReadFromDemuxer() again. |
| 394 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests()); | 408 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests()); |
| 395 player_.OnDemuxerSeekDone(kNoTimestamp()); | 409 player_.OnDemuxerSeekDone(kNoTimestamp()); |
| 396 EXPECT_EQ(original_num_data_requests + 1, demuxer_->num_data_requests()); | 410 EXPECT_EQ(original_num_data_requests + expected_new_data_requests, |
| 411 demuxer_->num_data_requests()); | |
| 397 | 412 |
| 398 // No other seek should have been requested. | 413 // No other seek should have been requested. |
| 399 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests()); | 414 EXPECT_EQ(original_num_seeks + 1, demuxer_->num_seek_requests()); |
| 400 } | 415 } |
| 401 | 416 |
| 417 // Seek, assuming player has exactly 1 stream configured (corresponding to | |
| 418 // |is_audio|), has created the decoder job, and has an outstanding request | |
| 419 // for demuxed data. | |
| 420 void SeekPlayer(bool is_audio, const base::TimeDelta& seek_time) { | |
| 421 SeekPlayer(is_audio, seek_time, true, 1); | |
| 422 } | |
| 423 | |
| 402 DemuxerData CreateReadFromDemuxerAckWithConfigChanged(bool is_audio, | 424 DemuxerData CreateReadFromDemuxerAckWithConfigChanged(bool is_audio, |
| 403 int config_unit_index) { | 425 int config_unit_index) { |
| 404 DemuxerData data; | 426 DemuxerData data; |
| 405 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO; | 427 data.type = is_audio ? DemuxerStream::AUDIO : DemuxerStream::VIDEO; |
| 406 data.access_units.resize(config_unit_index + 1); | 428 data.access_units.resize(config_unit_index + 1); |
| 407 | 429 |
| 408 for (int i = 0; i < config_unit_index; ++i) | 430 for (int i = 0; i < config_unit_index; ++i) |
| 409 data.access_units[i] = CreateAccessUnitWithData(is_audio, i); | 431 data.access_units[i] = CreateAccessUnitWithData(is_audio, i); |
| 410 | 432 |
| 411 data.access_units[config_unit_index].status = DemuxerStream::kConfigChanged; | 433 data.access_units[config_unit_index].status = DemuxerStream::kConfigChanged; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 EXPECT_FALSE(GetMediaDecoderJob(false)); | 494 EXPECT_FALSE(GetMediaDecoderJob(false)); |
| 473 EXPECT_TRUE(player_.IsPlaying()); | 495 EXPECT_TRUE(player_.IsPlaying()); |
| 474 | 496 |
| 475 // Only one browser seek should have been initiated, and no further data | 497 // Only one browser seek should have been initiated, and no further data |
| 476 // should have been requested. | 498 // should have been requested. |
| 477 expected_num_seek_requests++; | 499 expected_num_seek_requests++; |
| 478 expected_num_browser_seek_requests++; | 500 expected_num_browser_seek_requests++; |
| 479 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests()); | 501 EXPECT_EQ(expected_num_seek_requests, demuxer_->num_seek_requests()); |
| 480 EXPECT_EQ(expected_num_browser_seek_requests, | 502 EXPECT_EQ(expected_num_browser_seek_requests, |
| 481 demuxer_->num_browser_seek_requests()); | 503 demuxer_->num_browser_seek_requests()); |
| 482 EXPECT_EQ(expected_num_data_requests, demuxer_->num_seek_requests()); | 504 EXPECT_EQ(expected_num_data_requests, demuxer_->num_seek_requests()); |
|
wolenetz
2013/12/12 03:34:46
Oops. This typo (num_*seek?!*_requests) is fixed i
| |
| 483 } | 505 } |
| 484 | 506 |
| 485 // Creates a new decoder job and feeds it data ending with a |kConfigChanged| | 507 // Creates a new decoder job and feeds it data ending with a |kConfigChanged| |
| 486 // access unit. If |config_unit_in_prefetch| is true, sends feeds the config | 508 // access unit. If |config_unit_in_prefetch| is true, sends feeds the config |
| 487 // change AU in response to the job's first read request (prefetch). If | 509 // change AU in response to the job's first read request (prefetch). If |
| 488 // false, regular data is fed and decoded prior to feeding the config change | 510 // false, regular data is fed and decoded prior to feeding the config change |
| 489 // AU in response to the second data request (after prefetch completed). | 511 // AU in response to the second data request (after prefetch completed). |
| 490 // |config_unit_index| controls which access unit is |kConfigChanged|. | 512 // |config_unit_index| controls which access unit is |kConfigChanged|. |
| 491 void StartConfigChange(bool is_audio, | 513 void StartConfigChange(bool is_audio, |
| 492 bool config_unit_in_prefetch, | 514 bool config_unit_in_prefetch, |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 521 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); | 543 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); |
| 522 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests()); | 544 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests()); |
| 523 } | 545 } |
| 524 | 546 |
| 525 // Feed and decode access units with data for any units prior to | 547 // Feed and decode access units with data for any units prior to |
| 526 // |config_unit_index|, and a |kConfigChanged| unit at that index. | 548 // |config_unit_index|, and a |kConfigChanged| unit at that index. |
| 527 // Player should prepare to reconfigure the decoder job, and should request | 549 // Player should prepare to reconfigure the decoder job, and should request |
| 528 // new demuxer configs. | 550 // new demuxer configs. |
| 529 player_.OnDemuxerDataAvailable( | 551 player_.OnDemuxerDataAvailable( |
| 530 CreateReadFromDemuxerAckWithConfigChanged(is_audio, config_unit_index)); | 552 CreateReadFromDemuxerAckWithConfigChanged(is_audio, config_unit_index)); |
| 531 while (GetMediaDecoderJob(is_audio)->is_decoding()) | 553 WaitForDecodeDone(is_audio, !is_audio, false, false); |
| 532 message_loop_.RunUntilIdle(); | |
| 533 | 554 |
| 534 expected_num_config_requests++; | 555 expected_num_config_requests++; |
| 535 EXPECT_TRUE(player_.IsPlaying()); | 556 EXPECT_TRUE(player_.IsPlaying()); |
| 536 EXPECT_TRUE(GetMediaDecoderJob(is_audio)); | 557 EXPECT_TRUE(GetMediaDecoderJob(is_audio)); |
| 537 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); | 558 EXPECT_EQ(expected_num_data_requests, demuxer_->num_data_requests()); |
| 538 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests()); | 559 EXPECT_EQ(expected_num_config_requests, demuxer_->num_config_requests()); |
| 539 } | 560 } |
| 540 | 561 |
| 541 void CreateNextTextureAndSetVideoSurface() { | 562 void CreateNextTextureAndSetVideoSurface() { |
| 542 gfx::SurfaceTexture* surface_texture; | 563 gfx::SurfaceTexture* surface_texture; |
| 543 if (surface_texture_a_is_next_) { | 564 if (surface_texture_a_is_next_) { |
| 544 surface_texture_a_ = new gfx::SurfaceTexture(next_texture_id_++); | 565 surface_texture_a_ = new gfx::SurfaceTexture(next_texture_id_++); |
| 545 surface_texture = surface_texture_a_.get(); | 566 surface_texture = surface_texture_a_.get(); |
| 546 } else { | 567 } else { |
| 547 surface_texture_b_ = new gfx::SurfaceTexture(next_texture_id_++); | 568 surface_texture_b_ = new gfx::SurfaceTexture(next_texture_id_++); |
| 548 surface_texture = surface_texture_b_.get(); | 569 surface_texture = surface_texture_b_.get(); |
| 549 } | 570 } |
| 550 | 571 |
| 551 surface_texture_a_is_next_ = !surface_texture_a_is_next_; | 572 surface_texture_a_is_next_ = !surface_texture_a_is_next_; |
| 552 gfx::ScopedJavaSurface surface = gfx::ScopedJavaSurface(surface_texture); | 573 gfx::ScopedJavaSurface surface = gfx::ScopedJavaSurface(surface_texture); |
| 553 player_.SetVideoSurface(surface.Pass()); | 574 player_.SetVideoSurface(surface.Pass()); |
| 554 } | 575 } |
| 555 | 576 |
| 577 // Wait for one or both of the jobs to complete decoding, and optionally | |
| 578 // spot-check that one or more of the jobs do not resume decoding. Due to | |
| 579 // RunUntilIdle()'s large granularity, these spot-checks do not guarantee the | |
| 580 // absence of decode resumption. Decoder jobs are assumed to exist for any | |
| 581 // stream whose decode completion is awaited or whose lack of decode | |
| 582 // resumption is spot-checked. | |
| 583 void WaitForDecodeDone(bool wait_for_audio, | |
| 584 bool wait_for_video, | |
| 585 bool spot_check_no_audio_decoding, | |
| 586 bool spot_check_no_video_decoding) { | |
| 587 DCHECK(wait_for_audio || wait_for_video); | |
| 588 DCHECK(!(wait_for_audio && spot_check_no_audio_decoding)); | |
| 589 DCHECK(!(wait_for_video && spot_check_no_video_decoding)); | |
| 590 | |
| 591 while ((wait_for_audio && GetMediaDecoderJob(true)->is_decoding()) || | |
| 592 (wait_for_video && GetMediaDecoderJob(false)->is_decoding())) { | |
| 593 EXPECT_FALSE(spot_check_no_audio_decoding && | |
| 594 GetMediaDecoderJob(true)->is_decoding()); | |
| 595 EXPECT_FALSE(spot_check_no_video_decoding && | |
| 596 GetMediaDecoderJob(false)->is_decoding()); | |
| 597 message_loop_.RunUntilIdle(); | |
| 598 } | |
| 599 | |
| 600 EXPECT_FALSE(spot_check_no_audio_decoding && | |
| 601 GetMediaDecoderJob(true)->is_decoding()); | |
| 602 EXPECT_FALSE(spot_check_no_video_decoding && | |
| 603 GetMediaDecoderJob(false)->is_decoding()); | |
| 604 } | |
| 605 | |
| 606 void WaitForAudioDecodeDone() { | |
| 607 WaitForDecodeDone(true, false, false, false); | |
| 608 } | |
| 609 | |
| 610 void WaitForVideoDecodeDone() { | |
| 611 WaitForDecodeDone(false, true, false, false); | |
| 612 } | |
| 613 | |
| 614 void WaitForAudioVideoDecodeDone() { | |
| 615 WaitForDecodeDone(true, true, false, false); | |
| 616 } | |
| 617 | |
| 618 // If |send_eos| is true, generates EOS for the stream corresponding to | |
| 619 // |eos_for_audio|. Verifies that playback completes. If |send_eos| is false, | |
| 620 // then it is assumed that caller previously arranged for player to receive | |
| 621 // EOS for the stream corresponding to |eos_is_audio|, but the player has not | |
| 622 // yet decoded that EOS. | |
| 623 void VerifyPlaybackCompletesOnEOSDecode(bool send_eos, bool eos_for_audio) { | |
| 624 int original_num_data_requests = demuxer_->num_data_requests(); | |
| 625 if (send_eos) | |
| 626 player_.OnDemuxerDataAvailable(CreateEOSAck(eos_for_audio)); | |
| 627 EXPECT_FALSE(manager_.playback_completed()); | |
| 628 message_loop_.Run(); | |
| 629 EXPECT_TRUE(manager_.playback_completed()); | |
| 630 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests()); | |
| 631 } | |
| 632 | |
| 633 // Similar to VerifyPlaybackCompletesOnEOSDecode(), this helper also | |
| 634 // spot-checks that the stream corresponding to !|eos_is_audio| does not | |
| 635 // resume decoding while the EOS for the stream corresponding to | |
| 636 // |eos_is_audio|. By example, if |eos_is_audio| is false, then video EOS is | |
| 637 // expected to be decoded but audio decoder should not resume decoding. | |
| 638 void AV_VerifyPlaybackCompletesOnEOSDecode(bool send_eos, bool eos_is_audio) { | |
| 639 int original_num_data_requests = demuxer_->num_data_requests(); | |
| 640 if (send_eos) { | |
| 641 EXPECT_FALSE(GetMediaDecoderJob(!eos_is_audio)->is_decoding()); | |
| 642 player_.OnDemuxerDataAvailable(CreateEOSAck(eos_is_audio)); | |
| 643 } | |
| 644 | |
| 645 EXPECT_FALSE(manager_.playback_completed()); | |
| 646 EXPECT_FALSE(GetMediaDecoderJob(!eos_is_audio)->is_decoding()); | |
| 647 message_loop_.RunUntilIdle(); // This lets OnPrefetchDone() run if pending. | |
| 648 WaitForDecodeDone(eos_is_audio, !eos_is_audio, !eos_is_audio, eos_is_audio); | |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
This is really confusing looking. Do you really ne
wolenetz
2013/12/12 03:34:46
Yeah, this was confusing because it was more of a
| |
| 649 EXPECT_TRUE(manager_.playback_completed()); | |
| 650 EXPECT_EQ(original_num_data_requests, demuxer_->num_data_requests()); | |
| 651 } | |
| 652 | |
| 653 void VerifyCompletedPlaybackResumesOnSeekPlusStart(bool have_audio, | |
| 654 bool have_video) { | |
| 655 DCHECK(have_audio || have_video); | |
| 656 | |
| 657 EXPECT_TRUE(manager_.playback_completed()); | |
| 658 int original_num_data_requests = demuxer_->num_data_requests(); | |
| 659 SeekPlayer(true /* ignored, since not aborting */, | |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
nit: I think this just makes this unnecessarily co
wolenetz
2013/12/12 03:34:46
Yes, done :)
| |
| 660 base::TimeDelta(), false, 0); | |
| 661 | |
| 662 int data_request_delta = (have_audio ? 1 : 0) + (have_video ? 1 : 0); | |
| 663 DemuxerConfigs configs = CreateDemuxerConfigs(have_audio, have_video); | |
| 664 Start(configs); | |
| 665 | |
| 666 EXPECT_TRUE((GetMediaDecoderJob(true) != NULL) == have_audio && | |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
Shouldn't this type of check be in Start() instead
wolenetz
2013/12/12 03:34:46
Start() calls MSP::Start(), which does not guarant
| |
| 667 (GetMediaDecoderJob(false) != NULL) == have_video); | |
| 668 EXPECT_EQ(original_num_data_requests + data_request_delta, | |
| 669 demuxer_->num_data_requests()); | |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
Can this be moved into start as well?
wolenetz
2013/12/12 03:34:46
Along the lines of similar comment, I'll take a st
| |
| 670 } | |
| 671 | |
| 672 // Starts the appropriate decoder jobs according to |have_audio| and | |
| 673 // |have_video|. Then starts seek during decode of EOS or non-EOS according to | |
| 674 // |eos_audio| and |eos_video|. Simulates seek completion and verifies that | |
| 675 // playback never completed. | |
| 676 void VerifySeekDuringEOSDecodePreventsPlaybackCompletion(bool have_audio, | |
| 677 bool have_video, | |
| 678 bool eos_audio, | |
| 679 bool eos_video) { | |
| 680 DCHECK(have_audio || have_video); | |
| 681 DCHECK(have_audio || !eos_audio); | |
| 682 DCHECK(have_video || !eos_video); | |
| 683 | |
| 684 int data_request_delta = (have_audio ? 1 : 0) + (have_video ? 1 : 0); | |
| 685 DemuxerConfigs configs = CreateDemuxerConfigs(have_audio, have_video); | |
| 686 | |
| 687 if (have_video) | |
| 688 CreateNextTextureAndSetVideoSurface(); | |
| 689 Start(configs); | |
| 690 EXPECT_TRUE((GetMediaDecoderJob(true) != NULL) == have_audio && | |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
ditto. here and elsewhere.
wolenetz
2013/12/12 03:34:46
Done.
| |
| 691 (GetMediaDecoderJob(false) != NULL) == have_video); | |
| 692 EXPECT_EQ(data_request_delta, demuxer_->num_data_requests()); | |
| 693 | |
| 694 if (have_audio) | |
| 695 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | |
| 696 if (have_video) | |
| 697 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); | |
| 698 for (int i = data_request_delta + 1; i <= 2 * data_request_delta; i++) { | |
| 699 message_loop_.Run(); // Loop Quit() occurs on each data request. | |
| 700 EXPECT_EQ(i, demuxer_->num_data_requests()); | |
| 701 } | |
| 702 | |
| 703 // Simulate seek while decoding EOS or non-EOS for the appropriate | |
| 704 // stream(s). | |
| 705 if (eos_audio) { | |
| 706 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); | |
| 707 } else if (have_audio) { | |
| 708 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1)); | |
| 709 } | |
| 710 if (eos_video) { | |
| 711 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); | |
| 712 } else if (have_video) { | |
| 713 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); | |
| 714 } | |
| 715 EXPECT_TRUE(!have_audio || GetMediaDecoderJob(true)->is_decoding()); | |
| 716 EXPECT_TRUE(!have_video || GetMediaDecoderJob(false)->is_decoding()); | |
| 717 player_.SeekTo(base::TimeDelta()); | |
| 718 EXPECT_EQ(0, demuxer_->num_seek_requests()); | |
| 719 WaitForDecodeDone(have_audio, have_video, false, false); | |
| 720 | |
| 721 EXPECT_EQ(1, demuxer_->num_seek_requests()); | |
| 722 player_.OnDemuxerSeekDone(kNoTimestamp()); | |
| 723 EXPECT_EQ(3 * data_request_delta, demuxer_->num_data_requests()); | |
| 724 EXPECT_FALSE(manager_.playback_completed()); | |
| 725 } | |
| 726 | |
| 556 base::TimeTicks StartTimeTicks() { | 727 base::TimeTicks StartTimeTicks() { |
| 557 return player_.start_time_ticks_; | 728 return player_.start_time_ticks_; |
| 558 } | 729 } |
| 559 | 730 |
| 560 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid, | 731 bool IsTypeSupported(const std::vector<uint8>& scheme_uuid, |
| 561 const std::string& security_level, | 732 const std::string& security_level, |
| 562 const std::string& container, | 733 const std::string& container, |
| 563 const std::vector<std::string>& codecs) { | 734 const std::vector<std::string>& codecs) { |
| 564 return MediaSourcePlayer::IsTypeSupported( | 735 return MediaSourcePlayer::IsTypeSupported( |
| 565 scheme_uuid, security_level, container, codecs); | 736 scheme_uuid, security_level, container, codecs); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 810 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
| 640 | 811 |
| 641 // Note, the decoder job for the second surface set, above, will be created | 812 // Note, the decoder job for the second surface set, above, will be created |
| 642 // only after the pending read is satisfied and decoded, and the resulting | 813 // only after the pending read is satisfied and decoded, and the resulting |
| 643 // browser seek is done. See BrowserSeek_* tests for this coverage. | 814 // browser seek is done. See BrowserSeek_* tests for this coverage. |
| 644 } | 815 } |
| 645 | 816 |
| 646 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithInvalidSurface) { | 817 TEST_F(MediaSourcePlayerTest, StartVideoCodecWithInvalidSurface) { |
| 647 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 818 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 648 | 819 |
| 649 // Test video decoder job will be created when surface is valid. | 820 // Test video decoder job will be created when surface is valid. |
|
wolenetz
2013/12/12 03:34:46
This comment is incorrect. s/will be/will not be/,
| |
| 650 scoped_refptr<gfx::SurfaceTexture> surface_texture( | 821 scoped_refptr<gfx::SurfaceTexture> surface_texture( |
| 651 new gfx::SurfaceTexture(0)); | 822 new gfx::SurfaceTexture(0)); |
| 652 gfx::ScopedJavaSurface surface(surface_texture.get()); | 823 gfx::ScopedJavaSurface surface(surface_texture.get()); |
| 653 StartVideoDecoderJob(); | 824 StartVideoDecoderJob(); |
| 654 // Video decoder job will not be created until surface is available. | 825 // Video decoder job will not be created until surface is available. |
| 655 EXPECT_FALSE(GetMediaDecoderJob(false)); | 826 EXPECT_FALSE(GetMediaDecoderJob(false)); |
| 656 EXPECT_EQ(0, demuxer_->num_data_requests()); | 827 EXPECT_EQ(0, demuxer_->num_data_requests()); |
| 657 | 828 |
| 658 // Release the surface texture. | 829 // Release the surface texture. |
| 659 surface_texture = NULL; | 830 surface_texture = NULL; |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 850 | 1021 |
| 851 // Player should not seek the demuxer on setting initial surface. | 1022 // Player should not seek the demuxer on setting initial surface. |
| 852 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1023 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
| 853 | 1024 |
| 854 MediaDecoderJob* audio_decoder_job = GetMediaDecoderJob(true); | 1025 MediaDecoderJob* audio_decoder_job = GetMediaDecoderJob(true); |
| 855 MediaDecoderJob* video_decoder_job = GetMediaDecoderJob(false); | 1026 MediaDecoderJob* video_decoder_job = GetMediaDecoderJob(false); |
| 856 EXPECT_EQ(2, demuxer_->num_data_requests()); | 1027 EXPECT_EQ(2, demuxer_->num_data_requests()); |
| 857 EXPECT_FALSE(audio_decoder_job->is_decoding()); | 1028 EXPECT_FALSE(audio_decoder_job->is_decoding()); |
| 858 EXPECT_FALSE(video_decoder_job->is_decoding()); | 1029 EXPECT_FALSE(video_decoder_job->is_decoding()); |
| 859 | 1030 |
| 860 // Sending video data to player, audio decoder should not start. | 1031 // Sending video data to player, audio decoder should not start. |
|
wolenetz
2013/12/12 03:34:46
This comment is incorrect. s/audio/video/ is inclu
| |
| 861 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); | 1032 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); |
| 862 EXPECT_FALSE(video_decoder_job->is_decoding()); | 1033 EXPECT_FALSE(video_decoder_job->is_decoding()); |
| 863 | 1034 |
| 864 // Sending audio data to player, both decoders should start now. | 1035 // Sending audio data to player, both decoders should start now. |
| 865 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | 1036 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); |
| 866 EXPECT_TRUE(audio_decoder_job->is_decoding()); | 1037 EXPECT_TRUE(audio_decoder_job->is_decoding()); |
| 867 EXPECT_TRUE(video_decoder_job->is_decoding()); | 1038 EXPECT_TRUE(video_decoder_job->is_decoding()); |
| 868 | 1039 |
| 869 // Reconfirm no seek occurred. | 1040 // Reconfirm no seek occurred. |
| 870 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1041 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 894 // Let the decoder timeout and execute the OnDecoderStarved() callback. | 1065 // Let the decoder timeout and execute the OnDecoderStarved() callback. |
| 895 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); | 1066 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); |
| 896 | 1067 |
| 897 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | 1068 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); |
| 898 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); | 1069 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); |
| 899 message_loop_.RunUntilIdle(); | 1070 message_loop_.RunUntilIdle(); |
| 900 | 1071 |
| 901 // Send new data to the decoder so it can finish the currently | 1072 // Send new data to the decoder so it can finish the currently |
| 902 // pending decode. | 1073 // pending decode. |
| 903 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | 1074 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
| 904 while (GetMediaDecoderJob(true)->is_decoding()) | 1075 WaitForAudioDecodeDone(); |
| 905 message_loop_.RunUntilIdle(); | |
| 906 | 1076 |
| 907 // Verify the start time ticks is cleared at this point because the | 1077 // Verify the start time ticks is cleared at this point because the |
| 908 // player is prefetching. | 1078 // player is prefetching. |
| 909 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks()); | 1079 EXPECT_TRUE(StartTimeTicks() == base::TimeTicks()); |
| 910 | 1080 |
| 911 // Send new data to the decoder so it can finish prefetching. This should | 1081 // Send new data to the decoder so it can finish prefetching. This should |
| 912 // reset the start time ticks. | 1082 // reset the start time ticks. |
| 913 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); | 1083 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(3)); |
| 914 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); | 1084 EXPECT_TRUE(StartTimeTicks() != base::TimeTicks()); |
| 915 | 1085 |
| 916 base::TimeTicks current = StartTimeTicks(); | 1086 base::TimeTicks current = StartTimeTicks(); |
| 917 EXPECT_LE(100.0, (current - previous).InMillisecondsF()); | 1087 EXPECT_LE(100.0, (current - previous).InMillisecondsF()); |
| 918 } | 1088 } |
| 919 | 1089 |
| 920 TEST_F(MediaSourcePlayerTest, NoRequestForDataAfterInputEOS) { | 1090 TEST_F(MediaSourcePlayerTest, V_SecondAccessUnitIsEOSAndResumePlayAfterSeek) { |
| 921 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1091 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 922 | 1092 |
| 923 // Test MediaSourcePlayer will not request for new data after input EOS is | 1093 // Test MediaSourcePlayer can replay video after input EOS is reached. |
| 924 // reached. | |
| 925 CreateNextTextureAndSetVideoSurface(); | 1094 CreateNextTextureAndSetVideoSurface(); |
| 926 StartVideoDecoderJob(); | 1095 StartVideoDecoderJob(); |
| 1096 | |
| 927 // Player should not seek the demuxer on setting initial surface. | 1097 // Player should not seek the demuxer on setting initial surface. |
| 928 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1098 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
| 929 | 1099 |
| 930 EXPECT_EQ(1, demuxer_->num_data_requests()); | |
| 931 // Send the first input chunk. | 1100 // Send the first input chunk. |
| 932 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); | 1101 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); |
| 933 message_loop_.Run(); | 1102 message_loop_.Run(); |
| 934 EXPECT_EQ(2, demuxer_->num_data_requests()); | 1103 |
| 935 | 1104 VerifyPlaybackCompletesOnEOSDecode(true, false); |
| 936 // Send EOS. | 1105 VerifyCompletedPlaybackResumesOnSeekPlusStart(false, true); |
| 937 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); | 1106 } |
| 938 message_loop_.Run(); | 1107 |
| 939 // No more request for data should be made. | 1108 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitIsEOSAndResumePlayAfterSeek) { |
| 940 EXPECT_EQ(2, demuxer_->num_data_requests()); | 1109 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 941 | 1110 |
| 942 // Reconfirm no seek request has occurred. | 1111 // Test decode of audio EOS buffer without any prior decode. See also |
| 943 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1112 // http://b/11696552. |
| 944 } | 1113 // Also tests that seeking+Start() after completing audio playback resumes |
| 945 | 1114 // playback. |
| 946 TEST_F(MediaSourcePlayerTest, ReplayAfterInputEOS) { | 1115 Start(CreateAudioDemuxerConfigs(kCodecAAC)); |
| 947 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1116 EXPECT_TRUE(GetMediaDecoderJob(true)); |
| 948 | 1117 |
| 949 // Test MediaSourcePlayer can replay after input EOS is | 1118 VerifyPlaybackCompletesOnEOSDecode(true, true); |
| 950 // reached. | 1119 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, false); |
| 1120 } | |
| 1121 | |
| 1122 TEST_F(MediaSourcePlayerTest, V_FirstAccessUnitAfterSeekIsEOS) { | |
| 1123 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
| 1124 | |
| 1125 // Test decode of video EOS buffer, just after seeking, without any prior | |
| 1126 // decode (other than the simulated |kAborted| resulting from the seek | |
| 1127 // process.) | |
| 951 CreateNextTextureAndSetVideoSurface(); | 1128 CreateNextTextureAndSetVideoSurface(); |
| 952 StartVideoDecoderJob(); | 1129 StartVideoDecoderJob(); |
| 953 | 1130 EXPECT_TRUE(GetMediaDecoderJob(false)); |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
ditto
wolenetz
2013/12/12 03:34:46
Done.
| |
| 954 // Player should not seek the demuxer on setting initial surface. | 1131 SeekPlayer(false, base::TimeDelta()); |
| 955 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1132 VerifyPlaybackCompletesOnEOSDecode(true, false); |
| 956 | 1133 } |
| 957 EXPECT_EQ(1, demuxer_->num_data_requests()); | 1134 |
| 958 // Send the first input chunk. | 1135 TEST_F(MediaSourcePlayerTest, A_FirstAccessUnitAfterSeekIsEOS) { |
| 1136 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
| 1137 | |
| 1138 // Test decode of audio EOS buffer, just after seeking, without any prior | |
| 1139 // decode (other than the simulated |kAborted| resulting from the seek | |
| 1140 // process.) See also http://b/11696552. | |
| 1141 Start(CreateAudioDemuxerConfigs(kCodecAAC)); | |
| 1142 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
| 1143 SeekPlayer(true, base::TimeDelta()); | |
| 1144 VerifyPlaybackCompletesOnEOSDecode(true, true); | |
| 1145 } | |
| 1146 | |
| 1147 TEST_F(MediaSourcePlayerTest, AV_PlaybackCompletionAcrossConfigChange) { | |
| 1148 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
| 1149 | |
| 1150 // Test that if one stream (audio) has completed decode of EOS and the other | |
| 1151 // stream (video) processes config change, that subsequent video EOS completes | |
| 1152 // A/V playback. | |
| 1153 // Also tests that seeking+Start() after completing playback resumes playback. | |
| 1154 Start(CreateAudioVideoDemuxerConfigs()); | |
| 1155 CreateNextTextureAndSetVideoSurface(); | |
| 1156 EXPECT_TRUE(GetMediaDecoderJob(true) && GetMediaDecoderJob(false)); | |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
ditto.
wolenetz
2013/12/12 03:34:46
Done.
| |
| 1157 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS | |
| 1158 EXPECT_EQ(0, demuxer_->num_config_requests()); | |
| 1159 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged( | |
| 1160 false, 0)); // Video |kConfigChanged| as first unit. | |
| 1161 | |
| 1162 WaitForAudioVideoDecodeDone(); | |
| 1163 | |
| 1164 EXPECT_EQ(1, demuxer_->num_config_requests()); | |
| 1165 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
| 1166 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs()); | |
| 1167 EXPECT_EQ(3, demuxer_->num_data_requests()); | |
| 1168 | |
| 1169 // At no time after completing audio EOS decode, above, should the | |
| 1170 // audio decoder job resume decoding. Send and decode video EOS. Spot-check | |
| 1171 // that audio decode doesn't resume. | |
| 1172 AV_VerifyPlaybackCompletesOnEOSDecode(true, false); | |
| 1173 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true); | |
| 1174 } | |
| 1175 | |
| 1176 TEST_F(MediaSourcePlayerTest, VA_PlaybackCompletionAcrossConfigChange) { | |
| 1177 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
| 1178 | |
| 1179 // Test that if one stream (video) has completed decode of EOS and the other | |
| 1180 // stream (audio) processes config change, that subsequent audio EOS completes | |
| 1181 // A/V playback. | |
| 1182 // Also tests that seeking+Start() after completing playback resumes playback. | |
| 1183 Start(CreateAudioVideoDemuxerConfigs()); | |
| 1184 CreateNextTextureAndSetVideoSurface(); | |
| 1185 EXPECT_TRUE(GetMediaDecoderJob(true) && GetMediaDecoderJob(false)); | |
|
acolwell GONE FROM CHROMIUM
2013/12/11 21:20:22
ditto. here and elsewhere
wolenetz
2013/12/12 03:34:46
Done.
| |
| 1186 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
| 1187 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS | |
| 1188 EXPECT_EQ(0, demuxer_->num_config_requests()); | |
| 1189 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckWithConfigChanged( | |
| 1190 true, 0)); // Audio |kConfigChanged| as first unit. | |
| 1191 | |
| 1192 WaitForAudioVideoDecodeDone(); | |
| 1193 | |
| 1194 // TODO(wolenetz/qinmin): Prevent redundant demuxer config request and change | |
| 1195 // expectation to 1 here. See http://crbug.com/325528. | |
| 1196 EXPECT_EQ(2, demuxer_->num_config_requests()); | |
| 1197 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
| 1198 player_.OnDemuxerConfigsAvailable(CreateAudioVideoDemuxerConfigs()); | |
| 1199 EXPECT_EQ(3, demuxer_->num_data_requests()); | |
| 1200 | |
| 1201 // At no time after completing video EOS decode, above, should the | |
| 1202 // video decoder job resume decoding. Send and decode audio EOS. Spot-check | |
| 1203 // that video decode doesn't resume. | |
| 1204 AV_VerifyPlaybackCompletesOnEOSDecode(true, true); | |
| 1205 VerifyCompletedPlaybackResumesOnSeekPlusStart(true, true); | |
| 1206 } | |
| 1207 | |
| 1208 TEST_F(MediaSourcePlayerTest, AV_NoPrefetchForFinishedVideoOnAudioStarvation) { | |
| 1209 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
| 1210 | |
| 1211 // Test that if one stream (video) has completed decode of EOS, prefetch | |
| 1212 // resulting from player starvation occurs only for the other stream (audio), | |
| 1213 // and responding to that prefetch with EOS completes A/V playback, even if | |
| 1214 // another starvation occurs during the latter EOS's decode. | |
| 1215 Start(CreateAudioVideoDemuxerConfigs()); | |
| 1216 CreateNextTextureAndSetVideoSurface(); | |
| 1217 EXPECT_TRUE(GetMediaDecoderJob(true) && GetMediaDecoderJob(false)); | |
| 1218 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
| 1219 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | |
| 1220 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS | |
| 1221 | |
| 1222 // Wait until video EOS is processed and more data (assumed to be audio) is | |
| 1223 // requested. | |
| 1224 while (demuxer_->num_data_requests() < 3) | |
| 1225 message_loop_.RunUntilIdle(); | |
| 1226 WaitForVideoDecodeDone(); | |
| 1227 | |
| 1228 // Simulate decoder underrun to trigger prefetch while still decoding audio. | |
| 1229 EXPECT_EQ(3, demuxer_->num_data_requests()); | |
| 1230 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(1)); | |
| 1231 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding() && | |
| 1232 !GetMediaDecoderJob(false)->is_decoding()); | |
| 1233 TriggerPlayerStarvation(); | |
| 1234 | |
| 1235 // Complete the audio decode that was in progress when simulated player | |
| 1236 // starvation was triggered. At no time after completing video EOS decode, | |
| 1237 // above, should the video decoder job resume decoding. | |
| 1238 WaitForDecodeDone(true, false, false, true); | |
| 1239 EXPECT_EQ(4, demuxer_->num_data_requests()); | |
| 1240 | |
| 1241 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS | |
| 1242 EXPECT_FALSE(GetMediaDecoderJob(false)->is_decoding()); | |
| 1243 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | |
| 1244 | |
| 1245 // Simulate another decoder underrun to trigger prefetch while decoding EOS. | |
| 1246 TriggerPlayerStarvation(); | |
| 1247 | |
| 1248 AV_VerifyPlaybackCompletesOnEOSDecode(false, true); | |
| 1249 } | |
| 1250 | |
| 1251 TEST_F(MediaSourcePlayerTest, V_StarvationDuringEOSDecode) { | |
| 1252 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
| 1253 | |
| 1254 // Test that video-only playback completes without further data requested when | |
| 1255 // starvation occurs during EOS decode. | |
| 1256 CreateNextTextureAndSetVideoSurface(); | |
| 1257 StartVideoDecoderJob(); | |
| 959 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); | 1258 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForVideo()); |
| 960 message_loop_.Run(); | 1259 message_loop_.Run(); |
| 961 EXPECT_EQ(2, demuxer_->num_data_requests()); | 1260 EXPECT_EQ(2, demuxer_->num_data_requests()); |
| 962 | 1261 |
| 963 // Send EOS. | 1262 // Simulate decoder underrun to trigger prefetch while decoding EOS. |
| 964 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); | 1263 player_.OnDemuxerDataAvailable(CreateEOSAck(false)); // Video EOS |
| 1264 EXPECT_TRUE(GetMediaDecoderJob(false)->is_decoding()); | |
| 1265 TriggerPlayerStarvation(); | |
| 1266 VerifyPlaybackCompletesOnEOSDecode(false, false); | |
| 1267 } | |
| 1268 | |
| 1269 TEST_F(MediaSourcePlayerTest, A_StarvationDuringEOSDecode) { | |
| 1270 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | |
| 1271 | |
| 1272 // Test that audio-only playback completes without further data requested when | |
| 1273 // starvation occurs during EOS decode. | |
| 1274 StartAudioDecoderJob(); | |
| 1275 EXPECT_TRUE(GetMediaDecoderJob(true)); | |
| 1276 player_.OnDemuxerDataAvailable(CreateReadFromDemuxerAckForAudio(0)); | |
| 965 message_loop_.Run(); | 1277 message_loop_.Run(); |
| 966 // No more request for data should be made. | 1278 EXPECT_EQ(2, demuxer_->num_data_requests()); |
| 967 EXPECT_EQ(2, demuxer_->num_data_requests()); | 1279 |
| 968 | 1280 // Simulate decoder underrun to trigger prefetch while decoding EOS. |
| 969 // Initiate a seek. Skip requesting element seek of renderer. | 1281 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); // Audio EOS |
| 970 // Instead behave as if the renderer has asked us to seek. | 1282 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); |
| 971 player_.SeekTo(base::TimeDelta()); | 1283 TriggerPlayerStarvation(); |
| 972 StartVideoDecoderJob(); | 1284 VerifyPlaybackCompletesOnEOSDecode(false, true); |
| 973 EXPECT_EQ(1, demuxer_->num_seek_requests()); | 1285 } |
| 974 player_.OnDemuxerSeekDone(kNoTimestamp()); | 1286 |
| 975 // Seek/Play after EOS should request more data. | 1287 TEST_F(MediaSourcePlayerTest, AV_SeekDuringEOSDecodePreventsCompletion) { |
| 976 EXPECT_EQ(3, demuxer_->num_data_requests()); | 1288 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 977 | 1289 |
| 978 // Reconfirm only 1 seek request has occurred. | 1290 // Test that seek supercedes audio+video playback completion on simultaneous |
| 979 EXPECT_EQ(1, demuxer_->num_seek_requests()); | 1291 // audio and video EOS decode, if SeekTo() occurs during these EOS decodes. |
| 980 } | 1292 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, true); |
| 981 | 1293 } |
| 982 TEST_F(MediaSourcePlayerTest, FirstDataIsEOS) { | 1294 |
| 983 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1295 TEST_F(MediaSourcePlayerTest, AV_SeekDuringAudioEOSDecodePreventsCompletion) { |
| 984 | 1296 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 985 // Test decode of EOS buffer without any prior decode. See also | 1297 |
| 986 // http://b/11696552. | 1298 // Test that seek supercedes audio+video playback completion on simultaneous |
| 987 Start(CreateAudioDemuxerConfigs(kCodecAAC)); | 1299 // audio EOS and video non-EOS decode, if SeekTo() occurs during these |
| 988 EXPECT_TRUE(GetMediaDecoderJob(true)); | 1300 // decodes. |
| 989 | 1301 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, true, false); |
| 990 EXPECT_EQ(1, demuxer_->num_data_requests()); | 1302 } |
| 991 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); | 1303 |
| 992 EXPECT_FALSE(manager_.playback_completed()); | 1304 TEST_F(MediaSourcePlayerTest, AV_SeekDuringVideoEOSDecodePreventsCompletion) { |
| 993 | 1305 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 994 message_loop_.Run(); | 1306 |
| 995 EXPECT_TRUE(manager_.playback_completed()); | 1307 // Test that seek supercedes audio+video playback completion on simultaneous |
| 996 EXPECT_EQ(1, demuxer_->num_data_requests()); | 1308 // audio non-EOS and video EOS decode, if SeekTo() occurs during these |
| 997 } | 1309 // decodes. |
| 998 | 1310 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, true, false, true); |
| 999 TEST_F(MediaSourcePlayerTest, FirstDataAfterSeekIsEOS) { | 1311 } |
| 1000 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1312 |
| 1001 | 1313 TEST_F(MediaSourcePlayerTest, V_SeekDuringEOSDecodePreventsCompletion) { |
| 1002 // Test decode of EOS buffer, just after seeking, without any prior decode | 1314 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 1003 // (other than the simulated |kAborted| resulting from the seek process.) | 1315 |
| 1004 // See also http://b/11696552. | 1316 // Test that seek supercedes video-only playback completion on EOS decode, if |
| 1005 Start(CreateAudioDemuxerConfigs(kCodecAAC)); | 1317 // SeekTo() occurs during EOS decode. |
| 1006 EXPECT_TRUE(GetMediaDecoderJob(true)); | 1318 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(false, true, false, true); |
| 1007 | 1319 } |
| 1008 SeekPlayer(true, base::TimeDelta()); | 1320 |
| 1009 EXPECT_EQ(2, demuxer_->num_data_requests()); | 1321 TEST_F(MediaSourcePlayerTest, A_SeekDuringEOSDecodePreventsCompletion) { |
| 1010 player_.OnDemuxerDataAvailable(CreateEOSAck(true)); | 1322 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 1011 EXPECT_FALSE(manager_.playback_completed()); | 1323 |
| 1012 | 1324 // Test that seek supercedes audio-only playback completion on EOS decode, if |
| 1013 message_loop_.Run(); | 1325 // SeekTo() occurs during EOS decode. |
| 1014 EXPECT_TRUE(manager_.playback_completed()); | 1326 VerifySeekDuringEOSDecodePreventsPlaybackCompletion(true, false, true, false); |
| 1015 EXPECT_EQ(2, demuxer_->num_data_requests()); | |
| 1016 } | 1327 } |
| 1017 | 1328 |
| 1018 TEST_F(MediaSourcePlayerTest, NoRequestForDataAfterAbort) { | 1329 TEST_F(MediaSourcePlayerTest, NoRequestForDataAfterAbort) { |
| 1019 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1330 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 1020 | 1331 |
| 1021 // Test that the decoder will not request new data after receiving an aborted | 1332 // Test that the decoder will not request new data after receiving an aborted |
| 1022 // access unit. | 1333 // access unit. |
| 1023 StartAudioDecoderJob(); | 1334 StartAudioDecoderJob(); |
| 1024 EXPECT_EQ(1, demuxer_->num_data_requests()); | 1335 EXPECT_EQ(1, demuxer_->num_data_requests()); |
| 1025 | 1336 |
| 1026 // Send an aborted access unit. | 1337 // Send an aborted access unit. |
| 1027 player_.OnDemuxerDataAvailable(CreateAbortedAck(true)); | 1338 player_.OnDemuxerDataAvailable(CreateAbortedAck(true)); |
| 1028 | 1339 |
| 1029 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); | 1340 EXPECT_TRUE(GetMediaDecoderJob(true)->is_decoding()); |
| 1030 // Wait for the decoder job to finish decoding. | 1341 |
| 1031 while (GetMediaDecoderJob(true)->is_decoding()) | 1342 WaitForAudioDecodeDone(); |
| 1032 message_loop_.RunUntilIdle(); | |
| 1033 | 1343 |
| 1034 // No request will be sent for new data. | 1344 // No request will be sent for new data. |
| 1035 EXPECT_EQ(1, demuxer_->num_data_requests()); | 1345 EXPECT_EQ(1, demuxer_->num_data_requests()); |
| 1036 | 1346 |
| 1037 // No seek requests should have occurred. | 1347 // No seek requests should have occurred. |
| 1038 EXPECT_EQ(0, demuxer_->num_seek_requests()); | 1348 EXPECT_EQ(0, demuxer_->num_seek_requests()); |
| 1039 } | 1349 } |
| 1040 | 1350 |
| 1041 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) { | 1351 TEST_F(MediaSourcePlayerTest, DemuxerDataArrivesAfterRelease) { |
| 1042 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1352 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1653 } | 1963 } |
| 1654 | 1964 |
| 1655 TEST_F(MediaSourcePlayerTest, SeekToThenDemuxerSeekThenReleaseThenSeekDone) { | 1965 TEST_F(MediaSourcePlayerTest, SeekToThenDemuxerSeekThenReleaseThenSeekDone) { |
| 1656 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1966 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 1657 | 1967 |
| 1658 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC | 1968 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeek IPC |
| 1659 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the | 1969 // request and OnDemuxerSeekDone() arrives prior to the next Start(), then the |
| 1660 // player will resume correct post-seek preroll upon Start(). | 1970 // player will resume correct post-seek preroll upon Start(). |
| 1661 StartAudioDecoderJobAndSeekToWhileDecoding( | 1971 StartAudioDecoderJobAndSeekToWhileDecoding( |
| 1662 base::TimeDelta::FromMilliseconds(100)); | 1972 base::TimeDelta::FromMilliseconds(100)); |
| 1663 while (GetMediaDecoderJob(true)->is_decoding()) | 1973 WaitForAudioDecodeDone(); |
| 1664 message_loop_.RunUntilIdle(); | |
| 1665 EXPECT_EQ(1, demuxer_->num_seek_requests()); | 1974 EXPECT_EQ(1, demuxer_->num_seek_requests()); |
| 1666 | 1975 |
| 1667 ReleasePlayer(); | 1976 ReleasePlayer(); |
| 1668 player_.OnDemuxerSeekDone(kNoTimestamp()); | 1977 player_.OnDemuxerSeekDone(kNoTimestamp()); |
| 1669 EXPECT_FALSE(player_.IsPlaying()); | 1978 EXPECT_FALSE(player_.IsPlaying()); |
| 1670 EXPECT_FALSE(GetMediaDecoderJob(true)); | 1979 EXPECT_FALSE(GetMediaDecoderJob(true)); |
| 1671 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); | 1980 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); |
| 1672 | 1981 |
| 1673 // Player should begin prefetch and resume preroll upon Start(). | 1982 // Player should begin prefetch and resume preroll upon Start(). |
| 1674 EXPECT_EQ(1, demuxer_->num_data_requests()); | 1983 EXPECT_EQ(1, demuxer_->num_data_requests()); |
| 1675 StartAudioDecoderJob(); | 1984 StartAudioDecoderJob(); |
| 1676 EXPECT_TRUE(GetMediaDecoderJob(true)); | 1985 EXPECT_TRUE(GetMediaDecoderJob(true)); |
| 1677 EXPECT_TRUE(IsPrerolling(true)); | 1986 EXPECT_TRUE(IsPrerolling(true)); |
| 1678 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); | 1987 EXPECT_EQ(100.0, GetPrerollTimestamp().InMillisecondsF()); |
| 1679 EXPECT_EQ(2, demuxer_->num_data_requests()); | 1988 EXPECT_EQ(2, demuxer_->num_data_requests()); |
| 1680 | 1989 |
| 1681 // No further seek should have been requested since before Release(), above. | 1990 // No further seek should have been requested since before Release(), above. |
| 1682 EXPECT_EQ(1, demuxer_->num_seek_requests()); | 1991 EXPECT_EQ(1, demuxer_->num_seek_requests()); |
| 1683 } | 1992 } |
| 1684 | 1993 |
| 1685 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenStart) { | 1994 TEST_F(MediaSourcePlayerTest, SeekToThenReleaseThenStart) { |
| 1686 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); | 1995 SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE(); |
| 1687 | 1996 |
| 1688 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC | 1997 // Test if Release() occurs after a SeekTo()'s subsequent DemuxerSeeK IPC |
| 1689 // request OnDemuxerSeekDone() does not occur until after the next Start(), | 1998 // request OnDemuxerSeekDone() does not occur until after the next Start(), |
|
wolenetz
2013/12/12 03:34:46
s/request OnDemux/request and OnDemux/ comment fix
| |
| 1690 // then the player remains pending seek done until (and resumes correct | 1999 // then the player remains pending seek done until (and resumes correct |
| 1691 // post-seek preroll after) OnDemuxerSeekDone(). | 2000 // post-seek preroll after) OnDemuxerSeekDone(). |
| 1692 StartAudioDecoderJobAndSeekToWhileDecoding( | 2001 StartAudioDecoderJobAndSeekToWhileDecoding( |
| 1693 base::TimeDelta::FromMilliseconds(100)); | 2002 base::TimeDelta::FromMilliseconds(100)); |
| 1694 while (GetMediaDecoderJob(true)->is_decoding()) | 2003 WaitForAudioDecodeDone(); |
| 1695 message_loop_.RunUntilIdle(); | |
| 1696 EXPECT_EQ(1, demuxer_->num_seek_requests()); | 2004 EXPECT_EQ(1, demuxer_->num_seek_requests()); |
| 1697 | 2005 |
| 1698 ReleasePlayer(); | 2006 ReleasePlayer(); |
| 1699 StartAudioDecoderJob(); | 2007 StartAudioDecoderJob(); |
| 1700 EXPECT_FALSE(GetMediaDecoderJob(true)); | 2008 EXPECT_FALSE(GetMediaDecoderJob(true)); |
| 1701 EXPECT_EQ(1, demuxer_->num_data_requests()); | 2009 EXPECT_EQ(1, demuxer_->num_data_requests()); |
| 1702 | 2010 |
| 1703 player_.OnDemuxerSeekDone(kNoTimestamp()); | 2011 player_.OnDemuxerSeekDone(kNoTimestamp()); |
| 1704 EXPECT_TRUE(GetMediaDecoderJob(true)); | 2012 EXPECT_TRUE(GetMediaDecoderJob(true)); |
| 1705 EXPECT_TRUE(IsPrerolling(true)); | 2013 EXPECT_TRUE(IsPrerolling(true)); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1902 | 2210 |
| 1903 std::vector<std::string> codec_avc(1, "avc1"); | 2211 std::vector<std::string> codec_avc(1, "avc1"); |
| 1904 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc)); | 2212 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L3", kVideoMp4, codec_avc)); |
| 1905 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc)); | 2213 EXPECT_FALSE(IsTypeSupported(invalid_uuid, "L1", kVideoMp4, codec_avc)); |
| 1906 } | 2214 } |
| 1907 | 2215 |
| 1908 // TODO(xhwang): Are these IsTypeSupported tests device specific? | 2216 // TODO(xhwang): Are these IsTypeSupported tests device specific? |
| 1909 // TODO(xhwang): Add more IsTypeSupported tests. | 2217 // TODO(xhwang): Add more IsTypeSupported tests. |
| 1910 | 2218 |
| 1911 } // namespace media | 2219 } // namespace media |
| OLD | NEW |