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

Side by Side Diff: media/test/pipeline_integration_test.cc

Issue 2808583002: RELAND: Media Remoting end to end integration tests. (Closed)
Patch Set: Rebased. Created 3 years, 8 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
« no previous file with comments | « media/test/mock_media_source.cc ('k') | media/test/pipeline_integration_test_base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 7
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/strings/string_split.h" 17 #include "base/strings/string_split.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
20 #include "build/build_config.h" 20 #include "build/build_config.h"
21 #include "media/base/cdm_callback_promise.h" 21 #include "media/base/cdm_callback_promise.h"
22 #include "media/base/cdm_context.h"
23 #include "media/base/cdm_key_information.h" 22 #include "media/base/cdm_key_information.h"
24 #include "media/base/content_decryption_module.h"
25 #include "media/base/decoder_buffer.h" 23 #include "media/base/decoder_buffer.h"
26 #include "media/base/media.h" 24 #include "media/base/media.h"
27 #include "media/base/media_switches.h" 25 #include "media/base/media_switches.h"
28 #include "media/base/media_tracks.h" 26 #include "media/base/media_tracks.h"
29 #include "media/base/test_data_util.h" 27 #include "media/base/test_data_util.h"
30 #include "media/base/timestamp_constants.h" 28 #include "media/base/timestamp_constants.h"
31 #include "media/cdm/aes_decryptor.h" 29 #include "media/cdm/aes_decryptor.h"
32 #include "media/cdm/json_web_key.h" 30 #include "media/cdm/json_web_key.h"
33 #include "media/filters/chunk_demuxer.h"
34 #include "media/media_features.h" 31 #include "media/media_features.h"
35 #include "media/renderers/renderer_impl.h" 32 #include "media/renderers/renderer_impl.h"
33 #include "media/test/fake_encrypted_media.h"
34 #include "media/test/mock_media_source.h"
36 #include "media/test/pipeline_integration_test_base.h" 35 #include "media/test/pipeline_integration_test_base.h"
37 #include "testing/gmock/include/gmock/gmock.h" 36 #include "testing/gmock/include/gmock/gmock.h"
38 #include "url/gurl.h" 37 #include "url/gurl.h"
39 38
40 #if defined(MOJO_RENDERER) 39 #if defined(MOJO_RENDERER)
41 #include "media/mojo/clients/mojo_renderer.h" 40 #include "media/mojo/clients/mojo_renderer.h"
42 #include "media/mojo/interfaces/interface_factory.mojom.h" 41 #include "media/mojo/interfaces/interface_factory.mojom.h"
43 #include "media/mojo/interfaces/renderer.mojom.h" 42 #include "media/mojo/interfaces/renderer.mojom.h"
44 #include "services/service_manager/public/cpp/connect.h" 43 #include "services/service_manager/public/cpp/connect.h"
45 #include "services/service_manager/public/cpp/service_test.h" 44 #include "services/service_manager/public/cpp/service_test.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 #endif 86 #endif
88 87
89 using testing::_; 88 using testing::_;
90 using testing::AnyNumber; 89 using testing::AnyNumber;
91 using testing::AtLeast; 90 using testing::AtLeast;
92 using testing::AtMost; 91 using testing::AtMost;
93 using testing::SaveArg; 92 using testing::SaveArg;
94 93
95 namespace media { 94 namespace media {
96 95
97 const char kSourceId[] = "SourceId";
98
99 const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\""; 96 const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\"";
100 const char kWebMVP9[] = "video/webm; codecs=\"vp9\""; 97 const char kWebMVP9[] = "video/webm; codecs=\"vp9\"";
101 const char kAudioOnlyWebM[] = "video/webm; codecs=\"vorbis\""; 98 const char kAudioOnlyWebM[] = "video/webm; codecs=\"vorbis\"";
102 const char kOpusAudioOnlyWebM[] = "video/webm; codecs=\"opus\""; 99 const char kOpusAudioOnlyWebM[] = "video/webm; codecs=\"opus\"";
103 const char kVideoOnlyWebM[] = "video/webm; codecs=\"vp8\""; 100 const char kVideoOnlyWebM[] = "video/webm; codecs=\"vp8\"";
104 #if BUILDFLAG(USE_PROPRIETARY_CODECS) 101 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
105 const char kADTS[] = "audio/aac"; 102 const char kADTS[] = "audio/aac";
106 const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\""; 103 const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\"";
107 const char kMP4VideoAVC3[] = "video/mp4; codecs=\"avc3.64001f\""; 104 const char kMP4VideoAVC3[] = "video/mp4; codecs=\"avc3.64001f\"";
108 const char kMP4VideoVP9[] = "video/mp4; codecs=\"vp09.00.10.08.01.05.01\""; 105 const char kMP4VideoVP9[] = "video/mp4; codecs=\"vp09.00.10.08.01.05.01\"";
109 const char kMP4VideoHEVC1[] = "video/mp4; codecs=\"hvc1.1.6.L93.B0\""; 106 const char kMP4VideoHEVC1[] = "video/mp4; codecs=\"hvc1.1.6.L93.B0\"";
110 const char kMP4VideoHEVC2[] = "video/mp4; codecs=\"hev1.1.6.L93.B0\""; 107 const char kMP4VideoHEVC2[] = "video/mp4; codecs=\"hev1.1.6.L93.B0\"";
111 const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\""; 108 const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\"";
112 const char kMP4Audio[] = "audio/mp4; codecs=\"mp4a.40.2\""; 109 const char kMP4Audio[] = "audio/mp4; codecs=\"mp4a.40.2\"";
113 const char kMP3[] = "audio/mpeg"; 110 const char kMP3[] = "audio/mpeg";
114 const char kMP2AudioSBR[] = "video/mp2t; codecs=\"avc1.4D4041,mp4a.40.5\""; 111 const char kMP2AudioSBR[] = "video/mp2t; codecs=\"avc1.4D4041,mp4a.40.5\"";
115 #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) 112 #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
116 113
117 const size_t kAppendWholeFile = std::numeric_limits<size_t>::max();
118
119 // Constants for the Media Source config change tests. 114 // Constants for the Media Source config change tests.
120 const int kAppendTimeSec = 1; 115 const int kAppendTimeSec = 1;
121 const int kAppendTimeMs = kAppendTimeSec * 1000; 116 const int kAppendTimeMs = kAppendTimeSec * 1000;
122 const int k320WebMFileDurationMs = 2736; 117 const int k320WebMFileDurationMs = 2736;
123 const int k640WebMFileDurationMs = 2749; 118 const int k640WebMFileDurationMs = 2749;
124 const int kOpusEndTrimmingWebMFileDurationMs = 2741; 119 const int kOpusEndTrimmingWebMFileDurationMs = 2741;
125 const int kVP9WebMFileDurationMs = 2736; 120 const int kVP9WebMFileDurationMs = 2736;
126 const int kVP8AWebMFileDurationMs = 2734; 121 const int kVP8AWebMFileDurationMs = 2734;
127 122
128 #if !defined(MOJO_RENDERER) 123 #if !defined(MOJO_RENDERER)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 exploded_time.second = 56; 175 exploded_time.second = 56;
181 exploded_time.millisecond = 789; 176 exploded_time.millisecond = 789;
182 base::Time timeline_offset; 177 base::Time timeline_offset;
183 EXPECT_TRUE(base::Time::FromUTCExploded(exploded_time, &timeline_offset)); 178 EXPECT_TRUE(base::Time::FromUTCExploded(exploded_time, &timeline_offset));
184 179
185 timeline_offset += base::TimeDelta::FromMicroseconds(123); 180 timeline_offset += base::TimeDelta::FromMicroseconds(123);
186 181
187 return timeline_offset; 182 return timeline_offset;
188 } 183 }
189 184
190 // Note: Tests using this class only exercise the DecryptingDemuxerStream path.
191 // They do not exercise the Decrypting{Audio|Video}Decoder path.
192 class FakeEncryptedMedia {
193 public:
194 // Defines the behavior of the "app" that responds to EME events.
195 class AppBase {
196 public:
197 virtual ~AppBase() {}
198
199 virtual void OnSessionMessage(
200 const std::string& session_id,
201 ContentDecryptionModule::MessageType message_type,
202 const std::vector<uint8_t>& message,
203 AesDecryptor* decryptor) = 0;
204
205 virtual void OnSessionClosed(const std::string& session_id) = 0;
206
207 virtual void OnSessionKeysChange(const std::string& session_id,
208 bool has_additional_usable_key,
209 CdmKeysInfo keys_info) = 0;
210
211 virtual void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
212 const std::vector<uint8_t>& init_data,
213 AesDecryptor* decryptor) = 0;
214 };
215
216 FakeEncryptedMedia(AppBase* app)
217 : decryptor_(new AesDecryptor(
218 GURL::EmptyGURL(),
219 base::Bind(&FakeEncryptedMedia::OnSessionMessage,
220 base::Unretained(this)),
221 base::Bind(&FakeEncryptedMedia::OnSessionClosed,
222 base::Unretained(this)),
223 base::Bind(&FakeEncryptedMedia::OnSessionKeysChange,
224 base::Unretained(this)))),
225 cdm_context_(decryptor_.get()),
226 app_(app) {}
227
228 CdmContext* GetCdmContext() { return &cdm_context_; }
229
230 // Callbacks for firing session events. Delegate to |app_|.
231 void OnSessionMessage(const std::string& session_id,
232 ContentDecryptionModule::MessageType message_type,
233 const std::vector<uint8_t>& message) {
234 app_->OnSessionMessage(session_id, message_type, message, decryptor_.get());
235 }
236
237 void OnSessionClosed(const std::string& session_id) {
238 app_->OnSessionClosed(session_id);
239 }
240
241 void OnSessionKeysChange(const std::string& session_id,
242 bool has_additional_usable_key,
243 CdmKeysInfo keys_info) {
244 app_->OnSessionKeysChange(session_id, has_additional_usable_key,
245 std::move(keys_info));
246 }
247
248 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
249 const std::vector<uint8_t>& init_data) {
250 app_->OnEncryptedMediaInitData(init_data_type, init_data, decryptor_.get());
251 }
252
253 private:
254 class TestCdmContext : public CdmContext {
255 public:
256 TestCdmContext(Decryptor* decryptor) : decryptor_(decryptor) {}
257
258 Decryptor* GetDecryptor() final { return decryptor_; }
259 int GetCdmId() const final { return kInvalidCdmId; }
260
261 private:
262 Decryptor* decryptor_;
263 };
264
265 scoped_refptr<AesDecryptor> decryptor_;
266 TestCdmContext cdm_context_;
267 std::unique_ptr<AppBase> app_;
268 };
269
270 enum PromiseResult { RESOLVED, REJECTED }; 185 enum PromiseResult { RESOLVED, REJECTED };
271 186
272 // Provides the test key in response to the encrypted event. 187 // Provides the test key in response to the encrypted event.
273 class KeyProvidingApp : public FakeEncryptedMedia::AppBase { 188 class KeyProvidingApp : public FakeEncryptedMedia::AppBase {
274 public: 189 public:
275 KeyProvidingApp() {} 190 KeyProvidingApp() {}
276 191
277 void OnResolveWithSession(PromiseResult expected, 192 void OnResolveWithSession(PromiseResult expected,
278 const std::string& session_id) { 193 const std::string& session_id) {
279 EXPECT_EQ(expected, RESOLVED); 194 EXPECT_EQ(expected, RESOLVED);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 CdmKeysInfo keys_info) override { 350 CdmKeysInfo keys_info) override {
436 EXPECT_FALSE(session_id.empty()); 351 EXPECT_FALSE(session_id.empty());
437 EXPECT_EQ(has_additional_usable_key, true); 352 EXPECT_EQ(has_additional_usable_key, true);
438 } 353 }
439 354
440 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, 355 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
441 const std::vector<uint8_t>& init_data, 356 const std::vector<uint8_t>& init_data,
442 AesDecryptor* decryptor) override {} 357 AesDecryptor* decryptor) override {}
443 }; 358 };
444 359
445 // Helper class that emulates calls made on the ChunkDemuxer by the
446 // Media Source API.
447 class MockMediaSource {
448 public:
449 MockMediaSource(const std::string& filename,
450 const std::string& mimetype,
451 size_t initial_append_size)
452 : current_position_(0),
453 initial_append_size_(initial_append_size),
454 mimetype_(mimetype),
455 chunk_demuxer_(new ChunkDemuxer(
456 base::Bind(&MockMediaSource::DemuxerOpened, base::Unretained(this)),
457 base::Bind(&MockMediaSource::OnEncryptedMediaInitData,
458 base::Unretained(this)),
459 &media_log_)),
460 owned_chunk_demuxer_(chunk_demuxer_) {
461 file_data_ = ReadTestDataFile(filename);
462
463 if (initial_append_size_ == kAppendWholeFile)
464 initial_append_size_ = file_data_->data_size();
465
466 DCHECK_GT(initial_append_size_, 0u);
467 DCHECK_LE(initial_append_size_, file_data_->data_size());
468 }
469
470 virtual ~MockMediaSource() {}
471
472 std::unique_ptr<Demuxer> GetDemuxer() {
473 return std::move(owned_chunk_demuxer_);
474 }
475
476 void set_encrypted_media_init_data_cb(
477 const Demuxer::EncryptedMediaInitDataCB& encrypted_media_init_data_cb) {
478 encrypted_media_init_data_cb_ = encrypted_media_init_data_cb;
479 }
480
481 void set_demuxer_failure_cb(const PipelineStatusCB& demuxer_failure_cb) {
482 demuxer_failure_cb_ = demuxer_failure_cb;
483 }
484
485 void Seek(base::TimeDelta seek_time,
486 size_t new_position,
487 size_t seek_append_size) {
488 chunk_demuxer_->StartWaitingForSeek(seek_time);
489
490 chunk_demuxer_->ResetParserState(kSourceId, base::TimeDelta(),
491 kInfiniteDuration,
492 &last_timestamp_offset_);
493
494 DCHECK_LT(new_position, file_data_->data_size());
495 current_position_ = new_position;
496
497 AppendData(seek_append_size);
498 }
499
500 void Seek(base::TimeDelta seek_time) {
501 chunk_demuxer_->StartWaitingForSeek(seek_time);
502 }
503
504 void AppendData(size_t size) {
505 DCHECK(chunk_demuxer_);
506 DCHECK_LT(current_position_, file_data_->data_size());
507 DCHECK_LE(current_position_ + size, file_data_->data_size());
508
509 ASSERT_TRUE(chunk_demuxer_->AppendData(
510 kSourceId, file_data_->data() + current_position_, size,
511 base::TimeDelta(), kInfiniteDuration, &last_timestamp_offset_));
512 current_position_ += size;
513 }
514
515 bool AppendAtTime(base::TimeDelta timestamp_offset,
516 const uint8_t* pData,
517 int size) {
518 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
519 bool success =
520 chunk_demuxer_->AppendData(kSourceId, pData, size, base::TimeDelta(),
521 kInfiniteDuration, &timestamp_offset);
522 last_timestamp_offset_ = timestamp_offset;
523 return success;
524 }
525
526 void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset,
527 base::TimeDelta append_window_start,
528 base::TimeDelta append_window_end,
529 const uint8_t* pData,
530 int size) {
531 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
532 ASSERT_TRUE(
533 chunk_demuxer_->AppendData(kSourceId, pData, size, append_window_start,
534 append_window_end, &timestamp_offset));
535 last_timestamp_offset_ = timestamp_offset;
536 }
537
538 void SetMemoryLimits(size_t limit_bytes) {
539 chunk_demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, limit_bytes);
540 chunk_demuxer_->SetMemoryLimitsForTest(DemuxerStream::VIDEO, limit_bytes);
541 }
542
543 bool EvictCodedFrames(base::TimeDelta currentMediaTime, size_t newDataSize) {
544 return chunk_demuxer_->EvictCodedFrames(kSourceId, currentMediaTime,
545 newDataSize);
546 }
547
548 void RemoveRange(base::TimeDelta start, base::TimeDelta end) {
549 chunk_demuxer_->Remove(kSourceId, start, end);
550 }
551
552 void EndOfStream() { chunk_demuxer_->MarkEndOfStream(PIPELINE_OK); }
553
554 void Shutdown() {
555 if (!chunk_demuxer_)
556 return;
557 chunk_demuxer_->ResetParserState(kSourceId, base::TimeDelta(),
558 kInfiniteDuration,
559 &last_timestamp_offset_);
560 chunk_demuxer_->Shutdown();
561 chunk_demuxer_ = NULL;
562 }
563
564 void DemuxerOpened() {
565 base::ThreadTaskRunnerHandle::Get()->PostTask(
566 FROM_HERE, base::Bind(&MockMediaSource::DemuxerOpenedTask,
567 base::Unretained(this)));
568 }
569
570 void DemuxerOpenedTask() {
571 ChunkDemuxer::Status status = AddId();
572 if (status != ChunkDemuxer::kOk) {
573 CHECK(!demuxer_failure_cb_.is_null());
574 demuxer_failure_cb_.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
575 return;
576 }
577 chunk_demuxer_->SetTracksWatcher(
578 kSourceId, base::Bind(&MockMediaSource::InitSegmentReceived,
579 base::Unretained(this)));
580
581 AppendData(initial_append_size_);
582 }
583
584 ChunkDemuxer::Status AddId() {
585 // This code assumes that |mimetype_| is one of the following forms.
586 // 1. audio/mpeg
587 // 2. video/webm;codec="vorbis,vp8".
588 size_t semicolon = mimetype_.find(";");
589 std::string type = mimetype_;
590 std::string codecs_param = "";
591 if (semicolon != std::string::npos) {
592 type = mimetype_.substr(0, semicolon);
593 size_t codecs_param_start = mimetype_.find("codecs=\"", semicolon);
594
595 CHECK_NE(codecs_param_start, std::string::npos);
596
597 codecs_param_start += 8; // Skip over the codecs=".
598
599 size_t codecs_param_end = mimetype_.find("\"", codecs_param_start);
600
601 CHECK_NE(codecs_param_end, std::string::npos);
602
603 codecs_param = mimetype_.substr(codecs_param_start,
604 codecs_param_end - codecs_param_start);
605 }
606
607 return chunk_demuxer_->AddId(kSourceId, type, codecs_param);
608 }
609
610 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
611 const std::vector<uint8_t>& init_data) {
612 DCHECK(!init_data.empty());
613 CHECK(!encrypted_media_init_data_cb_.is_null());
614 encrypted_media_init_data_cb_.Run(init_data_type, init_data);
615 }
616
617 base::TimeDelta last_timestamp_offset() const {
618 return last_timestamp_offset_;
619 }
620
621 void InitSegmentReceived(std::unique_ptr<MediaTracks> tracks) {
622 CHECK(tracks.get());
623 EXPECT_GT(tracks->tracks().size(), 0u);
624 CHECK(chunk_demuxer_);
625 // Verify that track ids are unique.
626 std::set<MediaTrack::Id> track_ids;
627 for (const auto& track : tracks->tracks()) {
628 EXPECT_EQ(track_ids.end(), track_ids.find(track->id()));
629 track_ids.insert(track->id());
630 }
631 InitSegmentReceivedMock(tracks);
632 }
633
634 MOCK_METHOD1(InitSegmentReceivedMock, void(std::unique_ptr<MediaTracks>&));
635
636 private:
637 MediaLog media_log_;
638 scoped_refptr<DecoderBuffer> file_data_;
639 size_t current_position_;
640 size_t initial_append_size_;
641 std::string mimetype_;
642 ChunkDemuxer* chunk_demuxer_;
643 std::unique_ptr<Demuxer> owned_chunk_demuxer_;
644 PipelineStatusCB demuxer_failure_cb_;
645 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_;
646 base::TimeDelta last_timestamp_offset_;
647 };
648
649 // A rough simulation of GpuVideoDecoder that fails every Decode() request. This 360 // A rough simulation of GpuVideoDecoder that fails every Decode() request. This
650 // is used to test post-Initialize() fallback paths. 361 // is used to test post-Initialize() fallback paths.
651 class FailingVideoDecoder : public VideoDecoder { 362 class FailingVideoDecoder : public VideoDecoder {
652 public: 363 public:
653 std::string GetDisplayName() const override { return "FailingVideoDecoder"; } 364 std::string GetDisplayName() const override { return "FailingVideoDecoder"; }
654 void Initialize(const VideoDecoderConfig& config, 365 void Initialize(const VideoDecoderConfig& config,
655 bool low_delay, 366 bool low_delay,
656 CdmContext* cdm_context, 367 CdmContext* cdm_context,
657 const InitCB& init_cb, 368 const InitCB& init_cb,
658 const OutputCB& output_cb) override { 369 const OutputCB& output_cb) override {
659 init_cb.Run(true); 370 init_cb.Run(true);
660 } 371 }
661 void Decode(const scoped_refptr<DecoderBuffer>& buffer, 372 void Decode(const scoped_refptr<DecoderBuffer>& buffer,
662 const DecodeCB& decode_cb) override { 373 const DecodeCB& decode_cb) override {
663 base::ThreadTaskRunnerHandle::Get()->PostTask( 374 base::ThreadTaskRunnerHandle::Get()->PostTask(
664 FROM_HERE, base::Bind(decode_cb, DecodeStatus::DECODE_ERROR)); 375 FROM_HERE, base::Bind(decode_cb, DecodeStatus::DECODE_ERROR));
665 } 376 }
666 void Reset(const base::Closure& closure) override { closure.Run(); } 377 void Reset(const base::Closure& closure) override { closure.Run(); }
667 bool NeedsBitstreamConversion() const override { return true; } 378 bool NeedsBitstreamConversion() const override { return true; }
668 }; 379 };
669 380
670 // TODO(xhwang): These tests have been disabled for some time as apptests and no 381 // TODO(xhwang): These tests have been disabled for some time as apptests and no
671 // longer pass. They need to be reconstituted as shell tests. 382 // longer pass. They need to be reconstituted as shell tests.
672 // Currently there are compile issues which must be resolved, 383 // Currently there are compile issues which must be resolved,
673 // preferably by eliminating multiple inheritance here which is 384 // preferably by eliminating multiple inheritance here which is
674 // banned by Google C++ style. 385 // banned by Google C++ style.
675 #if defined(MOJO_RENDERER) && defined(ENABLE_MOJO_PIPELINE_INTEGRATION_TEST) 386 #if defined(MOJO_RENDERER) && defined(ENABLE_MOJO_PIPELINE_INTEGRATION_TEST)
676 class PipelineIntegrationTestHost : public service_manager::test::ServiceTest, 387 class PipelineIntegrationTest : public service_manager::test::ServiceTest,
677 public PipelineIntegrationTestBase { 388 public PipelineIntegrationTestBase {
678 public: 389 public:
679 PipelineIntegrationTestHost() 390 PipelineIntegrationTest()
680 : service_manager::test::ServiceTest( 391 : service_manager::test::ServiceTest(
681 "media_pipeline_integration_shelltests") {} 392 "media_pipeline_integration_shelltests") {}
682 393
683 void SetUp() override { 394 void SetUp() override {
684 ServiceTest::SetUp(); 395 ServiceTest::SetUp();
685 InitializeMediaLibrary(); 396 InitializeMediaLibrary();
686 } 397 }
687 398
688 protected: 399 protected:
689 std::unique_ptr<Renderer> CreateRenderer( 400 std::unique_ptr<Renderer> CreateRenderer(
690 CreateVideoDecodersCB prepend_video_decoders_cb, 401 CreateVideoDecodersCB prepend_video_decoders_cb,
691 CreateAudioDecodersCB prepend_audio_decoders_cb) override { 402 CreateAudioDecodersCB prepend_audio_decoders_cb) override {
692 connector()->BindInterface("media", &media_interface_factory_); 403 connector()->BindInterface("media", &media_interface_factory_);
693 404
694 mojom::RendererPtr mojo_renderer; 405 mojom::RendererPtr mojo_renderer;
695 media_interface_factory_->CreateRenderer(std::string(), 406 media_interface_factory_->CreateRenderer(std::string(),
696 mojo::MakeRequest(&mojo_renderer)); 407 mojo::MakeRequest(&mojo_renderer));
697 408
698 return base::MakeUnique<MojoRenderer>(message_loop_.task_runner(), 409 return base::MakeUnique<MojoRenderer>(message_loop_.task_runner(),
699 std::move(mojo_renderer)); 410 std::move(mojo_renderer));
700 } 411 }
701 412
702 private: 413 private:
703 mojom::InterfaceFactoryPtr media_interface_factory_; 414 mojom::InterfaceFactoryPtr media_interface_factory_;
704 }; 415 };
705 #else 416 #else
706 class PipelineIntegrationTestHost : public testing::Test, 417 class PipelineIntegrationTest : public testing::Test,
707 public PipelineIntegrationTestBase {}; 418 public PipelineIntegrationTestBase {
708 #endif // defined(MOJO_RENDERER)
709
710 class PipelineIntegrationTest : public PipelineIntegrationTestHost {
711 public: 419 public:
712 PipelineStatus StartPipelineWithMediaSource(MockMediaSource* source) {
713 return StartPipelineWithMediaSource(source, kNormal, nullptr);
714 }
715
716 PipelineStatus StartPipelineWithEncryptedMedia(
717 MockMediaSource* source,
718 FakeEncryptedMedia* encrypted_media) {
719 return StartPipelineWithMediaSource(source, kNormal, encrypted_media);
720 }
721
722 PipelineStatus StartPipelineWithMediaSource(
723 MockMediaSource* source,
724 uint8_t test_type,
725 FakeEncryptedMedia* encrypted_media) {
726 hashing_enabled_ = test_type & kHashed;
727 clockless_playback_ = test_type & kClockless;
728
729 if (!(test_type & kExpectDemuxerFailure))
730 EXPECT_CALL(*source, InitSegmentReceivedMock(_)).Times(AtLeast(1));
731
732 EXPECT_CALL(*this, OnMetadata(_))
733 .Times(AtMost(1))
734 .WillRepeatedly(SaveArg<0>(&metadata_));
735 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
736 .Times(AnyNumber());
737 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING))
738 .Times(AnyNumber());
739 EXPECT_CALL(*this, OnDurationChange()).Times(AnyNumber());
740 EXPECT_CALL(*this, OnVideoNaturalSizeChange(_)).Times(AtMost(1));
741 EXPECT_CALL(*this, OnVideoOpacityChange(_)).Times(AtMost(1));
742
743 source->set_demuxer_failure_cb(base::Bind(
744 &PipelineIntegrationTest::OnStatusCallback, base::Unretained(this)));
745 demuxer_ = source->GetDemuxer();
746
747 if (encrypted_media) {
748 EXPECT_CALL(*this, DecryptorAttached(true));
749
750 // Encrypted content used but keys provided in advance, so this is
751 // never called.
752 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
753 pipeline_->SetCdm(encrypted_media->GetCdmContext(),
754 base::Bind(&PipelineIntegrationTest::DecryptorAttached,
755 base::Unretained(this)));
756 } else {
757 // Encrypted content not used, so this is never called.
758 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
759 }
760
761 pipeline_->Start(demuxer_.get(), CreateRenderer(), this,
762 base::Bind(&PipelineIntegrationTest::OnStatusCallback,
763 base::Unretained(this)));
764
765 if (encrypted_media) {
766 source->set_encrypted_media_init_data_cb(
767 base::Bind(&FakeEncryptedMedia::OnEncryptedMediaInitData,
768 base::Unretained(encrypted_media)));
769 }
770 base::RunLoop().Run();
771 return pipeline_status_;
772 }
773
774 // Verifies that seeking works properly for ChunkDemuxer when the 420 // Verifies that seeking works properly for ChunkDemuxer when the
775 // seek happens while there is a pending read on the ChunkDemuxer 421 // seek happens while there is a pending read on the ChunkDemuxer
776 // and no data is available. 422 // and no data is available.
777 bool TestSeekDuringRead(const std::string& filename, 423 bool TestSeekDuringRead(const std::string& filename,
778 const std::string& mimetype, 424 const std::string& mimetype,
779 int initial_append_size, 425 int initial_append_size,
780 base::TimeDelta start_seek_time, 426 base::TimeDelta start_seek_time,
781 base::TimeDelta seek_time, 427 base::TimeDelta seek_time,
782 int seek_file_position, 428 int seek_file_position,
783 int seek_append_size) { 429 int seek_append_size) {
(...skipping 10 matching lines...) Expand all
794 if (!Seek(seek_time)) 440 if (!Seek(seek_time))
795 return false; 441 return false;
796 442
797 source.EndOfStream(); 443 source.EndOfStream();
798 444
799 source.Shutdown(); 445 source.Shutdown();
800 Stop(); 446 Stop();
801 return true; 447 return true;
802 } 448 }
803 }; 449 };
450 #endif // defined(MOJO_RENDERER)
804 451
805 struct PlaybackTestData { 452 struct PlaybackTestData {
806 const std::string filename; 453 const std::string filename;
807 const uint32_t start_time_ms; 454 const uint32_t start_time_ms;
808 const uint32_t duration_ms; 455 const uint32_t duration_ms;
809 }; 456 };
810 457
811 struct MSEPlaybackTestData { 458 struct MSEPlaybackTestData {
812 const std::string filename; 459 const std::string filename;
813 const std::string mimetype; 460 const std::string mimetype;
(...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after
2703 2350
2704 TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) { 2351 TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) {
2705 ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm")); 2352 ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm"));
2706 Play(); 2353 Play();
2707 ASSERT_TRUE(WaitUntilOnEnded()); 2354 ASSERT_TRUE(WaitUntilOnEnded());
2708 ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000), 2355 ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000),
2709 demuxer_->GetStartTime()); 2356 demuxer_->GetStartTime());
2710 } 2357 }
2711 2358
2712 } // namespace media 2359 } // namespace media
OLDNEW
« no previous file with comments | « media/test/mock_media_source.cc ('k') | media/test/pipeline_integration_test_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698