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 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(), ×tamp_offset
);
345 current_position_
+= size
;
346 last_timestamp_offset_
= timestamp_offset
;
349 void AppendAtTime(base::TimeDelta timestamp_offset
,
352 CHECK(!chunk_demuxer_
->IsParsingMediaSegment(kSourceId
));
353 chunk_demuxer_
->AppendData(kSourceId
, pData
, size
,
354 base::TimeDelta(), kInfiniteDuration(),
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
,
364 CHECK(!chunk_demuxer_
->IsParsingMediaSegment(kSourceId
));
365 chunk_demuxer_
->AppendData(kSourceId
,
371 last_timestamp_offset_
= timestamp_offset
;
375 chunk_demuxer_
->MarkEndOfStream(PIPELINE_OK
);
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.
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_
),
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_
;
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
{
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));
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)),
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));
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)),
499 source
->set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey
,
500 base::Unretained(encrypted_media
)));
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
,
517 StartPipelineWithMediaSource(&source
);
519 if (pipeline_status_
!= PIPELINE_OK
)
523 if (!WaitUntilCurrentTimeIsAfter(start_seek_time
))
526 source
.Seek(seek_time
, seek_file_position
, seek_append_size
);
527 if (!Seek(seek_time
))
530 source
.EndOfStream();
538 TEST_F(PipelineIntegrationTest
, BasicPlayback
) {
539 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK
));
543 ASSERT_TRUE(WaitUntilOnEnded());
546 TEST_F(PipelineIntegrationTest
, BasicPlaybackOpusOgg
) {
547 ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus.ogg"), PIPELINE_OK
));
551 ASSERT_TRUE(WaitUntilOnEnded());
554 TEST_F(PipelineIntegrationTest
, BasicPlaybackHashed
) {
556 GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK
, kHashed
));
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
) {
569 GetTestDataFilePath("bear-320x240-live.webm"), PIPELINE_OK
, kHashed
));
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
) {
586 Start(GetTestDataFilePath("sfx_f32le.wav"), PIPELINE_OK
, kHashed
));
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()));
603 ASSERT_TRUE(WaitUntilOnEnded());
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());
619 ASSERT_TRUE(WaitUntilOnEnded());
621 EXPECT_TRUE(demuxer_
->GetTimelineOffset().is_null());
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());
638 ASSERT_TRUE(WaitUntilOnEnded());
640 EXPECT_EQ(kLiveTimelineOffset(),
641 demuxer_
->GetTimelineOffset());
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());
658 ASSERT_TRUE(WaitUntilOnEnded());
663 TEST_P(PipelineIntegrationTest
, BasicPlayback_MediaSource_VP8A_WebM
) {
664 MockMediaSource
source("bear-vp8a.webm", kVideoOnlyWebM
, kAppendWholeFile
,
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());
676 ASSERT_TRUE(WaitUntilOnEnded());
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());
693 ASSERT_TRUE(WaitUntilOnEnded());
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);
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());
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());
746 EXPECT_TRUE(WaitUntilOnEnded());
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());
772 EXPECT_TRUE(WaitUntilOnEnded());
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();
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());
804 EXPECT_EQ(PIPELINE_ERROR_DECODE
, WaitUntilEndedOrError());
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());
832 EXPECT_EQ(PIPELINE_ERROR_DECODE
, WaitUntilEndedOrError());
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());
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");
858 source
.last_timestamp_offset() - base::TimeDelta::FromMilliseconds(10),
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());
870 EXPECT_TRUE(WaitUntilOnEnded());
873 TEST_F(PipelineIntegrationTest
, BasicPlaybackHashed_MP3
) {
874 ASSERT_TRUE(Start(GetTestDataFilePath("sfx.mp3"), PIPELINE_OK
, kHashed
));
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());
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
,
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());
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();
939 EXPECT_TRUE(WaitUntilOnEnded());
942 TEST_P(PipelineIntegrationTest
, MediaSource_ConfigChange_MP4
) {
943 MockMediaSource
source("bear-640x360-av_frag.mp4", kMP4
, kAppendWholeFile
,
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());
962 EXPECT_TRUE(WaitUntilOnEnded());
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());
989 EXPECT_TRUE(WaitUntilOnEnded());
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());
1022 EXPECT_EQ(PIPELINE_ERROR_DECODE
, WaitUntilEndedOrError());
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());
1050 EXPECT_EQ(PIPELINE_ERROR_DECODE
, WaitUntilEndedOrError());
1054 // Verify files which change configuration midstream fail gracefully.
1055 TEST_F(PipelineIntegrationTest
, MidStreamConfigChangesFail
) {
1057 GetTestDataFilePath("midstream_config_change.mp3"), PIPELINE_OK
));
1059 ASSERT_EQ(WaitUntilEndedOrError(), PIPELINE_ERROR_DECODE
);
1064 TEST_F(PipelineIntegrationTest
, BasicPlayback_16x9AspectRatio
) {
1065 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-16x9-aspect.webm"),
1068 ASSERT_TRUE(WaitUntilOnEnded());
1071 TEST_P(PipelineIntegrationTest
, EncryptedPlayback_WebM
) {
1072 MockMediaSource
source("bear-320x240-av_enc-av.webm", kWebM
, 219816,
1074 FakeEncryptedMedia
encrypted_media(new KeyProvidingApp());
1075 StartPipelineWithEncryptedMedia(&source
, &encrypted_media
);
1077 source
.EndOfStream();
1078 ASSERT_EQ(PIPELINE_OK
, pipeline_status_
);
1082 ASSERT_TRUE(WaitUntilOnEnded());
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_
);
1098 ASSERT_TRUE(WaitUntilOnEnded());
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_
);
1114 ASSERT_TRUE(WaitUntilOnEnded());
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_
);
1131 ASSERT_TRUE(WaitUntilOnEnded());
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_
);
1147 ASSERT_TRUE(WaitUntilOnEnded());
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_
);
1164 ASSERT_TRUE(WaitUntilOnEnded());
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_
);
1181 ASSERT_TRUE(WaitUntilOnEnded());
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());
1199 ASSERT_TRUE(WaitUntilOnEnded());
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);
1215 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time
));
1217 ASSERT_TRUE(Seek(seek_time
));
1218 EXPECT_EQ(pipeline_
->GetMediaTime(), seek_time
);
1220 ASSERT_TRUE(WaitUntilOnEnded());
1222 // Make sure seeking after reaching the end works as expected.
1224 ASSERT_TRUE(Seek(seek_time
));
1225 EXPECT_EQ(pipeline_
->GetMediaTime(), seek_time
);
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);
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
,
1254 base::TimeDelta::FromMilliseconds(464),
1255 base::TimeDelta::FromMilliseconds(617),
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
,
1263 base::TimeDelta::FromMilliseconds(167),
1264 base::TimeDelta::FromMilliseconds(1668),
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"),
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"),
1281 ASSERT_TRUE(WaitUntilOnEnded());
1284 // Verify that VP9 video and Opus audio in the same WebM container can be played
1286 TEST_F(PipelineIntegrationTest
, BasicPlayback_VP9_Opus_WebM
) {
1287 ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9-opus.webm"),
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"),
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"),
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"),
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
,
1325 } // namespace media