Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / filters / pipeline_integration_test.cc
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.
4
5 #include "media/filters/pipeline_integration_test_base.h"
6
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"
19
20 using testing::_;
21 using testing::AnyNumber;
22 using testing::AtMost;
23 using testing::SaveArg;
24 using testing::Values;
25
26 namespace media {
27
28 const char kSourceId[] = "SourceId";
29 const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 };
30
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)
46
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
51 };
52
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
57 };
58
59 const int kAppendWholeFile = -1;
60
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;
69
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)
76
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);
92
93   timeline_offset += base::TimeDelta::FromMicroseconds(123);
94
95   return timeline_offset;
96 }
97
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;
104
105   return base::Time::FromUTCExploded(exploded_time);
106 }
107
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() {}
116
117     virtual void OnSessionCreated(uint32 session_id,
118                                   const std::string& web_session_id) = 0;
119
120     virtual void OnSessionMessage(uint32 session_id,
121                                   const std::vector<uint8>& message,
122                                   const std::string& destination_url) = 0;
123
124     virtual void OnSessionReady(uint32 session_id) = 0;
125
126     virtual void OnSessionClosed(uint32 session_id) = 0;
127
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";
133     }
134
135     virtual void NeedKey(const std::string& type,
136                          const std::vector<uint8>& init_data,
137                          AesDecryptor* decryptor) = 0;
138   };
139
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) {}
152
153   AesDecryptor* decryptor() {
154     return &decryptor_;
155   }
156
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);
160   }
161
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);
166   }
167
168   void OnSessionReady(uint32 session_id) {
169     app_->OnSessionReady(session_id);
170   }
171
172   void OnSessionClosed(uint32 session_id) {
173     app_->OnSessionClosed(session_id);
174   }
175
176   void OnSessionError(uint32 session_id,
177                       MediaKeys::KeyError error_code,
178                       uint32 system_code) {
179     app_->OnSessionError(session_id, error_code, system_code);
180   }
181
182   void NeedKey(const std::string& type,
183                const std::vector<uint8>& init_data) {
184     app_->NeedKey(type, init_data, &decryptor_);
185   }
186
187  private:
188   AesDecryptor decryptor_;
189   scoped_ptr<AppBase> app_;
190 };
191
192 // Provides |kSecretKey| in response to needkey.
193 class KeyProvidingApp : public FakeEncryptedMedia::AppBase {
194  public:
195   KeyProvidingApp() : current_session_id_(0) {}
196
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());
201   }
202
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());
208
209     current_session_id_ = session_id;
210   }
211
212   virtual void OnSessionReady(uint32 session_id) OVERRIDE {
213     EXPECT_GT(session_id, 0u);
214   }
215
216   virtual void OnSessionClosed(uint32 session_id) OVERRIDE {
217     EXPECT_GT(session_id, 0u);
218   }
219
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)));
226     }
227
228     EXPECT_EQ(current_session_id_, 12u);
229
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);
238     }
239
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());
246   }
247
248   uint32 current_session_id_;
249 };
250
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());
258   }
259
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";
266   }
267
268   virtual void OnSessionReady(uint32 session_id) OVERRIDE {
269     EXPECT_GT(session_id, 0u);
270     FAIL() << "Unexpected Ready";
271   }
272
273   virtual void OnSessionClosed(uint32 session_id) OVERRIDE {
274     EXPECT_GT(session_id, 0u);
275     FAIL() << "Unexpected Closed";
276   }
277
278   virtual void NeedKey(const std::string& type,
279                        const std::vector<uint8>& init_data,
280                        AesDecryptor* decryptor) OVERRIDE {
281   }
282 };
283
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) {
304
305     file_data_ = ReadTestDataFile(filename);
306
307     if (initial_append_size_ == kAppendWholeFile)
308       initial_append_size_ = file_data_->data_size();
309
310     DCHECK_GT(initial_append_size_, 0);
311     DCHECK_LE(initial_append_size_, file_data_->data_size());
312   }
313
314   virtual ~MockMediaSource() {}
315
316   scoped_ptr<Demuxer> GetDemuxer() { return owned_chunk_demuxer_.Pass(); }
317
318   void set_need_key_cb(const Demuxer::NeedKeyCB& need_key_cb) {
319     need_key_cb_ = need_key_cb;
320   }
321
322   void Seek(base::TimeDelta seek_time, int new_position, int seek_append_size) {
323     chunk_demuxer_->StartWaitingForSeek(seek_time);
324
325     // TODO(wolenetz): Test timestamp offset updating once "sequence" append
326     // mode processing is implemented. See http://crbug.com/249422.
327     chunk_demuxer_->Abort(
328         kSourceId,
329         base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_);
330
331     DCHECK_GE(new_position, 0);
332     DCHECK_LT(new_position, file_data_->data_size());
333     current_position_ = new_position;
334
335     AppendData(seek_append_size);
336   }
337
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());
342
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;
349   }
350
351   void AppendAtTime(base::TimeDelta timestamp_offset,
352                     const uint8* pData,
353                     int size) {
354     CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
355     chunk_demuxer_->AppendData(kSourceId, pData, size,
356                                base::TimeDelta(), kInfiniteDuration(),
357                                &timestamp_offset);
358     last_timestamp_offset_ = timestamp_offset;
359   }
360
361   void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset,
362                               base::TimeDelta append_window_start,
363                               base::TimeDelta append_window_end,
364                               const uint8* pData,
365                               int size) {
366     CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
367     chunk_demuxer_->AppendData(kSourceId,
368                                pData,
369                                size,
370                                append_window_start,
371                                append_window_end,
372                                &timestamp_offset);
373     last_timestamp_offset_ = timestamp_offset;
374   }
375
376   void EndOfStream() {
377     chunk_demuxer_->MarkEndOfStream(PIPELINE_OK);
378   }
379
380   void Abort() {
381     if (!chunk_demuxer_)
382       return;
383     chunk_demuxer_->Shutdown();
384     chunk_demuxer_ = NULL;
385   }
386
387   void DemuxerOpened() {
388     base::MessageLoop::current()->PostTask(
389         FROM_HERE, base::Bind(&MockMediaSource::DemuxerOpenedTask,
390                               base::Unretained(this)));
391   }
392
393   void DemuxerOpenedTask() {
394     // This code assumes that |mimetype_| is one of the following forms.
395     // 1. audio/mpeg
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);
403
404       CHECK_NE(codecs_param_start, std::string::npos);
405
406       codecs_param_start += 8; // Skip over the codecs=".
407
408       size_t codecs_param_end = mimetype_.find("\"", codecs_param_start);
409
410       CHECK_NE(codecs_param_end, std::string::npos);
411
412       std::string codecs_param =
413           mimetype_.substr(codecs_param_start,
414                            codecs_param_end - codecs_param_start);
415       Tokenize(codecs_param, ",", &codecs);
416     }
417
418     CHECK_EQ(chunk_demuxer_->AddId(kSourceId, type, codecs,
419                                    use_legacy_frame_processor_),
420              ChunkDemuxer::kOk);
421
422     AppendData(initial_append_size_);
423   }
424
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);
430   }
431
432   base::TimeDelta last_timestamp_offset() const {
433     return last_timestamp_offset_;
434   }
435
436  private:
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_;
447 };
448
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 {
456  public:
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));
461     pipeline_->Start(
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)),
470         base::Closure());
471
472     message_loop_.Run();
473   }
474
475   void StartHashedPipelineWithMediaSource(MockMediaSource* source) {
476     hashing_enabled_ = true;
477     StartPipelineWithMediaSource(source);
478   }
479
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));
486     pipeline_->Start(
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)),
496         base::Closure());
497
498     source->set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey,
499                                        base::Unretained(encrypted_media)));
500
501     message_loop_.Run();
502   }
503
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,
515                            GetParam());
516     StartPipelineWithMediaSource(&source);
517
518     if (pipeline_status_ != PIPELINE_OK)
519       return false;
520
521     Play();
522     if (!WaitUntilCurrentTimeIsAfter(start_seek_time))
523       return false;
524
525     source.Seek(seek_time, seek_file_position, seek_append_size);
526     if (!Seek(seek_time))
527       return false;
528
529     source.EndOfStream();
530
531     source.Abort();
532     Stop();
533     return true;
534   }
535 };
536
537 TEST_F(PipelineIntegrationTest, BasicPlayback) {
538   ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK));
539
540   Play();
541
542   ASSERT_TRUE(WaitUntilOnEnded());
543 }
544
545 TEST_F(PipelineIntegrationTest, BasicPlaybackOpusOgg) {
546   ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus.ogg"), PIPELINE_OK));
547
548   Play();
549
550   ASSERT_TRUE(WaitUntilOnEnded());
551 }
552
553 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed) {
554   ASSERT_TRUE(Start(
555       GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK, kHashed));
556
557   Play();
558
559   ASSERT_TRUE(WaitUntilOnEnded());
560
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());
564 }
565
566 TEST_F(PipelineIntegrationTest, BasicPlaybackLive) {
567   ASSERT_TRUE(Start(
568       GetTestDataFilePath("bear-320x240-live.webm"), PIPELINE_OK, kHashed));
569
570   Play();
571
572   ASSERT_TRUE(WaitUntilOnEnded());
573
574   EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash());
575   EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash());
576
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());
581 }
582
583 TEST_F(PipelineIntegrationTest, F32PlaybackHashed) {
584   ASSERT_TRUE(
585       Start(GetTestDataFilePath("sfx_f32le.wav"), PIPELINE_OK, kHashed));
586   Play();
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());
590 }
591
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)));
596
597   ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-av_enc-av.webm"),
598                     encrypted_media.decryptor()));
599
600   Play();
601
602   ASSERT_TRUE(WaitUntilOnEnded());
603   Stop();
604 }
605
606 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource) {
607   MockMediaSource source("bear-320x240.webm", kWebM, 219229, GetParam());
608   StartPipelineWithMediaSource(&source);
609   source.EndOfStream();
610
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());
615
616   Play();
617
618   ASSERT_TRUE(WaitUntilOnEnded());
619
620   EXPECT_TRUE(demuxer_->GetTimelineOffset().is_null());
621   source.Abort();
622   Stop();
623 }
624
625 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_Live) {
626   MockMediaSource source("bear-320x240-live.webm", kWebM, 219221, GetParam());
627   StartPipelineWithMediaSource(&source);
628   source.EndOfStream();
629
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());
634
635   Play();
636
637   ASSERT_TRUE(WaitUntilOnEnded());
638
639   EXPECT_EQ(kLiveTimelineOffset(),
640             demuxer_->GetTimelineOffset());
641   source.Abort();
642   Stop();
643 }
644
645 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP9_WebM) {
646   MockMediaSource source("bear-vp9.webm", kWebMVP9, 67504, GetParam());
647   StartPipelineWithMediaSource(&source);
648   source.EndOfStream();
649
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());
654
655   Play();
656
657   ASSERT_TRUE(WaitUntilOnEnded());
658   source.Abort();
659   Stop();
660 }
661
662 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP8A_WebM) {
663   MockMediaSource source("bear-vp8a.webm", kVideoOnlyWebM, kAppendWholeFile,
664                          GetParam());
665   StartPipelineWithMediaSource(&source);
666   source.EndOfStream();
667
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());
672
673   Play();
674
675   ASSERT_TRUE(WaitUntilOnEnded());
676   source.Abort();
677   Stop();
678 }
679
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();
685
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());
690   Play();
691
692   ASSERT_TRUE(WaitUntilOnEnded());
693   source.Abort();
694   Stop();
695 }
696
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);
702
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());
707
708   base::TimeDelta start_seek_time = base::TimeDelta::FromMilliseconds(1000);
709   base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2000);
710
711   Play();
712   ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
713   source.Seek(seek_time, 0x1D5, 34017);
714   source.EndOfStream();
715   ASSERT_TRUE(Seek(seek_time));
716
717   ASSERT_TRUE(WaitUntilOnEnded());
718
719   EXPECT_EQ("0.76,0.20,-0.82,-0.58,-1.29,-0.29,", GetAudioHash());
720
721   source.Abort();
722   Stop();
723 }
724
725 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_WebM) {
726   MockMediaSource source("bear-320x240-16x9-aspect.webm", kWebM,
727                          kAppendWholeFile, GetParam());
728   StartPipelineWithMediaSource(&source);
729
730   scoped_refptr<DecoderBuffer> second_file =
731       ReadTestDataFile("bear-640x360.webm");
732
733   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
734                       second_file->data(), second_file->data_size());
735
736   source.EndOfStream();
737
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());
742
743   Play();
744
745   EXPECT_TRUE(WaitUntilOnEnded());
746   source.Abort();
747   Stop();
748 }
749
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);
755
756   scoped_refptr<DecoderBuffer> second_file =
757       ReadTestDataFile("bear-640x360-av_enc-av.webm");
758
759   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
760                       second_file->data(), second_file->data_size());
761
762   source.EndOfStream();
763
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());
768
769   Play();
770
771   EXPECT_TRUE(WaitUntilOnEnded());
772   source.Abort();
773   Stop();
774 }
775
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);
783
784   scoped_refptr<DecoderBuffer> second_file =
785       ReadTestDataFile("bear-640x360-av_enc-av.webm");
786
787   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
788                       second_file->data(), second_file->data_size());
789
790   source.EndOfStream();
791
792   message_loop_.Run();
793   EXPECT_EQ(PIPELINE_ERROR_DECODE, pipeline_status_);
794
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());
800
801   Play();
802
803   EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
804   source.Abort();
805 }
806
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);
814
815   scoped_refptr<DecoderBuffer> second_file =
816       ReadTestDataFile("bear-640x360.webm");
817
818   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
819                       second_file->data(), second_file->data_size());
820
821   source.EndOfStream();
822
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());
828
829   Play();
830
831   EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
832   source.Abort();
833 }
834
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();
840
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());
844
845   Play();
846
847   EXPECT_TRUE(WaitUntilOnEnded());
848 }
849
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());
854
855   scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.adts");
856   source.AppendAtTime(
857       source.last_timestamp_offset() - base::TimeDelta::FromMilliseconds(10),
858       second_file->data(),
859       second_file->data_size());
860   source.EndOfStream();
861
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());
866
867   Play();
868
869   EXPECT_TRUE(WaitUntilOnEnded());
870 }
871
872 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed_MP3) {
873   ASSERT_TRUE(Start(GetTestDataFilePath("sfx.mp3"), PIPELINE_OK, kHashed));
874
875   Play();
876
877   ASSERT_TRUE(WaitUntilOnEnded());
878
879   // Verify codec delay and preroll are stripped.
880   EXPECT_EQ("3.05,2.87,3.00,3.32,3.58,4.08,", GetAudioHash());
881 }
882
883 TEST_P(PipelineIntegrationTest, MediaSource_MP3) {
884   MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile, GetParam());
885   StartHashedPipelineWithMediaSource(&source);
886   source.EndOfStream();
887
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());
891
892   Play();
893
894   EXPECT_TRUE(WaitUntilOnEnded());
895
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());
899 }
900
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());
905
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;
912
913   scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.mp3");
914   source.AppendAtTimeWithWindow(append_time,
915                                 append_time + mp3_preroll_duration,
916                                 kInfiniteDuration(),
917                                 second_file->data(),
918                                 second_file->data_size());
919   source.EndOfStream();
920
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());
925
926   Play();
927
928   EXPECT_TRUE(WaitUntilOnEnded());
929 }
930
931 TEST_P(PipelineIntegrationTest, MediaSource_MP3_Icecast) {
932   MockMediaSource source("icy_sfx.mp3", kMP3, kAppendWholeFile, GetParam());
933   StartPipelineWithMediaSource(&source);
934   source.EndOfStream();
935
936   Play();
937
938   EXPECT_TRUE(WaitUntilOnEnded());
939 }
940
941 TEST_P(PipelineIntegrationTest, MediaSource_ConfigChange_MP4) {
942   MockMediaSource source("bear-640x360-av_frag.mp4", kMP4, kAppendWholeFile,
943                          GetParam());
944   StartPipelineWithMediaSource(&source);
945
946   scoped_refptr<DecoderBuffer> second_file =
947       ReadTestDataFile("bear-1280x720-av_frag.mp4");
948
949   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
950                       second_file->data(), second_file->data_size());
951
952   source.EndOfStream();
953
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());
958
959   Play();
960
961   EXPECT_TRUE(WaitUntilOnEnded());
962   source.Abort();
963   Stop();
964 }
965
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);
972
973   scoped_refptr<DecoderBuffer> second_file =
974       ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4");
975
976   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
977                       second_file->data(), second_file->data_size());
978
979   source.EndOfStream();
980
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());
985
986   Play();
987
988   EXPECT_TRUE(WaitUntilOnEnded());
989   source.Abort();
990   Stop();
991 }
992
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);
1001
1002   scoped_refptr<DecoderBuffer> second_file =
1003       ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4");
1004
1005   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
1006                       second_file->data(), second_file->data_size());
1007
1008   source.EndOfStream();
1009
1010   message_loop_.Run();
1011   EXPECT_EQ(PIPELINE_ERROR_DECODE, pipeline_status_);
1012
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());
1018
1019   Play();
1020
1021   EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
1022   source.Abort();
1023 }
1024
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);
1032
1033   scoped_refptr<DecoderBuffer> second_file =
1034       ReadTestDataFile("bear-1280x720-av_frag.mp4");
1035
1036   source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
1037                       second_file->data(), second_file->data_size());
1038
1039   source.EndOfStream();
1040
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());
1046
1047   Play();
1048
1049   EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError());
1050   source.Abort();
1051 }
1052
1053 // Verify files which change configuration midstream fail gracefully.
1054 TEST_F(PipelineIntegrationTest, MidStreamConfigChangesFail) {
1055   ASSERT_TRUE(Start(
1056       GetTestDataFilePath("midstream_config_change.mp3"), PIPELINE_OK));
1057   Play();
1058   ASSERT_EQ(WaitUntilEndedOrError(), PIPELINE_ERROR_DECODE);
1059 }
1060
1061 #endif
1062
1063 TEST_F(PipelineIntegrationTest, BasicPlayback_16x9AspectRatio) {
1064   ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-16x9-aspect.webm"),
1065                     PIPELINE_OK));
1066   Play();
1067   ASSERT_TRUE(WaitUntilOnEnded());
1068 }
1069
1070 TEST_P(PipelineIntegrationTest, EncryptedPlayback_WebM) {
1071   MockMediaSource source("bear-320x240-av_enc-av.webm", kWebM, 219816,
1072                          GetParam());
1073   FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
1074   StartPipelineWithEncryptedMedia(&source, &encrypted_media);
1075
1076   source.EndOfStream();
1077   ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1078
1079   Play();
1080
1081   ASSERT_TRUE(WaitUntilOnEnded());
1082   source.Abort();
1083   Stop();
1084 }
1085
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);
1091
1092   source.EndOfStream();
1093   ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1094
1095   Play();
1096
1097   ASSERT_TRUE(WaitUntilOnEnded());
1098   source.Abort();
1099   Stop();
1100 }
1101
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);
1107
1108   source.EndOfStream();
1109   ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1110
1111   Play();
1112
1113   ASSERT_TRUE(WaitUntilOnEnded());
1114   source.Abort();
1115   Stop();
1116 }
1117
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);
1124
1125   source.EndOfStream();
1126   ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1127
1128   Play();
1129
1130   ASSERT_TRUE(WaitUntilOnEnded());
1131   source.Abort();
1132   Stop();
1133 }
1134
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);
1140
1141   source.EndOfStream();
1142   ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1143
1144   Play();
1145
1146   ASSERT_TRUE(WaitUntilOnEnded());
1147   source.Abort();
1148   Stop();
1149 }
1150
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);
1157
1158   source.EndOfStream();
1159   ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1160
1161   Play();
1162
1163   ASSERT_TRUE(WaitUntilOnEnded());
1164   source.Abort();
1165   Stop();
1166 }
1167
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);
1174
1175   source.EndOfStream();
1176   ASSERT_EQ(PIPELINE_OK, pipeline_status_);
1177
1178   Play();
1179
1180   ASSERT_TRUE(WaitUntilOnEnded());
1181   source.Abort();
1182   Stop();
1183 }
1184
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();
1190
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());
1195
1196   Play();
1197
1198   ASSERT_TRUE(WaitUntilOnEnded());
1199   source.Abort();
1200   Stop();
1201 }
1202
1203 #endif
1204
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));
1208
1209   base::TimeDelta duration(pipeline_->GetMediaDuration());
1210   base::TimeDelta start_seek_time(duration / 4);
1211   base::TimeDelta seek_time(duration * 3 / 4);
1212
1213   Play();
1214   ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
1215   Pause();
1216   ASSERT_TRUE(Seek(seek_time));
1217   EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
1218   Play();
1219   ASSERT_TRUE(WaitUntilOnEnded());
1220
1221   // Make sure seeking after reaching the end works as expected.
1222   Pause();
1223   ASSERT_TRUE(Seek(seek_time));
1224   EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
1225   Play();
1226   ASSERT_TRUE(WaitUntilOnEnded());
1227 }
1228
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));
1232
1233   base::TimeDelta duration(pipeline_->GetMediaDuration());
1234   base::TimeDelta start_seek_time(duration / 4);
1235   base::TimeDelta seek_time(duration * 3 / 4);
1236
1237   Play();
1238   ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
1239   ASSERT_TRUE(Seek(seek_time));
1240   EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
1241   ASSERT_TRUE(WaitUntilOnEnded());
1242
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());
1247 }
1248
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,
1252                                  8192,
1253                                  base::TimeDelta::FromMilliseconds(464),
1254                                  base::TimeDelta::FromMilliseconds(617),
1255                                  0x10CA, 19730));
1256 }
1257
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,
1261                                  32768,
1262                                  base::TimeDelta::FromMilliseconds(167),
1263                                  base::TimeDelta::FromMilliseconds(1668),
1264                                  0x1C896, 65536));
1265 }
1266
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"),
1270                     PIPELINE_OK));
1271   Play();
1272   ASSERT_TRUE(WaitUntilOnEnded());
1273 }
1274
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"),
1278                     PIPELINE_OK));
1279   Play();
1280   ASSERT_TRUE(WaitUntilOnEnded());
1281 }
1282
1283 // Verify that VP9 video and Opus audio in the same WebM container can be played
1284 // back.
1285 TEST_F(PipelineIntegrationTest, BasicPlayback_VP9_Opus_WebM) {
1286   ASSERT_TRUE(Start(GetTestDataFilePath("bear-vp9-opus.webm"),
1287                     PIPELINE_OK));
1288   Play();
1289   ASSERT_TRUE(WaitUntilOnEnded());
1290 }
1291
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"),
1295                     PIPELINE_OK));
1296   Play();
1297   ASSERT_TRUE(WaitUntilOnEnded());
1298   EXPECT_EQ(last_video_frame_format_, VideoFrame::YV12A);
1299 }
1300
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"),
1304                     PIPELINE_OK));
1305   Play();
1306   ASSERT_TRUE(WaitUntilOnEnded());
1307   EXPECT_EQ(last_video_frame_format_, VideoFrame::YV12A);
1308 }
1309
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"),
1314                     PIPELINE_OK));
1315   Play();
1316   ASSERT_TRUE(WaitUntilOnEnded());
1317 }
1318
1319 // For MediaSource tests, generate two sets of tests: one using FrameProcessor,
1320 // and one using LegacyFrameProcessor.
1321 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, PipelineIntegrationTest,
1322                         Values(false));
1323 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, PipelineIntegrationTest,
1324                         Values(true));
1325
1326 }  // namespace media