OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "media/base/cdm_callback_promise.h" | 17 #include "media/base/cdm_callback_promise.h" |
18 #include "media/base/cdm_context.h" | 18 #include "media/base/cdm_context.h" |
19 #include "media/base/cdm_key_information.h" | 19 #include "media/base/cdm_key_information.h" |
20 #include "media/base/decoder_buffer.h" | 20 #include "media/base/decoder_buffer.h" |
21 #include "media/base/media.h" | 21 #include "media/base/media.h" |
22 #include "media/base/media_keys.h" | 22 #include "media/base/media_keys.h" |
23 #include "media/base/media_switches.h" | 23 #include "media/base/media_switches.h" |
| 24 #include "media/base/media_tracks.h" |
24 #include "media/base/test_data_util.h" | 25 #include "media/base/test_data_util.h" |
25 #include "media/base/timestamp_constants.h" | 26 #include "media/base/timestamp_constants.h" |
26 #include "media/cdm/aes_decryptor.h" | 27 #include "media/cdm/aes_decryptor.h" |
27 #include "media/cdm/json_web_key.h" | 28 #include "media/cdm/json_web_key.h" |
28 #include "media/filters/chunk_demuxer.h" | 29 #include "media/filters/chunk_demuxer.h" |
29 #include "media/renderers/renderer_impl.h" | 30 #include "media/renderers/renderer_impl.h" |
30 #include "media/test/pipeline_integration_test_base.h" | 31 #include "media/test/pipeline_integration_test_base.h" |
31 #include "testing/gmock/include/gmock/gmock.h" | 32 #include "testing/gmock/include/gmock/gmock.h" |
32 #include "url/gurl.h" | 33 #include "url/gurl.h" |
33 | 34 |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 chunk_demuxer_->StartWaitingForSeek(seek_time); | 528 chunk_demuxer_->StartWaitingForSeek(seek_time); |
528 } | 529 } |
529 | 530 |
530 void AppendData(size_t size) { | 531 void AppendData(size_t size) { |
531 DCHECK(chunk_demuxer_); | 532 DCHECK(chunk_demuxer_); |
532 DCHECK_LT(current_position_, file_data_->data_size()); | 533 DCHECK_LT(current_position_, file_data_->data_size()); |
533 DCHECK_LE(current_position_ + size, file_data_->data_size()); | 534 DCHECK_LE(current_position_ + size, file_data_->data_size()); |
534 | 535 |
535 chunk_demuxer_->AppendData( | 536 chunk_demuxer_->AppendData( |
536 kSourceId, file_data_->data() + current_position_, size, | 537 kSourceId, file_data_->data() + current_position_, size, |
537 base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_, | 538 base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_); |
538 base::Bind(&MockMediaSource::InitSegmentReceived, | |
539 base::Unretained(this))); | |
540 current_position_ += size; | 539 current_position_ += size; |
541 } | 540 } |
542 | 541 |
543 void AppendAtTime(base::TimeDelta timestamp_offset, | 542 void AppendAtTime(base::TimeDelta timestamp_offset, |
544 const uint8_t* pData, | 543 const uint8_t* pData, |
545 int size) { | 544 int size) { |
546 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId)); | 545 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId)); |
547 chunk_demuxer_->AppendData(kSourceId, pData, size, base::TimeDelta(), | 546 chunk_demuxer_->AppendData(kSourceId, pData, size, base::TimeDelta(), |
548 kInfiniteDuration(), ×tamp_offset, | 547 kInfiniteDuration(), ×tamp_offset); |
549 base::Bind(&MockMediaSource::InitSegmentReceived, | |
550 base::Unretained(this))); | |
551 last_timestamp_offset_ = timestamp_offset; | 548 last_timestamp_offset_ = timestamp_offset; |
552 } | 549 } |
553 | 550 |
554 void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset, | 551 void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset, |
555 base::TimeDelta append_window_start, | 552 base::TimeDelta append_window_start, |
556 base::TimeDelta append_window_end, | 553 base::TimeDelta append_window_end, |
557 const uint8_t* pData, | 554 const uint8_t* pData, |
558 int size) { | 555 int size) { |
559 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId)); | 556 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId)); |
560 chunk_demuxer_->AppendData(kSourceId, pData, size, append_window_start, | 557 chunk_demuxer_->AppendData(kSourceId, pData, size, append_window_start, |
561 append_window_end, ×tamp_offset, | 558 append_window_end, ×tamp_offset); |
562 base::Bind(&MockMediaSource::InitSegmentReceived, | |
563 base::Unretained(this))); | |
564 last_timestamp_offset_ = timestamp_offset; | 559 last_timestamp_offset_ = timestamp_offset; |
565 } | 560 } |
566 | 561 |
567 void SetMemoryLimits(size_t limit_bytes) { | 562 void SetMemoryLimits(size_t limit_bytes) { |
568 chunk_demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, limit_bytes); | 563 chunk_demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, limit_bytes); |
569 chunk_demuxer_->SetMemoryLimits(DemuxerStream::VIDEO, limit_bytes); | 564 chunk_demuxer_->SetMemoryLimits(DemuxerStream::VIDEO, limit_bytes); |
570 } | 565 } |
571 | 566 |
572 void EvictCodedFrames(base::TimeDelta currentMediaTime, size_t newDataSize) { | 567 void EvictCodedFrames(base::TimeDelta currentMediaTime, size_t newDataSize) { |
573 chunk_demuxer_->EvictCodedFrames(kSourceId, currentMediaTime, newDataSize); | 568 chunk_demuxer_->EvictCodedFrames(kSourceId, currentMediaTime, newDataSize); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 | 609 |
615 CHECK_NE(codecs_param_end, std::string::npos); | 610 CHECK_NE(codecs_param_end, std::string::npos); |
616 | 611 |
617 std::string codecs_param = mimetype_.substr( | 612 std::string codecs_param = mimetype_.substr( |
618 codecs_param_start, codecs_param_end - codecs_param_start); | 613 codecs_param_start, codecs_param_end - codecs_param_start); |
619 codecs = base::SplitString(codecs_param, ",", base::KEEP_WHITESPACE, | 614 codecs = base::SplitString(codecs_param, ",", base::KEEP_WHITESPACE, |
620 base::SPLIT_WANT_NONEMPTY); | 615 base::SPLIT_WANT_NONEMPTY); |
621 } | 616 } |
622 | 617 |
623 CHECK_EQ(chunk_demuxer_->AddId(kSourceId, type, codecs), ChunkDemuxer::kOk); | 618 CHECK_EQ(chunk_demuxer_->AddId(kSourceId, type, codecs), ChunkDemuxer::kOk); |
| 619 chunk_demuxer_->SetTracksWatcher( |
| 620 kSourceId, base::Bind(&MockMediaSource::InitSegmentReceivedWrapper, |
| 621 base::Unretained(this))); |
624 | 622 |
625 AppendData(initial_append_size_); | 623 AppendData(initial_append_size_); |
626 } | 624 } |
627 | 625 |
628 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, | 626 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, |
629 const std::vector<uint8_t>& init_data) { | 627 const std::vector<uint8_t>& init_data) { |
630 DCHECK(!init_data.empty()); | 628 DCHECK(!init_data.empty()); |
631 CHECK(!encrypted_media_init_data_cb_.is_null()); | 629 CHECK(!encrypted_media_init_data_cb_.is_null()); |
632 encrypted_media_init_data_cb_.Run(init_data_type, init_data); | 630 encrypted_media_init_data_cb_.Run(init_data_type, init_data); |
633 } | 631 } |
634 | 632 |
635 base::TimeDelta last_timestamp_offset() const { | 633 base::TimeDelta last_timestamp_offset() const { |
636 return last_timestamp_offset_; | 634 return last_timestamp_offset_; |
637 } | 635 } |
638 | 636 |
639 MOCK_METHOD0(InitSegmentReceived, void(void)); | 637 // A workaround for gtest mocks not allowing moving scoped_ptrs. |
| 638 void InitSegmentReceivedWrapper(scoped_ptr<MediaTracks> tracks) { |
| 639 InitSegmentReceived(tracks); |
| 640 } |
| 641 |
| 642 MOCK_METHOD1(InitSegmentReceived, void(scoped_ptr<MediaTracks>&)); |
640 | 643 |
641 private: | 644 private: |
642 scoped_refptr<DecoderBuffer> file_data_; | 645 scoped_refptr<DecoderBuffer> file_data_; |
643 size_t current_position_; | 646 size_t current_position_; |
644 size_t initial_append_size_; | 647 size_t initial_append_size_; |
645 std::string mimetype_; | 648 std::string mimetype_; |
646 ChunkDemuxer* chunk_demuxer_; | 649 ChunkDemuxer* chunk_demuxer_; |
647 scoped_ptr<Demuxer> owned_chunk_demuxer_; | 650 scoped_ptr<Demuxer> owned_chunk_demuxer_; |
648 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_; | 651 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_; |
649 base::TimeDelta last_timestamp_offset_; | 652 base::TimeDelta last_timestamp_offset_; |
(...skipping 25 matching lines...) Expand all Loading... |
675 interfaces::ServiceFactoryPtr media_service_factory_; | 678 interfaces::ServiceFactoryPtr media_service_factory_; |
676 }; | 679 }; |
677 #else | 680 #else |
678 class PipelineIntegrationTestHost : public testing::Test, | 681 class PipelineIntegrationTestHost : public testing::Test, |
679 public PipelineIntegrationTestBase {}; | 682 public PipelineIntegrationTestBase {}; |
680 #endif // defined(MOJO_RENDERER) | 683 #endif // defined(MOJO_RENDERER) |
681 | 684 |
682 class PipelineIntegrationTest : public PipelineIntegrationTestHost { | 685 class PipelineIntegrationTest : public PipelineIntegrationTestHost { |
683 public: | 686 public: |
684 void StartPipelineWithMediaSource(MockMediaSource* source) { | 687 void StartPipelineWithMediaSource(MockMediaSource* source) { |
685 EXPECT_CALL(*source, InitSegmentReceived()).Times(AtLeast(1)); | 688 EXPECT_CALL(*source, InitSegmentReceived(_)).Times(AtLeast(1)); |
686 EXPECT_CALL(*this, OnMetadata(_)) | 689 EXPECT_CALL(*this, OnMetadata(_)) |
687 .Times(AtMost(1)) | 690 .Times(AtMost(1)) |
688 .WillRepeatedly(SaveArg<0>(&metadata_)); | 691 .WillRepeatedly(SaveArg<0>(&metadata_)); |
689 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_ENOUGH)) | 692 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_ENOUGH)) |
690 .Times(AnyNumber()); | 693 .Times(AnyNumber()); |
691 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_NOTHING)) | 694 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_NOTHING)) |
692 .Times(AnyNumber()); | 695 .Times(AnyNumber()); |
693 | 696 |
694 // Encrypted content not used, so this is never called. | 697 // Encrypted content not used, so this is never called. |
695 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); | 698 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); |
(...skipping 23 matching lines...) Expand all Loading... |
719 } | 722 } |
720 | 723 |
721 void StartHashedClocklessPipelineWithMediaSource(MockMediaSource* source) { | 724 void StartHashedClocklessPipelineWithMediaSource(MockMediaSource* source) { |
722 hashing_enabled_ = true; | 725 hashing_enabled_ = true; |
723 clockless_playback_ = true; | 726 clockless_playback_ = true; |
724 StartPipelineWithMediaSource(source); | 727 StartPipelineWithMediaSource(source); |
725 } | 728 } |
726 | 729 |
727 void StartPipelineWithEncryptedMedia(MockMediaSource* source, | 730 void StartPipelineWithEncryptedMedia(MockMediaSource* source, |
728 FakeEncryptedMedia* encrypted_media) { | 731 FakeEncryptedMedia* encrypted_media) { |
729 EXPECT_CALL(*source, InitSegmentReceived()).Times(AtLeast(1)); | 732 EXPECT_CALL(*source, InitSegmentReceived(_)).Times(AtLeast(1)); |
730 EXPECT_CALL(*this, OnMetadata(_)) | 733 EXPECT_CALL(*this, OnMetadata(_)) |
731 .Times(AtMost(1)) | 734 .Times(AtMost(1)) |
732 .WillRepeatedly(SaveArg<0>(&metadata_)); | 735 .WillRepeatedly(SaveArg<0>(&metadata_)); |
733 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_ENOUGH)) | 736 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_ENOUGH)) |
734 .Times(AnyNumber()); | 737 .Times(AnyNumber()); |
735 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_NOTHING)) | 738 EXPECT_CALL(*this, OnBufferingStateChanged(BUFFERING_HAVE_NOTHING)) |
736 .Times(AnyNumber()); | 739 .Times(AnyNumber()); |
737 EXPECT_CALL(*this, DecryptorAttached(true)); | 740 EXPECT_CALL(*this, DecryptorAttached(true)); |
738 | 741 |
739 // Encrypted content used but keys provided in advance, so this is | 742 // Encrypted content used but keys provided in advance, so this is |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2020 | 2023 |
2021 TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) { | 2024 TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) { |
2022 ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm")); | 2025 ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm")); |
2023 Play(); | 2026 Play(); |
2024 ASSERT_TRUE(WaitUntilOnEnded()); | 2027 ASSERT_TRUE(WaitUntilOnEnded()); |
2025 ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000), | 2028 ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000), |
2026 demuxer_->GetStartTime()); | 2029 demuxer_->GetStartTime()); |
2027 } | 2030 } |
2028 | 2031 |
2029 } // namespace media | 2032 } // namespace media |
OLD | NEW |