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
3 // found in the LICENSE file.
5 #include "media/filters/pipeline_integration_test_base.h"
8 #include "base/command_line.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_util.h"
11 #include "build/build_config.h"
12 #include "media/base/decoder_buffer.h"
13 #include "media/base/media_keys.h"
14 #include "media/base/media_switches.h"
15 #include "media/base/test_data_util.h"
16 #include "media/cdm/aes_decryptor.h"
17 #include "media/cdm/json_web_key.h"
18 #include "media/filters/chunk_demuxer.h"
21 using testing::AnyNumber;
22 using testing::AtMost;
23 using testing::SaveArg;
24 using testing::Values;
28 const char kSourceId[] = "SourceId";
29 const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 };
31 const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\"";
32 const char kWebMVP9[] = "video/webm; codecs=\"vp9\"";
33 const char kAudioOnlyWebM[] = "video/webm; codecs=\"vorbis\"";
34 const char kOpusAudioOnlyWebM[] = "video/webm; codecs=\"opus\"";
35 const char kVideoOnlyWebM[] = "video/webm; codecs=\"vp8\"";
36 const char kMP4VideoType[] = "video/mp4";
37 const char kMP4AudioType[] = "audio/mp4";
38 #if defined(USE_PROPRIETARY_CODECS)
39 const char kADTS[] = "audio/aac";
40 const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\"";
41 const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\"";
42 const char kMP4VideoAVC3[] = "video/mp4; codecs=\"avc3.64001f\"";
43 const char kMP4Audio[] = "audio/mp4; codecs=\"mp4a.40.2\"";
44 const char kMP3[] = "audio/mpeg";
45 #endif // defined(USE_PROPRIETARY_CODECS)
47 // Key used to encrypt test files.
48 const uint8 kSecretKey[] = {
49 0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
50 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c
53 // The key ID for all encrypted files.
54 const uint8 kKeyId[] = {
55 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
56 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35
59 const int kAppendWholeFile = -1;
61 // Constants for the Media Source config change tests.
62 const int kAppendTimeSec = 1;
63 const int kAppendTimeMs = kAppendTimeSec * 1000;
64 const int k320WebMFileDurationMs = 2736;
65 const int k640WebMFileDurationMs = 2749;
66 const int kOpusEndTrimmingWebMFileDurationMs = 2741;
67 const int kVP9WebMFileDurationMs = 2736;
68 const int kVP8AWebMFileDurationMs = 2733;
70 #if defined(USE_PROPRIETARY_CODECS)
71 const int k640IsoFileDurationMs = 2737;
72 const int k640IsoCencFileDurationMs = 2736;
73 const int k1280IsoFileDurationMs = 2736;
74 const int k1280IsoAVC3FileDurationMs = 2736;
75 #endif // defined(USE_PROPRIETARY_CODECS)
77 // Return a timeline offset for bear-320x240-live.webm.
78 static base::Time kLiveTimelineOffset() {
79 // The file contians the following UTC timeline offset:
80 // 2012-11-10 12:34:56.789123456
81 // Since base::Time only has a resolution of microseconds,
82 // construct a base::Time for 2012-11-10 12:34:56.789123.
83 base::Time::Exploded exploded_time;
84 exploded_time.year = 2012;
85 exploded_time.month = 11;
86 exploded_time.day_of_month = 10;
87 exploded_time.hour = 12;
88 exploded_time.minute = 34;
89 exploded_time.second = 56;
90 exploded_time.millisecond = 789;
91 base::Time timeline_offset = base::Time::FromUTCExploded(exploded_time);
93 timeline_offset += base::TimeDelta::FromMicroseconds(123);
95 return timeline_offset;
98 // FFmpeg only supports time a resolution of seconds so this
99 // helper function truncates a base::Time to seconds resolution.
100 static base::Time TruncateToFFmpegTimeResolution(base::Time t) {
101 base::Time::Exploded exploded_time;
102 t.UTCExplode(&exploded_time);
103 exploded_time.millisecond = 0;
105 return base::Time::FromUTCExploded(exploded_time);
108 // Note: Tests using this class only exercise the DecryptingDemuxerStream path.
109 // They do not exercise the Decrypting{Audio|Video}Decoder path.
110 class FakeEncryptedMedia {
112 // Defines the behavior of the "app" that responds to EME events.
115 virtual ~AppBase() {}
117 virtual void OnSessionCreated(uint32 session_id,
118 const std::string& web_session_id) = 0;
120 virtual void OnSessionMessage(uint32 session_id,
121 const std::vector<uint8>& message,
122 const std::string& destination_url) = 0;
124 virtual void OnSessionReady(uint32 session_id) = 0;
126 virtual void OnSessionClosed(uint32 session_id) = 0;
128 // Errors are not expected unless overridden.
129 virtual void OnSessionError(uint32 session_id,
130 MediaKeys::KeyError error_code,
131 uint32 system_code) {
132 FAIL() << "Unexpected Key Error";
135 virtual void NeedKey(const std::string& type,
136 const std::vector<uint8>& init_data,
137 AesDecryptor* decryptor) = 0;
140 FakeEncryptedMedia(AppBase* app)
141 : decryptor_(base::Bind(&FakeEncryptedMedia::OnSessionCreated,
142 base::Unretained(this)),
143 base::Bind(&FakeEncryptedMedia::OnSessionMessage,
144 base::Unretained(this)),
145 base::Bind(&FakeEncryptedMedia::OnSessionReady,
146 base::Unretained(this)),
147 base::Bind(&FakeEncryptedMedia::OnSessionClosed,
148 base::Unretained(this)),
149 base::Bind(&FakeEncryptedMedia::OnSessionError,
150 base::Unretained(this))),
153 AesDecryptor* decryptor() {
157 // Callbacks for firing session events. Delegate to |app_|.
158 void OnSessionCreated(uint32 session_id, const std::string& web_session_id) {
159 app_->OnSessionCreated(session_id, web_session_id);
162 void OnSessionMessage(uint32 session_id,
163 const std::vector<uint8>& message,
164 const std::string& destination_url) {
165 app_->OnSessionMessage(session_id, message, destination_url);
168 void OnSessionReady(uint32 session_id) {
169 app_->OnSessionReady(session_id);
172 void OnSessionClosed(uint32 session_id) {
173 app_->OnSessionClosed(session_id);
176 void OnSessionError(uint32 session_id,
177 MediaKeys::KeyError error_code,
178 uint32 system_code) {
179 app_->OnSessionError(session_id, error_code, system_code);
182 void NeedKey(const std::string& type,
183 const std::vector<uint8>& init_data) {
184 app_->NeedKey(type, init_data, &decryptor_);
188 AesDecryptor decryptor_;
189 scoped_ptr<AppBase> app_;
192 // Provides |kSecretKey| in response to needkey.
193 class KeyProvidingApp : public FakeEncryptedMedia::AppBase {
195 KeyProvidingApp() : current_session_id_(0) {}
197 virtual void OnSessionCreated(uint32 session_id,
198 const std::string& web_session_id) OVERRIDE {
199 EXPECT_GT(session_id, 0u);
200 EXPECT_FALSE(web_session_id.empty());
203 virtual void OnSessionMessage(uint32 session_id,
204 const std::vector<uint8>& message,
205 const std::string& default_url) OVERRIDE {
206 EXPECT_GT(session_id, 0u);
207 EXPECT_FALSE(message.empty());
209 current_session_id_ = session_id;
212 virtual void OnSessionReady(uint32 session_id) OVERRIDE {
213 EXPECT_GT(session_id, 0u);
216 virtual void OnSessionClosed(uint32 session_id) OVERRIDE {
217 EXPECT_GT(session_id, 0u);
220 virtual void NeedKey(const std::string& type,
221 const std::vector<uint8>& init_data,
222 AesDecryptor* decryptor) OVERRIDE {
223 if (current_session_id_ == 0u) {
225 decryptor->CreateSession(12, type, kInitData, arraysize(kInitData)));
228 EXPECT_EQ(current_session_id_, 12u);
230 // Clear Key really needs the key ID in |init_data|. For WebM, they are the
231 // same, but this is not the case for ISO CENC. Therefore, provide the
233 const uint8* key_id = init_data.empty() ? NULL : &init_data[0];
234 size_t key_id_length = init_data.size();
235 if (type == kMP4AudioType || type == kMP4VideoType) {
237 key_id_length = arraysize(kKeyId);
240 // Convert key into a JSON structure and then add it.
241 std::string jwk = GenerateJWKSet(
242 kSecretKey, arraysize(kSecretKey), key_id, key_id_length);
243 decryptor->UpdateSession(current_session_id_,
244 reinterpret_cast<const uint8*>(jwk.data()),
248 uint32 current_session_id_;
251 // Ignores needkey and does not perform a license request
252 class NoResponseApp : public FakeEncryptedMedia::AppBase {
254 virtual void OnSessionCreated(uint32 session_id,
255 const std::string& web_session_id) OVERRIDE {
256 EXPECT_GT(session_id, 0u);
257 EXPECT_FALSE(web_session_id.empty());
260 virtual void OnSessionMessage(uint32 session_id,
261 const std::vector<uint8>& message,
262 const std::string& default_url) OVERRIDE {
263 EXPECT_GT(session_id, 0u);
264 EXPECT_FALSE(message.empty());
265 FAIL() << "Unexpected KeyMessage";
268 virtual void OnSessionReady(uint32 session_id) OVERRIDE {
269 EXPECT_GT(session_id, 0u);
270 FAIL() << "Unexpected Ready";
273 virtual void OnSessionClosed(uint32 session_id) OVERRIDE {
274 EXPECT_GT(session_id, 0u);
275 FAIL() << "Unexpected Closed";
278 virtual void NeedKey(const std::string& type,
279 const std::vector<uint8>& init_data,
280 AesDecryptor* decryptor) OVERRIDE {
284 // Helper class that emulates calls made on the ChunkDemuxer by the
286 class MockMediaSource {
288 MockMediaSource(const std::string& filename,
289 const std::string& mimetype,
290 int initial_append_size,
291 const bool use_legacy_frame_processor)
292 : file_path_(GetTestDataFilePath(filename)),
293 current_position_(0),
294 initial_append_size_(initial_append_size),
296 chunk_demuxer_(new ChunkDemuxer(
297 base::Bind(&MockMediaSource::DemuxerOpened, base::Unretained(this)),
298 base::Bind(&MockMediaSource::DemuxerNeedKey,
299 base::Unretained(this)),
302 owned_chunk_demuxer_(chunk_demuxer_),
303 use_legacy_frame_processor_(use_legacy_frame_processor) {
305 file_data_ = ReadTestDataFile(filename);
307 if (initial_append_size_ == kAppendWholeFile)
308 initial_append_size_ = file_data_->data_size();
310 DCHECK_GT(initial_append_size_, 0);
311 DCHECK_LE(initial_append_size_, file_data_->data_size());
314 virtual ~MockMediaSource() {}
316 scoped_ptr<Demuxer> GetDemuxer() { return owned_chunk_demuxer_.Pass(); }
318 void set_need_key_cb(const Demuxer::NeedKeyCB& need_key_cb) {
319 need_key_cb_ = need_key_cb;
322 void Seek(base::TimeDelta seek_time, int new_position, int seek_append_size) {
323 chunk_demuxer_->StartWaitingForSeek(seek_time);
325 // TODO(wolenetz): Test timestamp offset updating once "sequence" append
326 // mode processing is implemented. See http://crbug.com/249422.
327 chunk_demuxer_->Abort(
329 base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_);
331 DCHECK_GE(new_position, 0);
332 DCHECK_LT(new_position, file_data_->data_size());
333 current_position_ = new_position;
335 AppendData(seek_append_size);
338 void AppendData(int size) {
339 DCHECK(chunk_demuxer_);
340 DCHECK_LT(current_position_, file_data_->data_size());
341 DCHECK_LE(current_position_ + size, file_data_->data_size());
343 // TODO(wolenetz): Test timestamp offset updating once "sequence" append
344 // mode processing is implemented. See http://crbug.com/249422.
345 chunk_demuxer_->AppendData(
346 kSourceId, file_data_->data() + current_position_, size,
347 base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_);
348 current_position_ += size;
351 void AppendAtTime(base::TimeDelta timestamp_offset,
354 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
355 chunk_demuxer_->AppendData(kSourceId, pData, size,
356 base::TimeDelta(), kInfiniteDuration(),
358 last_timestamp_offset_ = timestamp_offset;
361 void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset,
362 base::TimeDelta append_window_start,
363 base::TimeDelta append_window_end,
366 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
367 chunk_demuxer_->AppendData(kSourceId,
373 last_timestamp_offset_ = timestamp_offset;
377 chunk_demuxer_->MarkEndOfStream(PIPELINE_OK);
383 chunk_demuxer_->Shutdown();
384 chunk_demuxer_ = NULL;
387 void DemuxerOpened() {
388 base::MessageLoop::current()->PostTask(
389 FROM_HERE, base::Bind(&MockMediaSource::DemuxerOpenedTask,
390 base::Unretained(this)));
393 void DemuxerOpenedTask() {
394 // This code assumes that |mimetype_| is one of the following forms.
396 // 2. video/webm;codec="vorbis,vp8".
397 size_t semicolon = mimetype_.find(";");
398 std::string type = mimetype_;
399 std::vector<std::string> codecs;
400 if (semicolon != std::string::npos) {
401 type = mimetype_.substr(0, semicolon);
402 size_t codecs_param_start = mimetype_.find("codecs=\"", semicolon);
404 CHECK_NE(codecs_param_start, std::string::npos);
406 codecs_param_start += 8; // Skip over the codecs=".
408 size_t codecs_param_end = mimetype_.find("\"", codecs_param_start);
410 CHECK_NE(codecs_param_end, std::string::npos);
412 std::string codecs_param =
413 mimetype_.substr(codecs_param_start,
414 codecs_param_end - codecs_param_start);
415 Tokenize(codecs_param, ",", &codecs);
418 CHECK_EQ(chunk_demuxer_->AddId(kSourceId, type, codecs,
419 use_legacy_frame_processor_),
422 AppendData(initial_append_size_);
425 void DemuxerNeedKey(const std::string& type,
426 const std::vector<uint8>& init_data) {
427 DCHECK(!init_data.empty());
428 CHECK(!need_key_cb_.is_null());
429 need_key_cb_.Run(type, init_data);
432 base::TimeDelta last_timestamp_offset() const {
433 return last_timestamp_offset_;
437 base::FilePath file_path_;
438 scoped_refptr<DecoderBuffer> file_data_;
439 int current_position_;
440 int initial_append_size_;
441 std::string mimetype_;
442 ChunkDemuxer* chunk_demuxer_;
443 scoped_ptr<Demuxer> owned_chunk_demuxer_;
444 Demuxer::NeedKeyCB need_key_cb_;
445 base::TimeDelta last_timestamp_offset_;
446 bool use_legacy_frame_processor_;
449 // Test parameter determines which coded frame processor is used to process
450 // appended data, and is only applicable in tests where the pipeline is using a
451 // (Mock)MediaSource (which are TEST_P, not TEST_F). If true,
452 // LegacyFrameProcessor is used. Otherwise, the new FrameProcessor is used.
453 class PipelineIntegrationTest
454 : public testing::TestWithParam<bool>,
455 public PipelineIntegrationTestBase {
457 void StartPipelineWithMediaSource(MockMediaSource* source) {
458 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1))
459 .WillRepeatedly(SaveArg<0>(&metadata_));
460 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
462 CreateFilterCollection(source->GetDemuxer(), NULL),
463 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
464 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
465 QuitOnStatusCB(PIPELINE_OK),
466 base::Bind(&PipelineIntegrationTest::OnMetadata,
467 base::Unretained(this)),
468 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted,
469 base::Unretained(this)),
475 void StartHashedPipelineWithMediaSource(MockMediaSource* source) {
476 hashing_enabled_ = true;
477 StartPipelineWithMediaSource(source);
480 void StartPipelineWithEncryptedMedia(
481 MockMediaSource* source,
482 FakeEncryptedMedia* encrypted_media) {
483 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1))
484 .WillRepeatedly(SaveArg<0>(&metadata_));
485 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
487 CreateFilterCollection(source->GetDemuxer(),
488 encrypted_media->decryptor()),
489 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
490 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
491 QuitOnStatusCB(PIPELINE_OK),
492 base::Bind(&PipelineIntegrationTest::OnMetadata,
493 base::Unretained(this)),
494 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted,
495 base::Unretained(this)),
498 source->set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey,
499 base::Unretained(encrypted_media)));
504 // Verifies that seeking works properly for ChunkDemuxer when the
505 // seek happens while there is a pending read on the ChunkDemuxer
506 // and no data is available.
507 bool TestSeekDuringRead(const std::string& filename,
508 const std::string& mimetype,
509 int initial_append_size,
510 base::TimeDelta start_seek_time,
511 base::TimeDelta seek_time,
512 int seek_file_position,
513 int seek_append_size) {
514 MockMediaSource source(filename, mimetype, initial_append_size,
516 StartPipelineWithMediaSource(&source);
518 if (pipeline_status_ != PIPELINE_OK)
522 if (!WaitUntilCurrentTimeIsAfter(start_seek_time))
525 source.Seek(seek_time, seek_file_position, seek_append_size);
526 if (!Seek(seek_time))
529 source.EndOfStream();
537 TEST_F(PipelineIntegrationTest, BasicPlayback) {
538 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK));
542 ASSERT_TRUE(WaitUntilOnEnded());
545 TEST_F(PipelineIntegrationTest, BasicPlaybackOpusOgg) {
546 ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus.ogg"), PIPELINE_OK));
550 ASSERT_TRUE(WaitUntilOnEnded());
553 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed) {
555 GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK, kHashed));
559 ASSERT_TRUE(WaitUntilOnEnded());
561 EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash());
562 EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash());
563 EXPECT_TRUE(demuxer_->GetTimelineOffset().is_null());
566 TEST_F(PipelineIntegrationTest, BasicPlaybackLive) {
568 GetTestDataFilePath("bear-320x240-live.webm"), PIPELINE_OK, kHashed));
572 ASSERT_TRUE(WaitUntilOnEnded());
574 EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash());
575 EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash());
577 // TODO: Fix FFmpeg code to return higher resolution time values so
578 // we don't have to truncate our expectations here.
579 EXPECT_EQ(TruncateToFFmpegTimeResolution(kLiveTimelineOffset()),
580 demuxer_->GetTimelineOffset());
583 TEST_F(PipelineIntegrationTest, F32PlaybackHashed) {
585 Start(GetTestDataFilePath("sfx_f32le.wav"), PIPELINE_OK, kHashed));
587 ASSERT_TRUE(WaitUntilOnEnded());
588 EXPECT_EQ(std::string(kNullVideoHash), GetVideoHash());
589 EXPECT_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
592 TEST_F(PipelineIntegrationTest, BasicPlaybackEncrypted) {
593 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
594 set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey,
595 base::Unretained(&encrypted_media)));
597 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-av_enc-av.webm"),
598 encrypted_media.decryptor()));
602 ASSERT_TRUE(WaitUntilOnEnded());
606 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource) {
607 MockMediaSource source("bear-320x240.webm", kWebM, 219229, GetParam());
608 StartPipelineWithMediaSource(&source);
609 source.EndOfStream();
611 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
612 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
613 EXPECT_EQ(k320WebMFileDurationMs,
614 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
618 ASSERT_TRUE(WaitUntilOnEnded());
620 EXPECT_TRUE(demuxer_->GetTimelineOffset().is_null());
625 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_Live) {
626 MockMediaSource source("bear-320x240-live.webm", kWebM, 219221, GetParam());
627 StartPipelineWithMediaSource(&source);
628 source.EndOfStream();
630 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
631 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
632 EXPECT_EQ(k320WebMFileDurationMs,
633 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
637 ASSERT_TRUE(WaitUntilOnEnded());
639 EXPECT_EQ(kLiveTimelineOffset(),
640 demuxer_->GetTimelineOffset());
645 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP9_WebM) {
646 MockMediaSource source("bear-vp9.webm", kWebMVP9, 67504, GetParam());
647 StartPipelineWithMediaSource(&source);
648 source.EndOfStream();
650 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
651 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
652 EXPECT_EQ(kVP9WebMFileDurationMs,
653 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
657 ASSERT_TRUE(WaitUntilOnEnded());
662 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP8A_WebM) {
663 MockMediaSource source("bear-vp8a.webm", kVideoOnlyWebM, kAppendWholeFile,
665 StartPipelineWithMediaSource(&source);
666 source.EndOfStream();
668 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
669 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
670 EXPECT_EQ(kVP8AWebMFileDurationMs,
671 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
675 ASSERT_TRUE(WaitUntilOnEnded());
680 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_Opus_WebM) {
681 MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
682 kAppendWholeFile, GetParam());
683 StartPipelineWithMediaSource(&source);
684 source.EndOfStream();
686 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
687 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
688 EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
689 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
692 ASSERT_TRUE(WaitUntilOnEnded());
697 // Flaky. http://crbug.com/304776
698 TEST_P(PipelineIntegrationTest, DISABLED_MediaSource_Opus_Seeking_WebM) {
699 MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
700 kAppendWholeFile, GetParam());
701 StartHashedPipelineWithMediaSource(&source);
703 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
704 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
705 EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
706 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
708 base::TimeDelta start_seek_time = base::TimeDelta::FromMilliseconds(1000);
709 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2000);
712 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
713 source.Seek(seek_time, 0x1D5, 34017);
714 source.EndOfStream();
715 ASSERT_TRUE(Seek(seek_time));
717 ASSERT_TRUE(WaitUntilOnEnded());
719 EXPECT_EQ("0.76,0.20,-0.82,-0.58,-1.29,-0.29,", GetAudioHash());
725 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_WebM) {
726 MockMediaSource source("bear-320x240-16x9-aspect.webm", kWebM,
727 kAppendWholeFile, GetParam());
728 StartPipelineWithMediaSource(&source);
730 scoped_refptr<DecoderBuffer> second_file =
731 ReadTestDataFile("bear-640x360.webm");
733 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
734 second_file->data(), second_file->data_size());
736 source.EndOfStream();
738 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
739 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
740 EXPECT_EQ(kAppendTimeMs + k640WebMFileDurationMs,
741 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
745 EXPECT_TRUE(WaitUntilOnEnded());
750 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_Encrypted_WebM) {
751 MockMediaSource source("bear-320x240-16x9-aspect-av_enc-av.webm", kWebM,
752 kAppendWholeFile, GetParam());
753 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
754 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
756 scoped_refptr<DecoderBuffer> second_file =
757 ReadTestDataFile("bear-640x360-av_enc-av.webm");
759 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
760 second_file->data(), second_file->data_size());
762 source.EndOfStream();
764 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
765 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
766 EXPECT_EQ(kAppendTimeMs + k640WebMFileDurationMs,
767 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
771 EXPECT_TRUE(WaitUntilOnEnded());
776 // Config changes from encrypted to clear are not currently supported.
777 TEST_P(PipelineIntegrationTest,
778 MediaSource_ConfigChange_ClearThenEncrypted_WebM) {
779 MockMediaSource source("bear-320x240-16x9-aspect.webm", kWebM,
780 kAppendWholeFile, GetParam());
781 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
782 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
784 scoped_refptr<DecoderBuffer> second_file =
785 ReadTestDataFile("bear-640x360-av_enc-av.webm");
787 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
788 second_file->data(), second_file->data_size());
790 source.EndOfStream();
793 EXPECT_EQ(PIPELINE_ERROR_DECODE, pipeline_status_);
795 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
796 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
797 // The second video was not added, so its time has not been added.
798 EXPECT_EQ(k320WebMFileDurationMs,
799 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
803 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
807 // Config changes from clear to encrypted are not currently supported.
808 TEST_P(PipelineIntegrationTest,
809 MediaSource_ConfigChange_EncryptedThenClear_WebM) {
810 MockMediaSource source("bear-320x240-16x9-aspect-av_enc-av.webm", kWebM,
811 kAppendWholeFile, GetParam());
812 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
813 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
815 scoped_refptr<DecoderBuffer> second_file =
816 ReadTestDataFile("bear-640x360.webm");
818 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
819 second_file->data(), second_file->data_size());
821 source.EndOfStream();
823 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
824 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
825 // The second video was not added, so its time has not been added.
826 EXPECT_EQ(k320WebMFileDurationMs,
827 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
831 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
835 #if defined(USE_PROPRIETARY_CODECS)
836 TEST_P(PipelineIntegrationTest, MediaSource_ADTS) {
837 MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile, GetParam());
838 StartPipelineWithMediaSource(&source);
839 source.EndOfStream();
841 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
842 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
843 EXPECT_EQ(325, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
847 EXPECT_TRUE(WaitUntilOnEnded());
850 TEST_P(PipelineIntegrationTest, MediaSource_ADTS_TimestampOffset) {
851 MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile, GetParam());
852 StartPipelineWithMediaSource(&source);
853 EXPECT_EQ(325, source.last_timestamp_offset().InMilliseconds());
855 scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.adts");
857 source.last_timestamp_offset() - base::TimeDelta::FromMilliseconds(10),
859 second_file->data_size());
860 source.EndOfStream();
862 EXPECT_EQ(640, source.last_timestamp_offset().InMilliseconds());
863 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
864 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
865 EXPECT_EQ(640, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
869 EXPECT_TRUE(WaitUntilOnEnded());
872 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed_MP3) {
873 ASSERT_TRUE(Start(GetTestDataFilePath("sfx.mp3"), PIPELINE_OK, kHashed));
877 ASSERT_TRUE(WaitUntilOnEnded());
879 // Verify codec delay and preroll are stripped.
880 EXPECT_EQ("3.05,2.87,3.00,3.32,3.58,4.08,", GetAudioHash());
883 TEST_P(PipelineIntegrationTest, MediaSource_MP3) {
884 MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile, GetParam());
885 StartHashedPipelineWithMediaSource(&source);
886 source.EndOfStream();
888 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
889 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
890 EXPECT_EQ(313, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
894 EXPECT_TRUE(WaitUntilOnEnded());
896 // Verify that codec delay was stripped, if it wasn't the hash would be:
897 // "5.16,1.25,7.78,4.29,8.98,2.76,"
898 EXPECT_EQ("5.81,2.71,8.97,4.32,7.83,1.12,", GetAudioHash());
901 TEST_P(PipelineIntegrationTest, MediaSource_MP3_TimestampOffset) {
902 MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile, GetParam());
903 StartPipelineWithMediaSource(&source);
904 EXPECT_EQ(313, source.last_timestamp_offset().InMilliseconds());
906 // There are 576 silent frames at the start of this mp3. The second append
907 // should trim them off.
908 const base::TimeDelta mp3_preroll_duration =
909 base::TimeDelta::FromSecondsD(576.0 / 44100);
910 const base::TimeDelta append_time =
911 source.last_timestamp_offset() - mp3_preroll_duration;
913 scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.mp3");
914 source.AppendAtTimeWithWindow(append_time,
915 append_time + mp3_preroll_duration,
918 second_file->data_size());
919 source.EndOfStream();
921 EXPECT_EQ(613, source.last_timestamp_offset().InMilliseconds());
922 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
923 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
924 EXPECT_EQ(613, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
928 EXPECT_TRUE(WaitUntilOnEnded());
931 TEST_P(PipelineIntegrationTest, MediaSource_MP3_Icecast) {
932 MockMediaSource source("icy_sfx.mp3", kMP3, kAppendWholeFile, GetParam());
933 StartPipelineWithMediaSource(&source);
934 source.EndOfStream();
938 EXPECT_TRUE(WaitUntilOnEnded());
941 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_MP4) {
942 MockMediaSource source("bear-640x360-av_frag.mp4", kMP4, kAppendWholeFile,
944 StartPipelineWithMediaSource(&source);
946 scoped_refptr<DecoderBuffer> second_file =
947 ReadTestDataFile("bear-1280x720-av_frag.mp4");
949 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
950 second_file->data(), second_file->data_size());
952 source.EndOfStream();
954 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
955 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
956 EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs,
957 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
961 EXPECT_TRUE(WaitUntilOnEnded());
966 TEST_P(PipelineIntegrationTest,
967 MediaSource_ConfigChange_Encrypted_MP4_CENC_VideoOnly) {
968 MockMediaSource source("bear-640x360-v_frag-cenc.mp4",
969 kMP4Video, kAppendWholeFile, GetParam());
970 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
971 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
973 scoped_refptr<DecoderBuffer> second_file =
974 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4");
976 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
977 second_file->data(), second_file->data_size());
979 source.EndOfStream();
981 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
982 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
983 EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs,
984 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
988 EXPECT_TRUE(WaitUntilOnEnded());
993 // Config changes from clear to encrypted are not currently supported.
994 // TODO(ddorwin): Figure out why this CHECKs in AppendAtTime().
995 TEST_P(PipelineIntegrationTest,
996 DISABLED_MediaSource_ConfigChange_ClearThenEncrypted_MP4_CENC) {
997 MockMediaSource source("bear-640x360-av_frag.mp4", kMP4Video,
998 kAppendWholeFile, GetParam());
999 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1000 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1002 scoped_refptr<DecoderBuffer> second_file =
1003 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4");
1005 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
1006 second_file->data(), second_file->data_size());
1008 source.EndOfStream();
1010 message_loop_.Run();
1011 EXPECT_EQ(PIPELINE_ERROR_DECODE, pipeline_status_);
1013 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
1014 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
1015 // The second video was not added, so its time has not been added.
1016 EXPECT_EQ(k640IsoFileDurationMs,
1017 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
1021 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
1025 // Config changes from encrypted to clear are not currently supported.
1026 TEST_P(PipelineIntegrationTest,
1027 MediaSource_ConfigChange_EncryptedThenClear_MP4_CENC) {
1028 MockMediaSource source("bear-640x360-v_frag-cenc.mp4",
1029 kMP4Video, kAppendWholeFile, GetParam());
1030 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1031 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1033 scoped_refptr<DecoderBuffer> second_file =
1034 ReadTestDataFile("bear-1280x720-av_frag.mp4");
1036 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
1037 second_file->data(), second_file->data_size());
1039 source.EndOfStream();
1041 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
1042 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
1043 // The second video was not added, so its time has not been added.
1044 EXPECT_EQ(k640IsoCencFileDurationMs,
1045 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
1049 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
1053 // Verify files which change configuration midstream fail gracefully.
1054 TEST_F(PipelineIntegrationTest, MidStreamConfigChangesFail) {
1056 GetTestDataFilePath("midstream_config_change.mp3"), PIPELINE_OK));
1058 ASSERT_EQ(WaitUntilEndedOrError(), PIPELINE_ERROR_DECODE);
1063 TEST_F(PipelineIntegrationTest, BasicPlayback_16x9AspectRatio) {
1064 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-16x9-aspect.webm"),
1067 ASSERT_TRUE(WaitUntilOnEnded());
1070 TEST_P(PipelineIntegrationTest, EncryptedPlayback_WebM) {
1071 MockMediaSource source("bear-320x240-av_enc-av.webm", kWebM, 219816,
1073 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1074 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1076 source.EndOfStream();
1077 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1081 ASSERT_TRUE(WaitUntilOnEnded());
1086 TEST_P(PipelineIntegrationTest, EncryptedPlayback_ClearStart_WebM) {
1087 MockMediaSource source("bear-320x240-av_enc-av_clear-1s.webm",
1088 kWebM, kAppendWholeFile, GetParam());
1089 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1090 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1092 source.EndOfStream();
1093 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1097 ASSERT_TRUE(WaitUntilOnEnded());
1102 TEST_P(PipelineIntegrationTest, EncryptedPlayback_NoEncryptedFrames_WebM) {
1103 MockMediaSource source("bear-320x240-av_enc-av_clear-all.webm",
1104 kWebM, kAppendWholeFile, GetParam());
1105 FakeEncryptedMedia encrypted_media(new NoResponseApp());
1106 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1108 source.EndOfStream();
1109 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1113 ASSERT_TRUE(WaitUntilOnEnded());
1118 #if defined(USE_PROPRIETARY_CODECS)
1119 TEST_P(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_VideoOnly) {
1120 MockMediaSource source("bear-1280x720-v_frag-cenc.mp4",
1121 kMP4Video, kAppendWholeFile, GetParam());
1122 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1123 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1125 source.EndOfStream();
1126 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1130 ASSERT_TRUE(WaitUntilOnEnded());
1135 TEST_P(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_AudioOnly) {
1136 MockMediaSource source("bear-1280x720-a_frag-cenc.mp4",
1137 kMP4Audio, kAppendWholeFile, GetParam());
1138 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1139 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1141 source.EndOfStream();
1142 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1146 ASSERT_TRUE(WaitUntilOnEnded());
1151 TEST_P(PipelineIntegrationTest,
1152 EncryptedPlayback_NoEncryptedFrames_MP4_CENC_VideoOnly) {
1153 MockMediaSource source("bear-1280x720-v_frag-cenc_clear-all.mp4",
1154 kMP4Video, kAppendWholeFile, GetParam());
1155 FakeEncryptedMedia encrypted_media(new NoResponseApp());
1156 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1158 source.EndOfStream();
1159 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1163 ASSERT_TRUE(WaitUntilOnEnded());
1168 TEST_P(PipelineIntegrationTest,
1169 EncryptedPlayback_NoEncryptedFrames_MP4_CENC_AudioOnly) {
1170 MockMediaSource source("bear-1280x720-a_frag-cenc_clear-all.mp4",
1171 kMP4Audio, kAppendWholeFile, GetParam());
1172 FakeEncryptedMedia encrypted_media(new NoResponseApp());
1173 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1175 source.EndOfStream();
1176 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1180 ASSERT_TRUE(WaitUntilOnEnded());
1185 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_AVC3) {
1186 MockMediaSource source("bear-1280x720-v_frag-avc3.mp4", kMP4VideoAVC3,
1187 kAppendWholeFile, GetParam());
1188 StartPipelineWithMediaSource(&source);
1189 source.EndOfStream();
1191 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
1192 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
1193 EXPECT_EQ(k1280IsoAVC3FileDurationMs,
1194 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
1198 ASSERT_TRUE(WaitUntilOnEnded());
1205 // TODO(acolwell): Fix flakiness http://crbug.com/117921
1206 TEST_F(PipelineIntegrationTest, DISABLED_SeekWhilePaused) {
1207 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK));
1209 base::TimeDelta duration(pipeline_->GetMediaDuration());
1210 base::TimeDelta start_seek_time(duration / 4);
1211 base::TimeDelta seek_time(duration * 3 / 4);
1214 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
1216 ASSERT_TRUE(Seek(seek_time));
1217 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
1219 ASSERT_TRUE(WaitUntilOnEnded());
1221 // Make sure seeking after reaching the end works as expected.
1223 ASSERT_TRUE(Seek(seek_time));
1224 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
1226 ASSERT_TRUE(WaitUntilOnEnded());
1229 // TODO(acolwell): Fix flakiness http://crbug.com/117921
1230 TEST_F(PipelineIntegrationTest, DISABLED_SeekWhilePlaying) {
1231 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK));
1233 base::TimeDelta duration(pipeline_->GetMediaDuration());
1234 base::TimeDelta start_seek_time(duration / 4);
1235 base::TimeDelta seek_time(duration * 3 / 4);
1238 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
1239 ASSERT_TRUE(Seek(seek_time));
1240 EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
1241 ASSERT_TRUE(WaitUntilOnEnded());
1243 // Make sure seeking after reaching the end works as expected.
1244 ASSERT_TRUE(Seek(seek_time));
1245 EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
1246 ASSERT_TRUE(WaitUntilOnEnded());
1249 // Verify audio decoder & renderer can handle aborted demuxer reads.
1250 TEST_P(PipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) {
1251 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", kAudioOnlyWebM,
1253 base::TimeDelta::FromMilliseconds(464),
1254 base::TimeDelta::FromMilliseconds(617),
1258 // Verify video decoder & renderer can handle aborted demuxer reads.
1259 TEST_P(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) {
1260 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", kVideoOnlyWebM,
1262 base::TimeDelta::FromMilliseconds(167),
1263 base::TimeDelta::FromMilliseconds(1668),
1267 // Verify that Opus audio in WebM containers can be played back.
1268 TEST_F(PipelineIntegrationTest, BasicPlayback_AudioOnly_Opus_WebM) {
1269 ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus-end-trimming.webm"),
1272 ASSERT_TRUE(WaitUntilOnEnded());
1275 // Verify that VP9 video in WebM containers can be played back.
1276 TEST_F(PipelineIntegrationTest, BasicPlayback_VideoOnly_VP9_WebM) {
1277 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9.webm"),
1280 ASSERT_TRUE(WaitUntilOnEnded());
1283 // Verify that VP9 video and Opus audio in the same WebM container can be played
1285 TEST_F(PipelineIntegrationTest, BasicPlayback_VP9_Opus_WebM) {
1286 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9-opus.webm"),
1289 ASSERT_TRUE(WaitUntilOnEnded());
1292 // Verify that VP8 video with alpha channel can be played back.
1293 TEST_F(PipelineIntegrationTest, BasicPlayback_VP8A_WebM) {
1294 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp8a.webm"),
1297 ASSERT_TRUE(WaitUntilOnEnded());
1298 EXPECT_EQ(last_video_frame_format_, VideoFrame::YV12A);
1301 // Verify that VP8A video with odd width/height can be played back.
1302 TEST_F(PipelineIntegrationTest, BasicPlayback_VP8A_Odd_WebM) {
1303 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp8a-odd-dimensions.webm"),
1306 ASSERT_TRUE(WaitUntilOnEnded());
1307 EXPECT_EQ(last_video_frame_format_, VideoFrame::YV12A);
1310 // Verify that VP8 video with inband text track can be played back.
1311 TEST_F(PipelineIntegrationTest,
1312 BasicPlayback_VP8_WebVTT_WebM) {
1313 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp8-webvtt.webm"),
1316 ASSERT_TRUE(WaitUntilOnEnded());
1319 // For MediaSource tests, generate two sets of tests: one using FrameProcessor,
1320 // and one using LegacyFrameProcessor.
1321 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, PipelineIntegrationTest,
1323 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, PipelineIntegrationTest,
1326 } // namespace media