Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / media / filters / pipeline_integration_test.cc
blobb5223a3a2bf92be3394dd83dbb4963ecff029b28
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"
7 #include "base/bind.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"
20 using testing::_;
21 using testing::AnyNumber;
22 using testing::AtMost;
23 using testing::SaveArg;
24 using testing::Values;
26 namespace media {
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 {
111 public:
112 // Defines the behavior of the "app" that responds to EME events.
113 class AppBase {
114 public:
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))),
151 app_(app) {}
153 AesDecryptor* decryptor() {
154 return &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_);
187 private:
188 AesDecryptor decryptor_;
189 scoped_ptr<AppBase> app_;
192 // Provides |kSecretKey| in response to needkey.
193 class KeyProvidingApp : public FakeEncryptedMedia::AppBase {
194 public:
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) {
224 EXPECT_TRUE(
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
232 // correct key ID.
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) {
236 key_id = kKeyId;
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()),
245 jwk.size());
248 uint32 current_session_id_;
251 // Ignores needkey and does not perform a license request
252 class NoResponseApp : public FakeEncryptedMedia::AppBase {
253 public:
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
285 // Media Source API.
286 class MockMediaSource {
287 public:
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),
295 mimetype_(mimetype),
296 chunk_demuxer_(new ChunkDemuxer(
297 base::Bind(&MockMediaSource::DemuxerOpened, base::Unretained(this)),
298 base::Bind(&MockMediaSource::DemuxerNeedKey,
299 base::Unretained(this)),
300 LogCB(),
301 true)),
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 chunk_demuxer_->Abort(kSourceId);
327 DCHECK_GE(new_position, 0);
328 DCHECK_LT(new_position, file_data_->data_size());
329 current_position_ = new_position;
331 AppendData(seek_append_size);
334 void AppendData(int size) {
335 DCHECK(chunk_demuxer_);
336 DCHECK_LT(current_position_, file_data_->data_size());
337 DCHECK_LE(current_position_ + size, file_data_->data_size());
339 // TODO(wolenetz): Test timestamp offset updating once "sequence" append
340 // mode processing is implemented. See http://crbug.com/249422.
341 base::TimeDelta timestamp_offset;
342 chunk_demuxer_->AppendData(
343 kSourceId, file_data_->data() + current_position_, size,
344 base::TimeDelta(), kInfiniteDuration(), &timestamp_offset);
345 current_position_ += size;
346 last_timestamp_offset_ = timestamp_offset;
349 void AppendAtTime(base::TimeDelta timestamp_offset,
350 const uint8* pData,
351 int size) {
352 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
353 chunk_demuxer_->AppendData(kSourceId, pData, size,
354 base::TimeDelta(), kInfiniteDuration(),
355 &timestamp_offset);
356 last_timestamp_offset_ = timestamp_offset;
359 void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset,
360 base::TimeDelta append_window_start,
361 base::TimeDelta append_window_end,
362 const uint8* pData,
363 int size) {
364 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
365 chunk_demuxer_->AppendData(kSourceId,
366 pData,
367 size,
368 append_window_start,
369 append_window_end,
370 &timestamp_offset);
371 last_timestamp_offset_ = timestamp_offset;
374 void EndOfStream() {
375 chunk_demuxer_->MarkEndOfStream(PIPELINE_OK);
378 void Abort() {
379 if (!chunk_demuxer_)
380 return;
381 chunk_demuxer_->Shutdown();
382 chunk_demuxer_ = NULL;
385 void DemuxerOpened() {
386 base::MessageLoop::current()->PostTask(
387 FROM_HERE, base::Bind(&MockMediaSource::DemuxerOpenedTask,
388 base::Unretained(this)));
391 void DemuxerOpenedTask() {
392 // This code assumes that |mimetype_| is one of the following forms.
393 // 1. audio/mpeg
394 // 2. video/webm;codec="vorbis,vp8".
395 size_t semicolon = mimetype_.find(";");
396 std::string type = mimetype_;
397 std::vector<std::string> codecs;
398 if (semicolon != std::string::npos) {
399 type = mimetype_.substr(0, semicolon);
400 size_t codecs_param_start = mimetype_.find("codecs=\"", semicolon);
402 CHECK_NE(codecs_param_start, std::string::npos);
404 codecs_param_start += 8; // Skip over the codecs=".
406 size_t codecs_param_end = mimetype_.find("\"", codecs_param_start);
408 CHECK_NE(codecs_param_end, std::string::npos);
410 std::string codecs_param =
411 mimetype_.substr(codecs_param_start,
412 codecs_param_end - codecs_param_start);
413 Tokenize(codecs_param, ",", &codecs);
416 CHECK_EQ(chunk_demuxer_->AddId(kSourceId, type, codecs,
417 use_legacy_frame_processor_),
418 ChunkDemuxer::kOk);
420 AppendData(initial_append_size_);
423 void DemuxerNeedKey(const std::string& type,
424 const std::vector<uint8>& init_data) {
425 DCHECK(!init_data.empty());
426 CHECK(!need_key_cb_.is_null());
427 need_key_cb_.Run(type, init_data);
430 base::TimeDelta last_timestamp_offset() const {
431 return last_timestamp_offset_;
434 private:
435 base::FilePath file_path_;
436 scoped_refptr<DecoderBuffer> file_data_;
437 int current_position_;
438 int initial_append_size_;
439 std::string mimetype_;
440 ChunkDemuxer* chunk_demuxer_;
441 scoped_ptr<Demuxer> owned_chunk_demuxer_;
442 Demuxer::NeedKeyCB need_key_cb_;
443 base::TimeDelta last_timestamp_offset_;
444 bool use_legacy_frame_processor_;
447 // Test parameter determines which coded frame processor is used to process
448 // appended data, and is only applicable in tests where the pipeline is using a
449 // (Mock)MediaSource (which are TEST_P, not TEST_F). If true,
450 // LegacyFrameProcessor is used. Otherwise, (not yet supported), a more
451 // compliant frame processor is used.
452 // TODO(wolenetz): Enable usage of new frame processor based on this flag.
453 // See http://crbug.com/249422.
454 class PipelineIntegrationTest
455 : public testing::TestWithParam<bool>,
456 public PipelineIntegrationTestBase {
457 public:
458 void StartPipelineWithMediaSource(MockMediaSource* source) {
459 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1))
460 .WillRepeatedly(SaveArg<0>(&metadata_));
461 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
462 pipeline_->Start(
463 CreateFilterCollection(source->GetDemuxer(), NULL),
464 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
465 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
466 QuitOnStatusCB(PIPELINE_OK),
467 base::Bind(&PipelineIntegrationTest::OnMetadata,
468 base::Unretained(this)),
469 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted,
470 base::Unretained(this)),
471 base::Closure());
473 message_loop_.Run();
476 void StartHashedPipelineWithMediaSource(MockMediaSource* source) {
477 hashing_enabled_ = true;
478 StartPipelineWithMediaSource(source);
481 void StartPipelineWithEncryptedMedia(
482 MockMediaSource* source,
483 FakeEncryptedMedia* encrypted_media) {
484 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1))
485 .WillRepeatedly(SaveArg<0>(&metadata_));
486 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
487 pipeline_->Start(
488 CreateFilterCollection(source->GetDemuxer(),
489 encrypted_media->decryptor()),
490 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
491 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
492 QuitOnStatusCB(PIPELINE_OK),
493 base::Bind(&PipelineIntegrationTest::OnMetadata,
494 base::Unretained(this)),
495 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted,
496 base::Unretained(this)),
497 base::Closure());
499 source->set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey,
500 base::Unretained(encrypted_media)));
502 message_loop_.Run();
505 // Verifies that seeking works properly for ChunkDemuxer when the
506 // seek happens while there is a pending read on the ChunkDemuxer
507 // and no data is available.
508 bool TestSeekDuringRead(const std::string& filename,
509 const std::string& mimetype,
510 int initial_append_size,
511 base::TimeDelta start_seek_time,
512 base::TimeDelta seek_time,
513 int seek_file_position,
514 int seek_append_size) {
515 MockMediaSource source(filename, mimetype, initial_append_size,
516 GetParam());
517 StartPipelineWithMediaSource(&source);
519 if (pipeline_status_ != PIPELINE_OK)
520 return false;
522 Play();
523 if (!WaitUntilCurrentTimeIsAfter(start_seek_time))
524 return false;
526 source.Seek(seek_time, seek_file_position, seek_append_size);
527 if (!Seek(seek_time))
528 return false;
530 source.EndOfStream();
532 source.Abort();
533 Stop();
534 return true;
538 TEST_F(PipelineIntegrationTest, BasicPlayback) {
539 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK));
541 Play();
543 ASSERT_TRUE(WaitUntilOnEnded());
546 TEST_F(PipelineIntegrationTest, BasicPlaybackOpusOgg) {
547 ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus.ogg"), PIPELINE_OK));
549 Play();
551 ASSERT_TRUE(WaitUntilOnEnded());
554 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed) {
555 ASSERT_TRUE(Start(
556 GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK, kHashed));
558 Play();
560 ASSERT_TRUE(WaitUntilOnEnded());
562 EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash());
563 EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash());
564 EXPECT_TRUE(demuxer_->GetTimelineOffset().is_null());
567 TEST_F(PipelineIntegrationTest, BasicPlaybackLive) {
568 ASSERT_TRUE(Start(
569 GetTestDataFilePath("bear-320x240-live.webm"), PIPELINE_OK, kHashed));
571 Play();
573 ASSERT_TRUE(WaitUntilOnEnded());
575 EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash());
576 EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash());
578 // TODO: Fix FFmpeg code to return higher resolution time values so
579 // we don't have to truncate our expectations here.
580 EXPECT_EQ(TruncateToFFmpegTimeResolution(kLiveTimelineOffset()),
581 demuxer_->GetTimelineOffset());
584 TEST_F(PipelineIntegrationTest, F32PlaybackHashed) {
585 ASSERT_TRUE(
586 Start(GetTestDataFilePath("sfx_f32le.wav"), PIPELINE_OK, kHashed));
587 Play();
588 ASSERT_TRUE(WaitUntilOnEnded());
589 EXPECT_EQ(std::string(kNullVideoHash), GetVideoHash());
590 EXPECT_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
593 TEST_F(PipelineIntegrationTest, BasicPlaybackEncrypted) {
594 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
595 set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey,
596 base::Unretained(&encrypted_media)));
598 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-av_enc-av.webm"),
599 encrypted_media.decryptor()));
601 Play();
603 ASSERT_TRUE(WaitUntilOnEnded());
604 Stop();
607 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource) {
608 MockMediaSource source("bear-320x240.webm", kWebM, 219229, GetParam());
609 StartPipelineWithMediaSource(&source);
610 source.EndOfStream();
612 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
613 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
614 EXPECT_EQ(k320WebMFileDurationMs,
615 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
617 Play();
619 ASSERT_TRUE(WaitUntilOnEnded());
621 EXPECT_TRUE(demuxer_->GetTimelineOffset().is_null());
622 source.Abort();
623 Stop();
626 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_Live) {
627 MockMediaSource source("bear-320x240-live.webm", kWebM, 219221, GetParam());
628 StartPipelineWithMediaSource(&source);
629 source.EndOfStream();
631 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
632 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
633 EXPECT_EQ(k320WebMFileDurationMs,
634 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
636 Play();
638 ASSERT_TRUE(WaitUntilOnEnded());
640 EXPECT_EQ(kLiveTimelineOffset(),
641 demuxer_->GetTimelineOffset());
642 source.Abort();
643 Stop();
646 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP9_WebM) {
647 MockMediaSource source("bear-vp9.webm", kWebMVP9, 67504, GetParam());
648 StartPipelineWithMediaSource(&source);
649 source.EndOfStream();
651 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
652 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
653 EXPECT_EQ(kVP9WebMFileDurationMs,
654 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
656 Play();
658 ASSERT_TRUE(WaitUntilOnEnded());
659 source.Abort();
660 Stop();
663 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP8A_WebM) {
664 MockMediaSource source("bear-vp8a.webm", kVideoOnlyWebM, kAppendWholeFile,
665 GetParam());
666 StartPipelineWithMediaSource(&source);
667 source.EndOfStream();
669 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
670 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
671 EXPECT_EQ(kVP8AWebMFileDurationMs,
672 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
674 Play();
676 ASSERT_TRUE(WaitUntilOnEnded());
677 source.Abort();
678 Stop();
681 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_Opus_WebM) {
682 MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
683 kAppendWholeFile, GetParam());
684 StartPipelineWithMediaSource(&source);
685 source.EndOfStream();
687 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
688 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
689 EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
690 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
691 Play();
693 ASSERT_TRUE(WaitUntilOnEnded());
694 source.Abort();
695 Stop();
698 // Flaky. http://crbug.com/304776
699 TEST_P(PipelineIntegrationTest, DISABLED_MediaSource_Opus_Seeking_WebM) {
700 MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
701 kAppendWholeFile, GetParam());
702 StartHashedPipelineWithMediaSource(&source);
704 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
705 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
706 EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
707 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
709 base::TimeDelta start_seek_time = base::TimeDelta::FromMilliseconds(1000);
710 base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2000);
712 Play();
713 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
714 source.Seek(seek_time, 0x1D5, 34017);
715 source.EndOfStream();
716 ASSERT_TRUE(Seek(seek_time));
718 ASSERT_TRUE(WaitUntilOnEnded());
720 EXPECT_EQ("0.76,0.20,-0.82,-0.58,-1.29,-0.29,", GetAudioHash());
722 source.Abort();
723 Stop();
726 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_WebM) {
727 MockMediaSource source("bear-320x240-16x9-aspect.webm", kWebM,
728 kAppendWholeFile, GetParam());
729 StartPipelineWithMediaSource(&source);
731 scoped_refptr<DecoderBuffer> second_file =
732 ReadTestDataFile("bear-640x360.webm");
734 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
735 second_file->data(), second_file->data_size());
737 source.EndOfStream();
739 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
740 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
741 EXPECT_EQ(kAppendTimeMs + k640WebMFileDurationMs,
742 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
744 Play();
746 EXPECT_TRUE(WaitUntilOnEnded());
747 source.Abort();
748 Stop();
751 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_Encrypted_WebM) {
752 MockMediaSource source("bear-320x240-16x9-aspect-av_enc-av.webm", kWebM,
753 kAppendWholeFile, GetParam());
754 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
755 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
757 scoped_refptr<DecoderBuffer> second_file =
758 ReadTestDataFile("bear-640x360-av_enc-av.webm");
760 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
761 second_file->data(), second_file->data_size());
763 source.EndOfStream();
765 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
766 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
767 EXPECT_EQ(kAppendTimeMs + k640WebMFileDurationMs,
768 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
770 Play();
772 EXPECT_TRUE(WaitUntilOnEnded());
773 source.Abort();
774 Stop();
777 // Config changes from encrypted to clear are not currently supported.
778 TEST_P(PipelineIntegrationTest,
779 MediaSource_ConfigChange_ClearThenEncrypted_WebM) {
780 MockMediaSource source("bear-320x240-16x9-aspect.webm", kWebM,
781 kAppendWholeFile, GetParam());
782 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
783 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
785 scoped_refptr<DecoderBuffer> second_file =
786 ReadTestDataFile("bear-640x360-av_enc-av.webm");
788 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
789 second_file->data(), second_file->data_size());
791 source.EndOfStream();
793 message_loop_.Run();
794 EXPECT_EQ(PIPELINE_ERROR_DECODE, pipeline_status_);
796 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
797 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
798 // The second video was not added, so its time has not been added.
799 EXPECT_EQ(k320WebMFileDurationMs,
800 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
802 Play();
804 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
805 source.Abort();
808 // Config changes from clear to encrypted are not currently supported.
809 TEST_P(PipelineIntegrationTest,
810 MediaSource_ConfigChange_EncryptedThenClear_WebM) {
811 MockMediaSource source("bear-320x240-16x9-aspect-av_enc-av.webm", kWebM,
812 kAppendWholeFile, GetParam());
813 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
814 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
816 scoped_refptr<DecoderBuffer> second_file =
817 ReadTestDataFile("bear-640x360.webm");
819 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
820 second_file->data(), second_file->data_size());
822 source.EndOfStream();
824 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
825 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
826 // The second video was not added, so its time has not been added.
827 EXPECT_EQ(k320WebMFileDurationMs,
828 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
830 Play();
832 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
833 source.Abort();
836 #if defined(USE_PROPRIETARY_CODECS)
837 TEST_P(PipelineIntegrationTest, MediaSource_ADTS) {
838 MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile, GetParam());
839 StartPipelineWithMediaSource(&source);
840 source.EndOfStream();
842 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
843 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
844 EXPECT_EQ(325, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
846 Play();
848 EXPECT_TRUE(WaitUntilOnEnded());
851 TEST_P(PipelineIntegrationTest, MediaSource_ADTS_TimestampOffset) {
852 MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile, GetParam());
853 StartPipelineWithMediaSource(&source);
854 EXPECT_EQ(325, source.last_timestamp_offset().InMilliseconds());
856 scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.adts");
857 source.AppendAtTime(
858 source.last_timestamp_offset() - base::TimeDelta::FromMilliseconds(10),
859 second_file->data(),
860 second_file->data_size());
861 source.EndOfStream();
863 EXPECT_EQ(640, source.last_timestamp_offset().InMilliseconds());
864 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
865 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
866 EXPECT_EQ(640, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
868 Play();
870 EXPECT_TRUE(WaitUntilOnEnded());
873 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed_MP3) {
874 ASSERT_TRUE(Start(GetTestDataFilePath("sfx.mp3"), PIPELINE_OK, kHashed));
876 Play();
878 ASSERT_TRUE(WaitUntilOnEnded());
880 // Verify codec delay and preroll are stripped.
881 EXPECT_EQ("3.05,2.87,3.00,3.32,3.58,4.08,", GetAudioHash());
884 TEST_P(PipelineIntegrationTest, MediaSource_MP3) {
885 MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile, GetParam());
886 StartHashedPipelineWithMediaSource(&source);
887 source.EndOfStream();
889 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
890 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
891 EXPECT_EQ(313, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
893 Play();
895 EXPECT_TRUE(WaitUntilOnEnded());
897 // Verify that codec delay was stripped, if it wasn't the hash would be:
898 // "5.16,1.25,7.78,4.29,8.98,2.76,"
899 EXPECT_EQ("5.81,2.71,8.97,4.32,7.83,1.12,", GetAudioHash());
902 TEST_P(PipelineIntegrationTest, MediaSource_MP3_TimestampOffset) {
903 MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile, GetParam());
904 StartPipelineWithMediaSource(&source);
905 EXPECT_EQ(313, source.last_timestamp_offset().InMilliseconds());
907 // There are 576 silent frames at the start of this mp3. The second append
908 // should trim them off.
909 const base::TimeDelta mp3_preroll_duration =
910 base::TimeDelta::FromSecondsD(576.0 / 44100);
911 const base::TimeDelta append_time =
912 source.last_timestamp_offset() - mp3_preroll_duration;
914 scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.mp3");
915 source.AppendAtTimeWithWindow(append_time,
916 append_time + mp3_preroll_duration,
917 kInfiniteDuration(),
918 second_file->data(),
919 second_file->data_size());
920 source.EndOfStream();
922 EXPECT_EQ(613, source.last_timestamp_offset().InMilliseconds());
923 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
924 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
925 EXPECT_EQ(613, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
927 Play();
929 EXPECT_TRUE(WaitUntilOnEnded());
932 TEST_P(PipelineIntegrationTest, MediaSource_MP3_Icecast) {
933 MockMediaSource source("icy_sfx.mp3", kMP3, kAppendWholeFile, GetParam());
934 StartPipelineWithMediaSource(&source);
935 source.EndOfStream();
937 Play();
939 EXPECT_TRUE(WaitUntilOnEnded());
942 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_MP4) {
943 MockMediaSource source("bear-640x360-av_frag.mp4", kMP4, kAppendWholeFile,
944 GetParam());
945 StartPipelineWithMediaSource(&source);
947 scoped_refptr<DecoderBuffer> second_file =
948 ReadTestDataFile("bear-1280x720-av_frag.mp4");
950 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
951 second_file->data(), second_file->data_size());
953 source.EndOfStream();
955 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
956 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
957 EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs,
958 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
960 Play();
962 EXPECT_TRUE(WaitUntilOnEnded());
963 source.Abort();
964 Stop();
967 TEST_P(PipelineIntegrationTest,
968 MediaSource_ConfigChange_Encrypted_MP4_CENC_VideoOnly) {
969 MockMediaSource source("bear-640x360-v_frag-cenc.mp4",
970 kMP4Video, kAppendWholeFile, GetParam());
971 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
972 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
974 scoped_refptr<DecoderBuffer> second_file =
975 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4");
977 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
978 second_file->data(), second_file->data_size());
980 source.EndOfStream();
982 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
983 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
984 EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs,
985 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
987 Play();
989 EXPECT_TRUE(WaitUntilOnEnded());
990 source.Abort();
991 Stop();
994 // Config changes from clear to encrypted are not currently supported.
995 // TODO(ddorwin): Figure out why this CHECKs in AppendAtTime().
996 TEST_P(PipelineIntegrationTest,
997 DISABLED_MediaSource_ConfigChange_ClearThenEncrypted_MP4_CENC) {
998 MockMediaSource source("bear-640x360-av_frag.mp4", kMP4Video,
999 kAppendWholeFile, GetParam());
1000 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1001 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1003 scoped_refptr<DecoderBuffer> second_file =
1004 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4");
1006 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
1007 second_file->data(), second_file->data_size());
1009 source.EndOfStream();
1011 message_loop_.Run();
1012 EXPECT_EQ(PIPELINE_ERROR_DECODE, pipeline_status_);
1014 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
1015 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
1016 // The second video was not added, so its time has not been added.
1017 EXPECT_EQ(k640IsoFileDurationMs,
1018 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
1020 Play();
1022 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
1023 source.Abort();
1026 // Config changes from encrypted to clear are not currently supported.
1027 TEST_P(PipelineIntegrationTest,
1028 MediaSource_ConfigChange_EncryptedThenClear_MP4_CENC) {
1029 MockMediaSource source("bear-640x360-v_frag-cenc.mp4",
1030 kMP4Video, kAppendWholeFile, GetParam());
1031 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1032 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1034 scoped_refptr<DecoderBuffer> second_file =
1035 ReadTestDataFile("bear-1280x720-av_frag.mp4");
1037 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
1038 second_file->data(), second_file->data_size());
1040 source.EndOfStream();
1042 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
1043 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
1044 // The second video was not added, so its time has not been added.
1045 EXPECT_EQ(k640IsoCencFileDurationMs,
1046 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
1048 Play();
1050 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
1051 source.Abort();
1054 // Verify files which change configuration midstream fail gracefully.
1055 TEST_F(PipelineIntegrationTest, MidStreamConfigChangesFail) {
1056 ASSERT_TRUE(Start(
1057 GetTestDataFilePath("midstream_config_change.mp3"), PIPELINE_OK));
1058 Play();
1059 ASSERT_EQ(WaitUntilEndedOrError(), PIPELINE_ERROR_DECODE);
1062 #endif
1064 TEST_F(PipelineIntegrationTest, BasicPlayback_16x9AspectRatio) {
1065 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-16x9-aspect.webm"),
1066 PIPELINE_OK));
1067 Play();
1068 ASSERT_TRUE(WaitUntilOnEnded());
1071 TEST_P(PipelineIntegrationTest, EncryptedPlayback_WebM) {
1072 MockMediaSource source("bear-320x240-av_enc-av.webm", kWebM, 219816,
1073 GetParam());
1074 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1075 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1077 source.EndOfStream();
1078 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1080 Play();
1082 ASSERT_TRUE(WaitUntilOnEnded());
1083 source.Abort();
1084 Stop();
1087 TEST_P(PipelineIntegrationTest, EncryptedPlayback_ClearStart_WebM) {
1088 MockMediaSource source("bear-320x240-av_enc-av_clear-1s.webm",
1089 kWebM, kAppendWholeFile, GetParam());
1090 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1091 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1093 source.EndOfStream();
1094 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1096 Play();
1098 ASSERT_TRUE(WaitUntilOnEnded());
1099 source.Abort();
1100 Stop();
1103 TEST_P(PipelineIntegrationTest, EncryptedPlayback_NoEncryptedFrames_WebM) {
1104 MockMediaSource source("bear-320x240-av_enc-av_clear-all.webm",
1105 kWebM, kAppendWholeFile, GetParam());
1106 FakeEncryptedMedia encrypted_media(new NoResponseApp());
1107 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1109 source.EndOfStream();
1110 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1112 Play();
1114 ASSERT_TRUE(WaitUntilOnEnded());
1115 source.Abort();
1116 Stop();
1119 #if defined(USE_PROPRIETARY_CODECS)
1120 TEST_P(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_VideoOnly) {
1121 MockMediaSource source("bear-1280x720-v_frag-cenc.mp4",
1122 kMP4Video, kAppendWholeFile, GetParam());
1123 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1124 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1126 source.EndOfStream();
1127 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1129 Play();
1131 ASSERT_TRUE(WaitUntilOnEnded());
1132 source.Abort();
1133 Stop();
1136 TEST_P(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_AudioOnly) {
1137 MockMediaSource source("bear-1280x720-a_frag-cenc.mp4",
1138 kMP4Audio, kAppendWholeFile, GetParam());
1139 FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1140 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1142 source.EndOfStream();
1143 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1145 Play();
1147 ASSERT_TRUE(WaitUntilOnEnded());
1148 source.Abort();
1149 Stop();
1152 TEST_P(PipelineIntegrationTest,
1153 EncryptedPlayback_NoEncryptedFrames_MP4_CENC_VideoOnly) {
1154 MockMediaSource source("bear-1280x720-v_frag-cenc_clear-all.mp4",
1155 kMP4Video, kAppendWholeFile, GetParam());
1156 FakeEncryptedMedia encrypted_media(new NoResponseApp());
1157 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1159 source.EndOfStream();
1160 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1162 Play();
1164 ASSERT_TRUE(WaitUntilOnEnded());
1165 source.Abort();
1166 Stop();
1169 TEST_P(PipelineIntegrationTest,
1170 EncryptedPlayback_NoEncryptedFrames_MP4_CENC_AudioOnly) {
1171 MockMediaSource source("bear-1280x720-a_frag-cenc_clear-all.mp4",
1172 kMP4Audio, kAppendWholeFile, GetParam());
1173 FakeEncryptedMedia encrypted_media(new NoResponseApp());
1174 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1176 source.EndOfStream();
1177 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1179 Play();
1181 ASSERT_TRUE(WaitUntilOnEnded());
1182 source.Abort();
1183 Stop();
1186 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_AVC3) {
1187 MockMediaSource source("bear-1280x720-v_frag-avc3.mp4", kMP4VideoAVC3,
1188 kAppendWholeFile, GetParam());
1189 StartPipelineWithMediaSource(&source);
1190 source.EndOfStream();
1192 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
1193 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
1194 EXPECT_EQ(k1280IsoAVC3FileDurationMs,
1195 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
1197 Play();
1199 ASSERT_TRUE(WaitUntilOnEnded());
1200 source.Abort();
1201 Stop();
1204 #endif
1206 // TODO(acolwell): Fix flakiness http://crbug.com/117921
1207 TEST_F(PipelineIntegrationTest, DISABLED_SeekWhilePaused) {
1208 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK));
1210 base::TimeDelta duration(pipeline_->GetMediaDuration());
1211 base::TimeDelta start_seek_time(duration / 4);
1212 base::TimeDelta seek_time(duration * 3 / 4);
1214 Play();
1215 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
1216 Pause();
1217 ASSERT_TRUE(Seek(seek_time));
1218 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
1219 Play();
1220 ASSERT_TRUE(WaitUntilOnEnded());
1222 // Make sure seeking after reaching the end works as expected.
1223 Pause();
1224 ASSERT_TRUE(Seek(seek_time));
1225 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
1226 Play();
1227 ASSERT_TRUE(WaitUntilOnEnded());
1230 // TODO(acolwell): Fix flakiness http://crbug.com/117921
1231 TEST_F(PipelineIntegrationTest, DISABLED_SeekWhilePlaying) {
1232 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK));
1234 base::TimeDelta duration(pipeline_->GetMediaDuration());
1235 base::TimeDelta start_seek_time(duration / 4);
1236 base::TimeDelta seek_time(duration * 3 / 4);
1238 Play();
1239 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
1240 ASSERT_TRUE(Seek(seek_time));
1241 EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
1242 ASSERT_TRUE(WaitUntilOnEnded());
1244 // Make sure seeking after reaching the end works as expected.
1245 ASSERT_TRUE(Seek(seek_time));
1246 EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
1247 ASSERT_TRUE(WaitUntilOnEnded());
1250 // Verify audio decoder & renderer can handle aborted demuxer reads.
1251 TEST_P(PipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) {
1252 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", kAudioOnlyWebM,
1253 8192,
1254 base::TimeDelta::FromMilliseconds(464),
1255 base::TimeDelta::FromMilliseconds(617),
1256 0x10CA, 19730));
1259 // Verify video decoder & renderer can handle aborted demuxer reads.
1260 TEST_P(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) {
1261 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", kVideoOnlyWebM,
1262 32768,
1263 base::TimeDelta::FromMilliseconds(167),
1264 base::TimeDelta::FromMilliseconds(1668),
1265 0x1C896, 65536));
1268 // Verify that Opus audio in WebM containers can be played back.
1269 TEST_F(PipelineIntegrationTest, BasicPlayback_AudioOnly_Opus_WebM) {
1270 ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus-end-trimming.webm"),
1271 PIPELINE_OK));
1272 Play();
1273 ASSERT_TRUE(WaitUntilOnEnded());
1276 // Verify that VP9 video in WebM containers can be played back.
1277 TEST_F(PipelineIntegrationTest, BasicPlayback_VideoOnly_VP9_WebM) {
1278 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9.webm"),
1279 PIPELINE_OK));
1280 Play();
1281 ASSERT_TRUE(WaitUntilOnEnded());
1284 // Verify that VP9 video and Opus audio in the same WebM container can be played
1285 // back.
1286 TEST_F(PipelineIntegrationTest, BasicPlayback_VP9_Opus_WebM) {
1287 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9-opus.webm"),
1288 PIPELINE_OK));
1289 Play();
1290 ASSERT_TRUE(WaitUntilOnEnded());
1293 // Verify that VP8 video with alpha channel can be played back.
1294 TEST_F(PipelineIntegrationTest, BasicPlayback_VP8A_WebM) {
1295 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp8a.webm"),
1296 PIPELINE_OK));
1297 Play();
1298 ASSERT_TRUE(WaitUntilOnEnded());
1299 EXPECT_EQ(last_video_frame_format_, VideoFrame::YV12A);
1302 // Verify that VP8A video with odd width/height can be played back.
1303 TEST_F(PipelineIntegrationTest, BasicPlayback_VP8A_Odd_WebM) {
1304 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp8a-odd-dimensions.webm"),
1305 PIPELINE_OK));
1306 Play();
1307 ASSERT_TRUE(WaitUntilOnEnded());
1308 EXPECT_EQ(last_video_frame_format_, VideoFrame::YV12A);
1311 // Verify that VP8 video with inband text track can be played back.
1312 TEST_F(PipelineIntegrationTest,
1313 BasicPlayback_VP8_WebVTT_WebM) {
1314 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp8-webvtt.webm"),
1315 PIPELINE_OK));
1316 Play();
1317 ASSERT_TRUE(WaitUntilOnEnded());
1320 // TODO(wolenetz): Enable MSE testing of new frame processor based on this flag,
1321 // once the new processor has landed. See http://crbug.com/249422.
1322 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, PipelineIntegrationTest,
1323 Values(true));
1325 } // namespace media