d2c410da9c02c7040b36b8490254b88b8b8cd447
[platform/framework/web/crosswalk.git] / src / media / filters / chunk_demuxer_unittest.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 <algorithm>
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "media/base/audio_decoder_config.h"
13 #include "media/base/decoder_buffer.h"
14 #include "media/base/decrypt_config.h"
15 #include "media/base/mock_demuxer_host.h"
16 #include "media/base/test_data_util.h"
17 #include "media/base/test_helpers.h"
18 #include "media/filters/chunk_demuxer.h"
19 #include "media/formats/webm/cluster_builder.h"
20 #include "media/formats/webm/webm_constants.h"
21 #include "media/formats/webm/webm_crypto_helpers.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using ::testing::AnyNumber;
25 using ::testing::Exactly;
26 using ::testing::InSequence;
27 using ::testing::NotNull;
28 using ::testing::Return;
29 using ::testing::SaveArg;
30 using ::testing::SetArgumentPointee;
31 using ::testing::_;
32
33 namespace media {
34
35 const uint8 kTracksHeader[] = {
36   0x16, 0x54, 0xAE, 0x6B,  // Tracks ID
37   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // tracks(size = 0)
38 };
39
40 // WebM Block bytes that represent a VP8 keyframe.
41 const uint8 kVP8Keyframe[] = {
42   0x010, 0x00, 0x00, 0x9d, 0x01, 0x2a, 0x00, 0x10, 0x00, 0x10, 0x00
43 };
44
45 // WebM Block bytes that represent a VP8 interframe.
46 const uint8 kVP8Interframe[] = { 0x11, 0x00, 0x00 };
47
48 const int kTracksHeaderSize = sizeof(kTracksHeader);
49 const int kTracksSizeOffset = 4;
50
51 // The size of TrackEntry element in test file "webm_vorbis_track_entry" starts
52 // at index 1 and spans 8 bytes.
53 const int kAudioTrackSizeOffset = 1;
54 const int kAudioTrackSizeWidth = 8;
55 const int kAudioTrackEntryHeaderSize =
56     kAudioTrackSizeOffset + kAudioTrackSizeWidth;
57
58 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at
59 // index 1 and spans 8 bytes.
60 const int kVideoTrackSizeOffset = 1;
61 const int kVideoTrackSizeWidth = 8;
62 const int kVideoTrackEntryHeaderSize =
63     kVideoTrackSizeOffset + kVideoTrackSizeWidth;
64
65 const int kVideoTrackNum = 1;
66 const int kAudioTrackNum = 2;
67 const int kTextTrackNum = 3;
68
69 const int kAudioBlockDuration = 23;
70 const int kVideoBlockDuration = 33;
71 const int kTextBlockDuration = 100;
72 const int kBlockSize = 10;
73
74 const char kSourceId[] = "SourceId";
75 const char kDefaultFirstClusterRange[] = "{ [0,46) }";
76 const int kDefaultFirstClusterEndTimestamp = 66;
77 const int kDefaultSecondClusterEndTimestamp = 132;
78
79 base::TimeDelta kDefaultDuration() {
80   return base::TimeDelta::FromMilliseconds(201224);
81 }
82
83 // Write an integer into buffer in the form of vint that spans 8 bytes.
84 // The data pointed by |buffer| should be at least 8 bytes long.
85 // |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF.
86 static void WriteInt64(uint8* buffer, int64 number) {
87   DCHECK(number >= 0 && number < GG_LONGLONG(0x00FFFFFFFFFFFFFF));
88   buffer[0] = 0x01;
89   int64 tmp = number;
90   for (int i = 7; i > 0; i--) {
91     buffer[i] = tmp & 0xff;
92     tmp >>= 8;
93   }
94 }
95
96 MATCHER_P(HasTimestamp, timestamp_in_ms, "") {
97   return arg.get() && !arg->end_of_stream() &&
98          arg->timestamp().InMilliseconds() == timestamp_in_ms;
99 }
100
101 MATCHER(IsEndOfStream, "") { return arg.get() && arg->end_of_stream(); }
102
103 static void OnReadDone(const base::TimeDelta& expected_time,
104                        bool* called,
105                        DemuxerStream::Status status,
106                        const scoped_refptr<DecoderBuffer>& buffer) {
107   EXPECT_EQ(status, DemuxerStream::kOk);
108   EXPECT_EQ(expected_time, buffer->timestamp());
109   *called = true;
110 }
111
112 static void OnReadDone_AbortExpected(
113     bool* called, DemuxerStream::Status status,
114     const scoped_refptr<DecoderBuffer>& buffer) {
115   EXPECT_EQ(status, DemuxerStream::kAborted);
116   EXPECT_EQ(NULL, buffer.get());
117   *called = true;
118 }
119
120 static void OnReadDone_EOSExpected(bool* called,
121                                    DemuxerStream::Status status,
122                                    const scoped_refptr<DecoderBuffer>& buffer) {
123   EXPECT_EQ(status, DemuxerStream::kOk);
124   EXPECT_TRUE(buffer->end_of_stream());
125   *called = true;
126 }
127
128 static void OnSeekDone_OKExpected(bool* called, PipelineStatus status) {
129   EXPECT_EQ(status, PIPELINE_OK);
130   *called = true;
131 }
132
133 static void LogFunc(const std::string& str) { DVLOG(1) << str; }
134
135 class ChunkDemuxerTest : public testing::Test {
136  protected:
137   enum CodecsIndex {
138     AUDIO,
139     VIDEO,
140     MAX_CODECS_INDEX
141   };
142
143   // Default cluster to append first for simple tests.
144   scoped_ptr<Cluster> kDefaultFirstCluster() {
145     return GenerateCluster(0, 4);
146   }
147
148   // Default cluster to append after kDefaultFirstCluster()
149   // has been appended. This cluster starts with blocks that
150   // have timestamps consistent with the end times of the blocks
151   // in kDefaultFirstCluster() so that these two clusters represent
152   // a continuous region.
153   scoped_ptr<Cluster> kDefaultSecondCluster() {
154     return GenerateCluster(46, 66, 5);
155   }
156
157   ChunkDemuxerTest() {
158     CreateNewDemuxer();
159   }
160
161   void CreateNewDemuxer() {
162     base::Closure open_cb =
163         base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this));
164     Demuxer::NeedKeyCB need_key_cb =
165         base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this));
166     demuxer_.reset(new ChunkDemuxer(open_cb, need_key_cb,
167                                     base::Bind(&LogFunc)));
168   }
169
170   virtual ~ChunkDemuxerTest() {
171     ShutdownDemuxer();
172   }
173
174   void CreateInitSegment(int stream_flags,
175                          bool is_audio_encrypted, bool is_video_encrypted,
176                          scoped_ptr<uint8[]>* buffer,
177                          int* size) {
178     bool has_audio = (stream_flags & HAS_AUDIO) != 0;
179     bool has_video = (stream_flags & HAS_VIDEO) != 0;
180     bool has_text = (stream_flags & HAS_TEXT) != 0;
181     scoped_refptr<DecoderBuffer> ebml_header;
182     scoped_refptr<DecoderBuffer> info;
183     scoped_refptr<DecoderBuffer> audio_track_entry;
184     scoped_refptr<DecoderBuffer> video_track_entry;
185     scoped_refptr<DecoderBuffer> audio_content_encodings;
186     scoped_refptr<DecoderBuffer> video_content_encodings;
187     scoped_refptr<DecoderBuffer> text_track_entry;
188
189     ebml_header = ReadTestDataFile("webm_ebml_element");
190
191     info = ReadTestDataFile("webm_info_element");
192
193     int tracks_element_size = 0;
194
195     if (has_audio) {
196       audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry");
197       tracks_element_size += audio_track_entry->data_size();
198       if (is_audio_encrypted) {
199         audio_content_encodings = ReadTestDataFile("webm_content_encodings");
200         tracks_element_size += audio_content_encodings->data_size();
201       }
202     }
203
204     if (has_video) {
205       video_track_entry = ReadTestDataFile("webm_vp8_track_entry");
206       tracks_element_size += video_track_entry->data_size();
207       if (is_video_encrypted) {
208         video_content_encodings = ReadTestDataFile("webm_content_encodings");
209         tracks_element_size += video_content_encodings->data_size();
210       }
211     }
212
213     if (has_text) {
214       // TODO(matthewjheaney): create an abstraction to do
215       // this (http://crbug/321454).
216       // We need it to also handle the creation of multiple text tracks.
217       //
218       // This is the track entry for a text track,
219       // TrackEntry [AE], size=30
220       //   TrackNum [D7], size=1, val=3
221       //   TrackUID [73] [C5], size=1, value=3
222       //   TrackType [83], size=1, val=0x11
223       //   CodecId [86], size=18, val="D_WEBVTT/SUBTITLES"
224       const char str[] = "\xAE\x9E\xD7\x81\x03\x73\xC5\x81\x03"
225                          "\x83\x81\x11\x86\x92"
226                          "D_WEBVTT/SUBTITLES";
227       const int len = strlen(str);
228       DCHECK_EQ(len, 32);
229       const uint8* const buf = reinterpret_cast<const uint8*>(str);
230       text_track_entry = DecoderBuffer::CopyFrom(buf, len);
231       tracks_element_size += text_track_entry->data_size();
232     }
233
234     *size = ebml_header->data_size() + info->data_size() +
235         kTracksHeaderSize + tracks_element_size;
236
237     buffer->reset(new uint8[*size]);
238
239     uint8* buf = buffer->get();
240     memcpy(buf, ebml_header->data(), ebml_header->data_size());
241     buf += ebml_header->data_size();
242
243     memcpy(buf, info->data(), info->data_size());
244     buf += info->data_size();
245
246     memcpy(buf, kTracksHeader, kTracksHeaderSize);
247     WriteInt64(buf + kTracksSizeOffset, tracks_element_size);
248     buf += kTracksHeaderSize;
249
250     // TODO(xhwang): Simplify this! Probably have test data files that contain
251     // ContentEncodings directly instead of trying to create one at run-time.
252     if (has_audio) {
253       memcpy(buf, audio_track_entry->data(),
254              audio_track_entry->data_size());
255       if (is_audio_encrypted) {
256         memcpy(buf + audio_track_entry->data_size(),
257                audio_content_encodings->data(),
258                audio_content_encodings->data_size());
259         WriteInt64(buf + kAudioTrackSizeOffset,
260                    audio_track_entry->data_size() +
261                    audio_content_encodings->data_size() -
262                    kAudioTrackEntryHeaderSize);
263         buf += audio_content_encodings->data_size();
264       }
265       buf += audio_track_entry->data_size();
266     }
267
268     if (has_video) {
269       memcpy(buf, video_track_entry->data(),
270              video_track_entry->data_size());
271       if (is_video_encrypted) {
272         memcpy(buf + video_track_entry->data_size(),
273                video_content_encodings->data(),
274                video_content_encodings->data_size());
275         WriteInt64(buf + kVideoTrackSizeOffset,
276                    video_track_entry->data_size() +
277                    video_content_encodings->data_size() -
278                    kVideoTrackEntryHeaderSize);
279         buf += video_content_encodings->data_size();
280       }
281       buf += video_track_entry->data_size();
282     }
283
284     if (has_text) {
285       memcpy(buf, text_track_entry->data(),
286              text_track_entry->data_size());
287       buf += text_track_entry->data_size();
288     }
289   }
290
291   ChunkDemuxer::Status AddId() {
292     return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
293   }
294
295   ChunkDemuxer::Status AddId(const std::string& source_id, int stream_flags) {
296     bool has_audio = (stream_flags & HAS_AUDIO) != 0;
297     bool has_video = (stream_flags & HAS_VIDEO) != 0;
298     std::vector<std::string> codecs;
299     std::string type;
300
301     if (has_audio) {
302       codecs.push_back("vorbis");
303       type = "audio/webm";
304     }
305
306     if (has_video) {
307       codecs.push_back("vp8");
308       type = "video/webm";
309     }
310
311     if (!has_audio && !has_video) {
312       return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
313     }
314
315     return demuxer_->AddId(source_id, type, codecs);
316   }
317
318   void AppendData(const uint8* data, size_t length) {
319     AppendData(kSourceId, data, length);
320   }
321
322   void AppendCluster(const std::string& source_id,
323                      scoped_ptr<Cluster> cluster) {
324     AppendData(source_id, cluster->data(), cluster->size());
325   }
326
327   void AppendCluster(scoped_ptr<Cluster> cluster) {
328     AppendCluster(kSourceId, cluster.Pass());
329   }
330
331   void AppendCluster(int timecode, int block_count) {
332     AppendCluster(GenerateCluster(timecode, block_count));
333   }
334
335   void AppendSingleStreamCluster(const std::string& source_id, int track_number,
336                                  int timecode, int block_count) {
337     int block_duration = 0;
338     switch (track_number) {
339       case kVideoTrackNum:
340         block_duration = kVideoBlockDuration;
341         break;
342       case kAudioTrackNum:
343         block_duration = kAudioBlockDuration;
344         break;
345       case kTextTrackNum:
346         block_duration = kTextBlockDuration;
347         break;
348     }
349     ASSERT_NE(block_duration, 0);
350     int end_timecode = timecode + block_count * block_duration;
351     AppendCluster(source_id,
352                   GenerateSingleStreamCluster(
353                       timecode, end_timecode, track_number, block_duration));
354   }
355
356   // |cluster_description| - A space delimited string of buffer info that
357   //  is used to construct a cluster. Each buffer info is a timestamp in
358   //  milliseconds and optionally followed by a 'K' to indicate that a buffer
359   //  should be marked as a keyframe. For example "0K 30 60" should constuct
360   //  a cluster with 3 blocks: a keyframe with timestamp 0 and 2 non-keyframes
361   //  at 30ms and 60ms.
362   void AppendSingleStreamCluster(const std::string& source_id, int track_number,
363                                  const std::string& cluster_description) {
364     std::vector<std::string> timestamps;
365     base::SplitString(cluster_description, ' ', &timestamps);
366
367     ClusterBuilder cb;
368     std::vector<uint8> data(10);
369     for (size_t i = 0; i < timestamps.size(); ++i) {
370       std::string timestamp_str = timestamps[i];
371       int block_flags = 0;
372       if (EndsWith(timestamp_str, "K", true)) {
373         block_flags = kWebMFlagKeyframe;
374         // Remove the "K" off of the token.
375         timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1);
376       }
377       int timestamp_in_ms;
378       CHECK(base::StringToInt(timestamp_str, &timestamp_in_ms));
379
380       if (i == 0)
381         cb.SetClusterTimecode(timestamp_in_ms);
382
383       if (track_number == kTextTrackNum) {
384         cb.AddBlockGroup(track_number, timestamp_in_ms, kTextBlockDuration,
385                          block_flags, &data[0], data.size());
386       } else {
387         cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags,
388                           &data[0], data.size());
389       }
390     }
391     AppendCluster(source_id, cb.Finish());
392   }
393
394   void AppendData(const std::string& source_id,
395                   const uint8* data, size_t length) {
396     EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber());
397     demuxer_->AppendData(source_id, data, length);
398   }
399
400   void AppendDataInPieces(const uint8* data, size_t length) {
401     AppendDataInPieces(data, length, 7);
402   }
403
404   void AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) {
405     const uint8* start = data;
406     const uint8* end = data + length;
407     while (start < end) {
408       size_t append_size = std::min(piece_size,
409                                     static_cast<size_t>(end - start));
410       AppendData(start, append_size);
411       start += append_size;
412     }
413   }
414
415   void AppendInitSegment(int stream_flags) {
416     AppendInitSegmentWithSourceId(kSourceId, stream_flags);
417   }
418
419   void AppendInitSegmentWithSourceId(const std::string& source_id,
420                                      int stream_flags) {
421     AppendInitSegmentWithEncryptedInfo(source_id, stream_flags, false, false);
422   }
423
424   void AppendInitSegmentWithEncryptedInfo(const std::string& source_id,
425                                           int stream_flags,
426                                           bool is_audio_encrypted,
427                                           bool is_video_encrypted) {
428     scoped_ptr<uint8[]> info_tracks;
429     int info_tracks_size = 0;
430     CreateInitSegment(stream_flags,
431                       is_audio_encrypted, is_video_encrypted,
432                       &info_tracks, &info_tracks_size);
433     AppendData(source_id, info_tracks.get(), info_tracks_size);
434   }
435
436   void AppendGarbage() {
437     // Fill up an array with gibberish.
438     int garbage_cluster_size = 10;
439     scoped_ptr<uint8[]> garbage_cluster(new uint8[garbage_cluster_size]);
440     for (int i = 0; i < garbage_cluster_size; ++i)
441       garbage_cluster[i] = i;
442     AppendData(garbage_cluster.get(), garbage_cluster_size);
443   }
444
445   void InitDoneCalled(PipelineStatus expected_status,
446                       PipelineStatus status) {
447     EXPECT_EQ(status, expected_status);
448   }
449
450   void AppendEmptyCluster(int timecode) {
451     AppendCluster(GenerateEmptyCluster(timecode));
452   }
453
454   PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration,
455                                     PipelineStatus expected_status) {
456     if (expected_duration != kNoTimestamp())
457       EXPECT_CALL(host_, SetDuration(expected_duration));
458     return CreateInitDoneCB(expected_status);
459   }
460
461   PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) {
462     return base::Bind(&ChunkDemuxerTest::InitDoneCalled,
463                       base::Unretained(this),
464                       expected_status);
465   }
466
467   enum StreamFlags {
468     HAS_AUDIO = 1 << 0,
469     HAS_VIDEO = 1 << 1,
470     HAS_TEXT = 1 << 2
471   };
472
473   bool InitDemuxer(int stream_flags) {
474     return InitDemuxerWithEncryptionInfo(stream_flags, false, false);
475   }
476
477   bool InitDemuxerWithEncryptionInfo(
478       int stream_flags, bool is_audio_encrypted, bool is_video_encrypted) {
479
480     PipelineStatus expected_status =
481         (stream_flags != 0) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN;
482
483     base::TimeDelta expected_duration = kNoTimestamp();
484     if (expected_status == PIPELINE_OK)
485       expected_duration = kDefaultDuration();
486
487     EXPECT_CALL(*this, DemuxerOpened());
488     demuxer_->Initialize(
489         &host_, CreateInitDoneCB(expected_duration, expected_status), true);
490
491     if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk)
492       return false;
493
494     AppendInitSegmentWithEncryptedInfo(
495         kSourceId, stream_flags,
496         is_audio_encrypted, is_video_encrypted);
497     return true;
498   }
499
500   bool InitDemuxerAudioAndVideoSourcesText(const std::string& audio_id,
501                                            const std::string& video_id,
502                                            bool has_text) {
503     EXPECT_CALL(*this, DemuxerOpened());
504     demuxer_->Initialize(
505         &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
506
507     if (AddId(audio_id, HAS_AUDIO) != ChunkDemuxer::kOk)
508       return false;
509     if (AddId(video_id, HAS_VIDEO) != ChunkDemuxer::kOk)
510       return false;
511
512     int audio_flags = HAS_AUDIO;
513     int video_flags = HAS_VIDEO;
514
515     if (has_text) {
516       audio_flags |= HAS_TEXT;
517       video_flags |= HAS_TEXT;
518     }
519
520     AppendInitSegmentWithSourceId(audio_id, audio_flags);
521     AppendInitSegmentWithSourceId(video_id, video_flags);
522     return true;
523   }
524
525   bool InitDemuxerAudioAndVideoSources(const std::string& audio_id,
526                                        const std::string& video_id) {
527     return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false);
528   }
529
530   // Initializes the demuxer with data from 2 files with different
531   // decoder configurations. This is used to test the decoder config change
532   // logic.
533   //
534   // bear-320x240.webm VideoDecoderConfig returns 320x240 for its natural_size()
535   // bear-640x360.webm VideoDecoderConfig returns 640x360 for its natural_size()
536   // The resulting video stream returns data from each file for the following
537   // time ranges.
538   // bear-320x240.webm : [0-501)       [801-2737)
539   // bear-640x360.webm :       [527-793)
540   //
541   // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size()
542   // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size()
543   // The resulting audio stream returns data from each file for the following
544   // time ranges.
545   // bear-320x240.webm : [0-524)       [779-2737)
546   // bear-640x360.webm :       [527-759)
547   bool InitDemuxerWithConfigChangeData() {
548     scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm");
549     scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm");
550
551     EXPECT_CALL(*this, DemuxerOpened());
552     demuxer_->Initialize(
553         &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744),
554                                  PIPELINE_OK), true);
555
556     if (AddId(kSourceId, HAS_AUDIO | HAS_VIDEO) != ChunkDemuxer::kOk)
557       return false;
558
559     // Append the whole bear1 file.
560     AppendData(bear1->data(), bear1->data_size());
561     CheckExpectedRanges(kSourceId, "{ [0,2737) }");
562
563     // Append initialization segment for bear2.
564     // Note: Offsets here and below are derived from
565     // media/test/data/bear-640x360-manifest.js and
566     // media/test/data/bear-320x240-manifest.js which were
567     // generated from media/test/data/bear-640x360.webm and
568     // media/test/data/bear-320x240.webm respectively.
569     AppendData(bear2->data(), 4340);
570
571     // Append a media segment that goes from [0.527000, 1.014000).
572     AppendData(bear2->data() + 55290, 18785);
573     CheckExpectedRanges(kSourceId, "{ [0,1028) [1201,2737) }");
574
575     // Append initialization segment for bear1 & fill gap with [779-1197)
576     // segment.
577     AppendData(bear1->data(), 4370);
578     AppendData(bear1->data() + 72737, 28183);
579     CheckExpectedRanges(kSourceId, "{ [0,2737) }");
580
581     MarkEndOfStream(PIPELINE_OK);
582     return true;
583   }
584
585   void ShutdownDemuxer() {
586     if (demuxer_) {
587       demuxer_->Shutdown();
588       message_loop_.RunUntilIdle();
589     }
590   }
591
592   void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) {
593     uint8 data[] = { 0x00 };
594     cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
595   }
596
597   scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) {
598     return GenerateCluster(timecode, timecode, block_count);
599   }
600
601   void AddVideoBlockGroup(ClusterBuilder* cb, int track_num, int64 timecode,
602                           int duration, int flags) {
603     const uint8* data =
604         (flags & kWebMFlagKeyframe) != 0 ? kVP8Keyframe : kVP8Interframe;
605     int size = (flags & kWebMFlagKeyframe) != 0 ? sizeof(kVP8Keyframe) :
606         sizeof(kVP8Interframe);
607     cb->AddBlockGroup(track_num, timecode, duration, flags, data, size);
608   }
609
610   scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode,
611                                       int first_video_timecode,
612                                       int block_count) {
613     CHECK_GT(block_count, 0);
614
615     int size = 10;
616     scoped_ptr<uint8[]> data(new uint8[size]);
617
618     ClusterBuilder cb;
619     cb.SetClusterTimecode(std::min(first_audio_timecode, first_video_timecode));
620
621     if (block_count == 1) {
622       cb.AddBlockGroup(kAudioTrackNum, first_audio_timecode,
623                        kAudioBlockDuration, kWebMFlagKeyframe,
624                        data.get(), size);
625       return cb.Finish();
626     }
627
628     int audio_timecode = first_audio_timecode;
629     int video_timecode = first_video_timecode;
630
631     // Create simple blocks for everything except the last 2 blocks.
632     // The first video frame must be a keyframe.
633     uint8 video_flag = kWebMFlagKeyframe;
634     for (int i = 0; i < block_count - 2; i++) {
635       if (audio_timecode <= video_timecode) {
636         cb.AddSimpleBlock(kAudioTrackNum, audio_timecode, kWebMFlagKeyframe,
637                           data.get(), size);
638         audio_timecode += kAudioBlockDuration;
639         continue;
640       }
641
642       cb.AddSimpleBlock(kVideoTrackNum, video_timecode, video_flag, data.get(),
643                         size);
644       video_timecode += kVideoBlockDuration;
645       video_flag = 0;
646     }
647
648     // Make the last 2 blocks BlockGroups so that they don't get delayed by the
649     // block duration calculation logic.
650     if (audio_timecode <= video_timecode) {
651       cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration,
652                        kWebMFlagKeyframe, data.get(), size);
653       AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode,
654                          kVideoBlockDuration, video_flag);
655     } else {
656       AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode,
657                          kVideoBlockDuration, video_flag);
658       cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration,
659                        kWebMFlagKeyframe, data.get(), size);
660     }
661
662     return cb.Finish();
663   }
664
665   scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode,
666                                                   int end_timecode,
667                                                   int track_number,
668                                                   int block_duration) {
669     CHECK_GT(end_timecode, timecode);
670
671     std::vector<uint8> data(kBlockSize);
672
673     ClusterBuilder cb;
674     cb.SetClusterTimecode(timecode);
675
676     // Create simple blocks for everything except the last block.
677     for (int i = 0; timecode < (end_timecode - block_duration); i++) {
678       cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe,
679                         &data[0], data.size());
680       timecode += block_duration;
681     }
682
683     // Make the last block a BlockGroup so that it doesn't get delayed by the
684     // block duration calculation logic.
685     if (track_number == kVideoTrackNum) {
686       AddVideoBlockGroup(&cb, track_number, timecode, block_duration,
687                          kWebMFlagKeyframe);
688     } else {
689       cb.AddBlockGroup(track_number, timecode, block_duration,
690                        kWebMFlagKeyframe, &data[0], data.size());
691     }
692     return cb.Finish();
693   }
694
695   void Read(DemuxerStream::Type type, const DemuxerStream::ReadCB& read_cb) {
696     demuxer_->GetStream(type)->Read(read_cb);
697     message_loop_.RunUntilIdle();
698   }
699
700   void ReadAudio(const DemuxerStream::ReadCB& read_cb) {
701     Read(DemuxerStream::AUDIO, read_cb);
702   }
703
704   void ReadVideo(const DemuxerStream::ReadCB& read_cb) {
705     Read(DemuxerStream::VIDEO, read_cb);
706   }
707
708   void GenerateExpectedReads(int timecode, int block_count) {
709     GenerateExpectedReads(timecode, timecode, block_count);
710   }
711
712   void GenerateExpectedReads(int start_audio_timecode,
713                              int start_video_timecode,
714                              int block_count) {
715     CHECK_GT(block_count, 0);
716
717     if (block_count == 1) {
718       ExpectRead(DemuxerStream::AUDIO, start_audio_timecode);
719       return;
720     }
721
722     int audio_timecode = start_audio_timecode;
723     int video_timecode = start_video_timecode;
724
725     for (int i = 0; i < block_count; i++) {
726       if (audio_timecode <= video_timecode) {
727         ExpectRead(DemuxerStream::AUDIO, audio_timecode);
728         audio_timecode += kAudioBlockDuration;
729         continue;
730       }
731
732       ExpectRead(DemuxerStream::VIDEO, video_timecode);
733       video_timecode += kVideoBlockDuration;
734     }
735   }
736
737   void GenerateSingleStreamExpectedReads(int timecode,
738                                          int block_count,
739                                          DemuxerStream::Type type,
740                                          int block_duration) {
741     CHECK_GT(block_count, 0);
742     int stream_timecode = timecode;
743
744     for (int i = 0; i < block_count; i++) {
745       ExpectRead(type, stream_timecode);
746       stream_timecode += block_duration;
747     }
748   }
749
750   void GenerateAudioStreamExpectedReads(int timecode, int block_count) {
751     GenerateSingleStreamExpectedReads(
752         timecode, block_count, DemuxerStream::AUDIO, kAudioBlockDuration);
753   }
754
755   void GenerateVideoStreamExpectedReads(int timecode, int block_count) {
756     GenerateSingleStreamExpectedReads(
757         timecode, block_count, DemuxerStream::VIDEO, kVideoBlockDuration);
758   }
759
760   scoped_ptr<Cluster> GenerateEmptyCluster(int timecode) {
761     ClusterBuilder cb;
762     cb.SetClusterTimecode(timecode);
763     return cb.Finish();
764   }
765
766   void CheckExpectedRanges(const std::string& expected) {
767     CheckExpectedRanges(kSourceId, expected);
768   }
769
770   void CheckExpectedRanges(const std::string&  id,
771                            const std::string& expected) {
772     Ranges<base::TimeDelta> r = demuxer_->GetBufferedRanges(id);
773
774     std::stringstream ss;
775     ss << "{ ";
776     for (size_t i = 0; i < r.size(); ++i) {
777       ss << "[" << r.start(i).InMilliseconds() << ","
778          << r.end(i).InMilliseconds() << ") ";
779     }
780     ss << "}";
781     EXPECT_EQ(expected, ss.str());
782   }
783
784   MOCK_METHOD2(ReadDone, void(DemuxerStream::Status status,
785                               const scoped_refptr<DecoderBuffer>&));
786
787   void StoreStatusAndBuffer(DemuxerStream::Status* status_out,
788                             scoped_refptr<DecoderBuffer>* buffer_out,
789                             DemuxerStream::Status status,
790                             const scoped_refptr<DecoderBuffer>& buffer) {
791     *status_out = status;
792     *buffer_out = buffer;
793   }
794
795   void ReadUntilNotOkOrEndOfStream(DemuxerStream::Type type,
796                                    DemuxerStream::Status* status,
797                                    base::TimeDelta* last_timestamp) {
798     DemuxerStream* stream = demuxer_->GetStream(type);
799     scoped_refptr<DecoderBuffer> buffer;
800
801     *last_timestamp = kNoTimestamp();
802     do {
803       stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
804                               base::Unretained(this), status, &buffer));
805       base::MessageLoop::current()->RunUntilIdle();
806       if (*status == DemuxerStream::kOk && !buffer->end_of_stream())
807         *last_timestamp = buffer->timestamp();
808     } while (*status == DemuxerStream::kOk && !buffer->end_of_stream());
809   }
810
811   void ExpectEndOfStream(DemuxerStream::Type type) {
812     EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, IsEndOfStream()));
813     demuxer_->GetStream(type)->Read(base::Bind(
814         &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
815     message_loop_.RunUntilIdle();
816   }
817
818   void ExpectRead(DemuxerStream::Type type, int64 timestamp_in_ms) {
819     EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
820                                 HasTimestamp(timestamp_in_ms)));
821     demuxer_->GetStream(type)->Read(base::Bind(
822         &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
823     message_loop_.RunUntilIdle();
824   }
825
826   void ExpectConfigChanged(DemuxerStream::Type type) {
827     EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
828     demuxer_->GetStream(type)->Read(base::Bind(
829         &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
830     message_loop_.RunUntilIdle();
831   }
832
833   void CheckExpectedBuffers(DemuxerStream* stream,
834                             const std::string& expected) {
835     std::vector<std::string> timestamps;
836     base::SplitString(expected, ' ', &timestamps);
837     std::stringstream ss;
838     for (size_t i = 0; i < timestamps.size(); ++i) {
839       DemuxerStream::Status status;
840       scoped_refptr<DecoderBuffer> buffer;
841       stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
842                               base::Unretained(this), &status, &buffer));
843       base::MessageLoop::current()->RunUntilIdle();
844       if (status != DemuxerStream::kOk || buffer->end_of_stream())
845         break;
846
847       if (i > 0)
848         ss << " ";
849       ss << buffer->timestamp().InMilliseconds();
850     }
851     EXPECT_EQ(expected, ss.str());
852   }
853
854   MOCK_METHOD1(Checkpoint, void(int id));
855
856   struct BufferTimestamps {
857     int video_time_ms;
858     int audio_time_ms;
859   };
860   static const int kSkip = -1;
861
862   // Test parsing a WebM file.
863   // |filename| - The name of the file in media/test/data to parse.
864   // |timestamps| - The expected timestamps on the parsed buffers.
865   //    a timestamp of kSkip indicates that a Read() call for that stream
866   //    shouldn't be made on that iteration of the loop. If both streams have
867   //    a kSkip then the loop will terminate.
868   bool ParseWebMFile(const std::string& filename,
869                      const BufferTimestamps* timestamps,
870                      const base::TimeDelta& duration) {
871     return ParseWebMFile(filename, timestamps, duration, HAS_AUDIO | HAS_VIDEO);
872   }
873
874   bool ParseWebMFile(const std::string& filename,
875                      const BufferTimestamps* timestamps,
876                      const base::TimeDelta& duration,
877                      int stream_flags) {
878     EXPECT_CALL(*this, DemuxerOpened());
879     demuxer_->Initialize(
880         &host_, CreateInitDoneCB(duration, PIPELINE_OK), true);
881
882     if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk)
883       return false;
884
885     // Read a WebM file into memory and send the data to the demuxer.
886     scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
887     AppendDataInPieces(buffer->data(), buffer->data_size(), 512);
888
889     // Verify that the timestamps on the first few packets match what we
890     // expect.
891     for (size_t i = 0;
892          (timestamps[i].audio_time_ms != kSkip ||
893           timestamps[i].video_time_ms != kSkip);
894          i++) {
895       bool audio_read_done = false;
896       bool video_read_done = false;
897
898       if (timestamps[i].audio_time_ms != kSkip) {
899         ReadAudio(base::Bind(&OnReadDone,
900                              base::TimeDelta::FromMilliseconds(
901                                  timestamps[i].audio_time_ms),
902                              &audio_read_done));
903         EXPECT_TRUE(audio_read_done);
904       }
905
906       if (timestamps[i].video_time_ms != kSkip) {
907         ReadVideo(base::Bind(&OnReadDone,
908                              base::TimeDelta::FromMilliseconds(
909                                  timestamps[i].video_time_ms),
910                              &video_read_done));
911         EXPECT_TRUE(video_read_done);
912       }
913     }
914
915     return true;
916   }
917
918   MOCK_METHOD0(DemuxerOpened, void());
919   // TODO(xhwang): This is a workaround of the issue that move-only parameters
920   // are not supported in mocked methods. Remove this when the issue is fixed
921   // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use
922   // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689).
923   MOCK_METHOD3(NeedKeyMock, void(const std::string& type,
924                                  const uint8* init_data, int init_data_size));
925   void DemuxerNeedKey(const std::string& type,
926                       const std::vector<uint8>& init_data) {
927     const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
928     NeedKeyMock(type, init_data_ptr, init_data.size());
929   }
930
931   void Seek(base::TimeDelta seek_time) {
932     demuxer_->StartWaitingForSeek(seek_time);
933     demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
934     message_loop_.RunUntilIdle();
935   }
936
937   void MarkEndOfStream(PipelineStatus status) {
938     demuxer_->MarkEndOfStream(status);
939     message_loop_.RunUntilIdle();
940   }
941
942   base::MessageLoop message_loop_;
943   MockDemuxerHost host_;
944
945   scoped_ptr<ChunkDemuxer> demuxer_;
946
947  private:
948   DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest);
949 };
950
951 TEST_F(ChunkDemuxerTest, Init) {
952   // Test no streams, audio-only, video-only, and audio & video scenarios.
953   // Audio and video streams can be encrypted or not encrypted.
954   for (int i = 0; i < 16; i++) {
955     bool has_audio = (i & 0x1) != 0;
956     bool has_video = (i & 0x2) != 0;
957     bool is_audio_encrypted = (i & 0x4) != 0;
958     bool is_video_encrypted = (i & 0x8) != 0;
959
960     // No test on invalid combination.
961     if ((!has_audio && is_audio_encrypted) ||
962         (!has_video && is_video_encrypted)) {
963       continue;
964     }
965
966     CreateNewDemuxer();
967
968     if (is_audio_encrypted || is_video_encrypted) {
969       int need_key_count = (is_audio_encrypted ? 1 : 0) +
970                            (is_video_encrypted ? 1 : 0);
971       EXPECT_CALL(*this, NeedKeyMock(kWebMEncryptInitDataType, NotNull(),
972                                      DecryptConfig::kDecryptionKeySize))
973           .Times(Exactly(need_key_count));
974     }
975
976     int stream_flags = 0;
977     if (has_audio)
978       stream_flags |= HAS_AUDIO;
979
980     if (has_video)
981       stream_flags |= HAS_VIDEO;
982
983     ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
984         stream_flags, is_audio_encrypted, is_video_encrypted));
985
986     DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
987     if (has_audio) {
988       ASSERT_TRUE(audio_stream);
989
990       const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
991       EXPECT_EQ(kCodecVorbis, config.codec());
992       EXPECT_EQ(32, config.bits_per_channel());
993       EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout());
994       EXPECT_EQ(44100, config.samples_per_second());
995       EXPECT_TRUE(config.extra_data());
996       EXPECT_GT(config.extra_data_size(), 0u);
997       EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
998       EXPECT_EQ(is_audio_encrypted,
999                 audio_stream->audio_decoder_config().is_encrypted());
1000     } else {
1001       EXPECT_FALSE(audio_stream);
1002     }
1003
1004     DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
1005     if (has_video) {
1006       EXPECT_TRUE(video_stream);
1007       EXPECT_EQ(is_video_encrypted,
1008                 video_stream->video_decoder_config().is_encrypted());
1009     } else {
1010       EXPECT_FALSE(video_stream);
1011     }
1012
1013     ShutdownDemuxer();
1014     demuxer_.reset();
1015   }
1016 }
1017
1018 // TODO(acolwell): Fold this test into Init tests since the tests are
1019 // almost identical.
1020 TEST_F(ChunkDemuxerTest, InitText) {
1021   // Test with 1 video stream and 1 text streams, and 0 or 1 audio streams.
1022   // No encryption cases handled here.
1023   bool has_video = true;
1024   bool is_audio_encrypted = false;
1025   bool is_video_encrypted = false;
1026   for (int i = 0; i < 2; i++) {
1027     bool has_audio = (i & 0x1) != 0;
1028
1029     CreateNewDemuxer();
1030
1031     DemuxerStream* text_stream = NULL;
1032     TextTrackConfig text_config;
1033     EXPECT_CALL(host_, AddTextStream(_, _))
1034         .WillOnce(DoAll(SaveArg<0>(&text_stream),
1035                         SaveArg<1>(&text_config)));
1036
1037     int stream_flags = HAS_TEXT;
1038     if (has_audio)
1039       stream_flags |= HAS_AUDIO;
1040
1041     if (has_video)
1042       stream_flags |= HAS_VIDEO;
1043
1044     ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
1045         stream_flags, is_audio_encrypted, is_video_encrypted));
1046     ASSERT_TRUE(text_stream);
1047     EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
1048     EXPECT_EQ(kTextSubtitles, text_config.kind());
1049
1050     DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
1051     if (has_audio) {
1052       ASSERT_TRUE(audio_stream);
1053
1054       const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
1055       EXPECT_EQ(kCodecVorbis, config.codec());
1056       EXPECT_EQ(32, config.bits_per_channel());
1057       EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout());
1058       EXPECT_EQ(44100, config.samples_per_second());
1059       EXPECT_TRUE(config.extra_data());
1060       EXPECT_GT(config.extra_data_size(), 0u);
1061       EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
1062       EXPECT_EQ(is_audio_encrypted,
1063                 audio_stream->audio_decoder_config().is_encrypted());
1064     } else {
1065       EXPECT_FALSE(audio_stream);
1066     }
1067
1068     DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
1069     if (has_video) {
1070       EXPECT_TRUE(video_stream);
1071       EXPECT_EQ(is_video_encrypted,
1072                 video_stream->video_decoder_config().is_encrypted());
1073     } else {
1074       EXPECT_FALSE(video_stream);
1075     }
1076
1077     ShutdownDemuxer();
1078     demuxer_.reset();
1079   }
1080 }
1081
1082 // Make sure that the demuxer reports an error if Shutdown()
1083 // is called before all the initialization segments are appended.
1084 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) {
1085   EXPECT_CALL(*this, DemuxerOpened());
1086   demuxer_->Initialize(
1087       &host_, CreateInitDoneCB(
1088           kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
1089
1090   EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
1091   EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk);
1092
1093   AppendInitSegmentWithSourceId("audio", HAS_AUDIO);
1094
1095   ShutdownDemuxer();
1096 }
1097
1098 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) {
1099   EXPECT_CALL(*this, DemuxerOpened());
1100   demuxer_->Initialize(
1101       &host_, CreateInitDoneCB(
1102           kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
1103
1104   EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
1105   EXPECT_EQ(AddId("video_and_text", HAS_VIDEO), ChunkDemuxer::kOk);
1106
1107   EXPECT_CALL(host_, AddTextStream(_, _))
1108       .Times(Exactly(1));
1109
1110   AppendInitSegmentWithSourceId("video_and_text", HAS_VIDEO | HAS_TEXT);
1111
1112   ShutdownDemuxer();
1113 }
1114
1115 // Verifies that all streams waiting for data receive an end of stream
1116 // buffer when Shutdown() is called.
1117 TEST_F(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) {
1118   DemuxerStream* text_stream = NULL;
1119   EXPECT_CALL(host_, AddTextStream(_, _))
1120       .WillOnce(SaveArg<0>(&text_stream));
1121   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
1122
1123   DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
1124   DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
1125
1126   bool audio_read_done = false;
1127   bool video_read_done = false;
1128   bool text_read_done = false;
1129   audio_stream->Read(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
1130   video_stream->Read(base::Bind(&OnReadDone_EOSExpected, &video_read_done));
1131   text_stream->Read(base::Bind(&OnReadDone_EOSExpected, &text_read_done));
1132   message_loop_.RunUntilIdle();
1133
1134   EXPECT_FALSE(audio_read_done);
1135   EXPECT_FALSE(video_read_done);
1136   EXPECT_FALSE(text_read_done);
1137
1138   ShutdownDemuxer();
1139
1140   EXPECT_TRUE(audio_read_done);
1141   EXPECT_TRUE(video_read_done);
1142   EXPECT_TRUE(text_read_done);
1143 }
1144
1145 // Test that Seek() completes successfully when the first cluster
1146 // arrives.
1147 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) {
1148   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1149   AppendCluster(kDefaultFirstCluster());
1150
1151   InSequence s;
1152
1153   EXPECT_CALL(*this, Checkpoint(1));
1154
1155   Seek(base::TimeDelta::FromMilliseconds(46));
1156
1157   EXPECT_CALL(*this, Checkpoint(2));
1158
1159   Checkpoint(1);
1160
1161   AppendCluster(kDefaultSecondCluster());
1162
1163   message_loop_.RunUntilIdle();
1164
1165   Checkpoint(2);
1166 }
1167
1168 // Test that parsing errors are handled for clusters appended after init.
1169 TEST_F(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) {
1170   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1171   AppendCluster(kDefaultFirstCluster());
1172
1173   EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1174   AppendGarbage();
1175 }
1176
1177 // Test the case where a Seek() is requested while the parser
1178 // is in the middle of cluster. This is to verify that the parser
1179 // does not reset itself on a seek.
1180 TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) {
1181   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1182
1183   InSequence s;
1184
1185   scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 6));
1186
1187   // Split the cluster into two appends at an arbitrary point near the end.
1188   int first_append_size = cluster_a->size() - 11;
1189   int second_append_size = cluster_a->size() - first_append_size;
1190
1191   // Append the first part of the cluster.
1192   AppendData(cluster_a->data(), first_append_size);
1193
1194   ExpectRead(DemuxerStream::AUDIO, 0);
1195   ExpectRead(DemuxerStream::VIDEO, 0);
1196   ExpectRead(DemuxerStream::AUDIO, kAudioBlockDuration);
1197   // Note: We skip trying to read a video buffer here because computing
1198   // the duration for this block relies on successfully parsing the last block
1199   // in the cluster the cluster.
1200   ExpectRead(DemuxerStream::AUDIO, 2 * kAudioBlockDuration);
1201
1202   Seek(base::TimeDelta::FromSeconds(5));
1203
1204   // Append the rest of the cluster.
1205   AppendData(cluster_a->data() + first_append_size, second_append_size);
1206
1207   // Append the new cluster and verify that only the blocks
1208   // in the new cluster are returned.
1209   AppendCluster(GenerateCluster(5000, 6));
1210   GenerateExpectedReads(5000, 6);
1211 }
1212
1213 // Test the case where AppendData() is called before Init().
1214 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) {
1215   scoped_ptr<uint8[]> info_tracks;
1216   int info_tracks_size = 0;
1217   CreateInitSegment(HAS_AUDIO | HAS_VIDEO,
1218                     false, false, &info_tracks, &info_tracks_size);
1219
1220   demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size);
1221 }
1222
1223 // Make sure Read() callbacks are dispatched with the proper data.
1224 TEST_F(ChunkDemuxerTest, Read) {
1225   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1226
1227   AppendCluster(kDefaultFirstCluster());
1228
1229   bool audio_read_done = false;
1230   bool video_read_done = false;
1231   ReadAudio(base::Bind(&OnReadDone,
1232                        base::TimeDelta::FromMilliseconds(0),
1233                        &audio_read_done));
1234   ReadVideo(base::Bind(&OnReadDone,
1235                        base::TimeDelta::FromMilliseconds(0),
1236                        &video_read_done));
1237
1238   EXPECT_TRUE(audio_read_done);
1239   EXPECT_TRUE(video_read_done);
1240 }
1241
1242 TEST_F(ChunkDemuxerTest, OutOfOrderClusters) {
1243   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1244   AppendCluster(kDefaultFirstCluster());
1245   AppendCluster(GenerateCluster(10, 4));
1246
1247   // Make sure that AppendCluster() does not fail with a cluster that has
1248   // overlaps with the previously appended cluster.
1249   AppendCluster(GenerateCluster(5, 4));
1250
1251   // Verify that AppendData() can still accept more data.
1252   scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2));
1253   demuxer_->AppendData(kSourceId, cluster_c->data(), cluster_c->size());
1254 }
1255
1256 TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) {
1257   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1258   AppendCluster(kDefaultFirstCluster());
1259
1260   ClusterBuilder cb;
1261
1262   // Test the case where block timecodes are not monotonically
1263   // increasing but stay above the cluster timecode.
1264   cb.SetClusterTimecode(5);
1265   AddSimpleBlock(&cb, kAudioTrackNum, 5);
1266   AddSimpleBlock(&cb, kVideoTrackNum, 10);
1267   AddSimpleBlock(&cb, kAudioTrackNum, 7);
1268   AddSimpleBlock(&cb, kVideoTrackNum, 15);
1269
1270   EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1271   AppendCluster(cb.Finish());
1272
1273   // Verify that AppendData() ignores data after the error.
1274   scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2));
1275   demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size());
1276 }
1277
1278 TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) {
1279   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1280   AppendCluster(kDefaultFirstCluster());
1281
1282   ClusterBuilder cb;
1283
1284   // Test timecodes going backwards and including values less than the cluster
1285   // timecode.
1286   cb.SetClusterTimecode(5);
1287   AddSimpleBlock(&cb, kAudioTrackNum, 5);
1288   AddSimpleBlock(&cb, kVideoTrackNum, 5);
1289   AddSimpleBlock(&cb, kAudioTrackNum, 3);
1290   AddSimpleBlock(&cb, kVideoTrackNum, 3);
1291
1292   EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1293   AppendCluster(cb.Finish());
1294
1295   // Verify that AppendData() ignores data after the error.
1296   scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2));
1297   demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size());
1298 }
1299
1300
1301 TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) {
1302   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1303   AppendCluster(kDefaultFirstCluster());
1304
1305   ClusterBuilder cb;
1306
1307   // Test monotonic increasing timestamps on a per stream
1308   // basis.
1309   cb.SetClusterTimecode(5);
1310   AddSimpleBlock(&cb, kAudioTrackNum, 5);
1311   AddSimpleBlock(&cb, kVideoTrackNum, 5);
1312   AddSimpleBlock(&cb, kAudioTrackNum, 4);
1313   AddSimpleBlock(&cb, kVideoTrackNum, 7);
1314
1315   EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1316   AppendCluster(cb.Finish());
1317 }
1318
1319 // Test the case where a cluster is passed to AppendCluster() before
1320 // INFO & TRACKS data.
1321 TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) {
1322   EXPECT_CALL(*this, DemuxerOpened());
1323   demuxer_->Initialize(
1324       &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
1325
1326   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
1327
1328   AppendCluster(GenerateCluster(0, 1));
1329 }
1330
1331 // Test cases where we get an MarkEndOfStream() call during initialization.
1332 TEST_F(ChunkDemuxerTest, EOSDuringInit) {
1333   EXPECT_CALL(*this, DemuxerOpened());
1334   demuxer_->Initialize(
1335       &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
1336   MarkEndOfStream(PIPELINE_OK);
1337 }
1338
1339 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) {
1340   EXPECT_CALL(*this, DemuxerOpened());
1341   demuxer_->Initialize(
1342       &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
1343
1344   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
1345
1346   CheckExpectedRanges("{ }");
1347   MarkEndOfStream(PIPELINE_OK);
1348   ShutdownDemuxer();
1349   CheckExpectedRanges("{ }");
1350   demuxer_->RemoveId(kSourceId);
1351   demuxer_.reset();
1352 }
1353
1354 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoMediaAppend) {
1355   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1356
1357   CheckExpectedRanges("{ }");
1358   MarkEndOfStream(PIPELINE_OK);
1359   CheckExpectedRanges("{ }");
1360 }
1361
1362 TEST_F(ChunkDemuxerTest, DecodeErrorEndOfStream) {
1363   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1364
1365   AppendCluster(kDefaultFirstCluster());
1366   CheckExpectedRanges(kDefaultFirstClusterRange);
1367
1368   EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1369   MarkEndOfStream(PIPELINE_ERROR_DECODE);
1370   CheckExpectedRanges(kDefaultFirstClusterRange);
1371 }
1372
1373 TEST_F(ChunkDemuxerTest, NetworkErrorEndOfStream) {
1374   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1375
1376   AppendCluster(kDefaultFirstCluster());
1377   CheckExpectedRanges(kDefaultFirstClusterRange);
1378
1379   EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK));
1380   MarkEndOfStream(PIPELINE_ERROR_NETWORK);
1381 }
1382
1383 // Helper class to reduce duplicate code when testing end of stream
1384 // Read() behavior.
1385 class EndOfStreamHelper {
1386  public:
1387   explicit EndOfStreamHelper(Demuxer* demuxer)
1388       : demuxer_(demuxer),
1389         audio_read_done_(false),
1390         video_read_done_(false) {
1391   }
1392
1393   // Request a read on the audio and video streams.
1394   void RequestReads() {
1395     EXPECT_FALSE(audio_read_done_);
1396     EXPECT_FALSE(video_read_done_);
1397
1398     DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
1399     DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
1400
1401     audio->Read(base::Bind(&OnEndOfStreamReadDone, &audio_read_done_));
1402     video->Read(base::Bind(&OnEndOfStreamReadDone, &video_read_done_));
1403     base::MessageLoop::current()->RunUntilIdle();
1404   }
1405
1406   // Check to see if |audio_read_done_| and |video_read_done_| variables
1407   // match |expected|.
1408   void CheckIfReadDonesWereCalled(bool expected) {
1409     base::MessageLoop::current()->RunUntilIdle();
1410     EXPECT_EQ(expected, audio_read_done_);
1411     EXPECT_EQ(expected, video_read_done_);
1412   }
1413
1414  private:
1415   static void OnEndOfStreamReadDone(
1416       bool* called,
1417       DemuxerStream::Status status,
1418       const scoped_refptr<DecoderBuffer>& buffer) {
1419     EXPECT_EQ(status, DemuxerStream::kOk);
1420     EXPECT_TRUE(buffer->end_of_stream());
1421     *called = true;
1422   }
1423
1424   Demuxer* demuxer_;
1425   bool audio_read_done_;
1426   bool video_read_done_;
1427
1428   DISALLOW_COPY_AND_ASSIGN(EndOfStreamHelper);
1429 };
1430
1431 // Make sure that all pending reads that we don't have media data for get an
1432 // "end of stream" buffer when MarkEndOfStream() is called.
1433 TEST_F(ChunkDemuxerTest, EndOfStreamWithPendingReads) {
1434   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1435
1436   AppendCluster(GenerateCluster(0, 2));
1437
1438   bool audio_read_done_1 = false;
1439   bool video_read_done_1 = false;
1440   EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
1441   EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
1442
1443   ReadAudio(base::Bind(&OnReadDone,
1444                        base::TimeDelta::FromMilliseconds(0),
1445                        &audio_read_done_1));
1446   ReadVideo(base::Bind(&OnReadDone,
1447                        base::TimeDelta::FromMilliseconds(0),
1448                        &video_read_done_1));
1449   message_loop_.RunUntilIdle();
1450
1451   EXPECT_TRUE(audio_read_done_1);
1452   EXPECT_TRUE(video_read_done_1);
1453
1454   end_of_stream_helper_1.RequestReads();
1455
1456   EXPECT_CALL(host_, SetDuration(
1457       base::TimeDelta::FromMilliseconds(kVideoBlockDuration)));
1458   MarkEndOfStream(PIPELINE_OK);
1459
1460   end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
1461
1462   end_of_stream_helper_2.RequestReads();
1463   end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
1464 }
1465
1466 // Make sure that all Read() calls after we get an MarkEndOfStream()
1467 // call return an "end of stream" buffer.
1468 TEST_F(ChunkDemuxerTest, ReadsAfterEndOfStream) {
1469   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1470
1471   AppendCluster(GenerateCluster(0, 2));
1472
1473   bool audio_read_done_1 = false;
1474   bool video_read_done_1 = false;
1475   EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
1476   EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
1477   EndOfStreamHelper end_of_stream_helper_3(demuxer_.get());
1478
1479   ReadAudio(base::Bind(&OnReadDone,
1480                        base::TimeDelta::FromMilliseconds(0),
1481                        &audio_read_done_1));
1482   ReadVideo(base::Bind(&OnReadDone,
1483                        base::TimeDelta::FromMilliseconds(0),
1484                        &video_read_done_1));
1485
1486   end_of_stream_helper_1.RequestReads();
1487
1488   EXPECT_TRUE(audio_read_done_1);
1489   EXPECT_TRUE(video_read_done_1);
1490   end_of_stream_helper_1.CheckIfReadDonesWereCalled(false);
1491
1492   EXPECT_CALL(host_, SetDuration(
1493       base::TimeDelta::FromMilliseconds(kVideoBlockDuration)));
1494   MarkEndOfStream(PIPELINE_OK);
1495
1496   end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
1497
1498   // Request a few more reads and make sure we immediately get
1499   // end of stream buffers.
1500   end_of_stream_helper_2.RequestReads();
1501   end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
1502
1503   end_of_stream_helper_3.RequestReads();
1504   end_of_stream_helper_3.CheckIfReadDonesWereCalled(true);
1505 }
1506
1507 TEST_F(ChunkDemuxerTest, EndOfStreamDuringCanceledSeek) {
1508   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1509
1510   AppendCluster(0, 10);
1511   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(138)));
1512   MarkEndOfStream(PIPELINE_OK);
1513
1514   // Start the first seek.
1515   Seek(base::TimeDelta::FromMilliseconds(20));
1516
1517   // Simulate another seek being requested before the first
1518   // seek has finished prerolling.
1519   base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(30);
1520   demuxer_->CancelPendingSeek(seek_time2);
1521
1522   // Finish second seek.
1523   Seek(seek_time2);
1524
1525   DemuxerStream::Status status;
1526   base::TimeDelta last_timestamp;
1527
1528   // Make sure audio can reach end of stream.
1529   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
1530   ASSERT_EQ(status, DemuxerStream::kOk);
1531
1532   // Make sure video can reach end of stream.
1533   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
1534   ASSERT_EQ(status, DemuxerStream::kOk);
1535 }
1536
1537 // Verify buffered range change behavior for audio/video/text tracks.
1538 TEST_F(ChunkDemuxerTest, EndOfStreamRangeChanges) {
1539   DemuxerStream* text_stream = NULL;
1540
1541   EXPECT_CALL(host_, AddTextStream(_, _))
1542       .WillOnce(SaveArg<0>(&text_stream));
1543   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
1544
1545   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 30");
1546   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23K");
1547
1548   // Check expected ranges and verify that an empty text track does not
1549   // affect the expected ranges.
1550   CheckExpectedRanges(kSourceId, "{ [0,46) }");
1551
1552   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(60)));
1553   MarkEndOfStream(PIPELINE_OK);
1554
1555   // Check expected ranges and verify that an empty text track does not
1556   // affect the expected ranges.
1557   CheckExpectedRanges(kSourceId, "{ [0,60) }");
1558
1559   // Unmark end of stream state and verify that the ranges return to
1560   // their pre-"end of stream" values.
1561   demuxer_->UnmarkEndOfStream();
1562   CheckExpectedRanges(kSourceId, "{ [0,46) }");
1563
1564   // Add text track data and verify that the buffered ranges don't change
1565   // since the intersection of all the tracks doesn't change.
1566   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(200)));
1567   AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K");
1568   CheckExpectedRanges(kSourceId, "{ [0,46) }");
1569
1570   // Mark end of stream and verify that text track data is reflected in
1571   // the new range.
1572   MarkEndOfStream(PIPELINE_OK);
1573   CheckExpectedRanges(kSourceId, "{ [0,200) }");
1574 }
1575
1576 // Make sure AppendData() will accept elements that span multiple calls.
1577 TEST_F(ChunkDemuxerTest, AppendingInPieces) {
1578   EXPECT_CALL(*this, DemuxerOpened());
1579   demuxer_->Initialize(
1580       &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
1581
1582   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
1583
1584   scoped_ptr<uint8[]> info_tracks;
1585   int info_tracks_size = 0;
1586   CreateInitSegment(HAS_AUDIO | HAS_VIDEO,
1587                     false, false, &info_tracks, &info_tracks_size);
1588
1589   scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster());
1590   scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster());
1591
1592   size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size();
1593   scoped_ptr<uint8[]> buffer(new uint8[buffer_size]);
1594   uint8* dst = buffer.get();
1595   memcpy(dst, info_tracks.get(), info_tracks_size);
1596   dst += info_tracks_size;
1597
1598   memcpy(dst, cluster_a->data(), cluster_a->size());
1599   dst += cluster_a->size();
1600
1601   memcpy(dst, cluster_b->data(), cluster_b->size());
1602   dst += cluster_b->size();
1603
1604   AppendDataInPieces(buffer.get(), buffer_size);
1605
1606   GenerateExpectedReads(0, 9);
1607 }
1608
1609 TEST_F(ChunkDemuxerTest, WebMFile_AudioAndVideo) {
1610   struct BufferTimestamps buffer_timestamps[] = {
1611     {0, 0},
1612     {33, 3},
1613     {67, 6},
1614     {100, 9},
1615     {133, 12},
1616     {kSkip, kSkip},
1617   };
1618
1619   ASSERT_TRUE(ParseWebMFile("bear-320x240.webm", buffer_timestamps,
1620                             base::TimeDelta::FromMilliseconds(2744)));
1621 }
1622
1623 TEST_F(ChunkDemuxerTest, WebMFile_LiveAudioAndVideo) {
1624   struct BufferTimestamps buffer_timestamps[] = {
1625     {0, 0},
1626     {33, 3},
1627     {67, 6},
1628     {100, 9},
1629     {133, 12},
1630     {kSkip, kSkip},
1631   };
1632
1633   ASSERT_TRUE(ParseWebMFile("bear-320x240-live.webm", buffer_timestamps,
1634                             kInfiniteDuration()));
1635 }
1636
1637 TEST_F(ChunkDemuxerTest, WebMFile_AudioOnly) {
1638   struct BufferTimestamps buffer_timestamps[] = {
1639     {kSkip, 0},
1640     {kSkip, 3},
1641     {kSkip, 6},
1642     {kSkip, 9},
1643     {kSkip, 12},
1644     {kSkip, kSkip},
1645   };
1646
1647   ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps,
1648                             base::TimeDelta::FromMilliseconds(2744),
1649                             HAS_AUDIO));
1650 }
1651
1652 TEST_F(ChunkDemuxerTest, WebMFile_VideoOnly) {
1653   struct BufferTimestamps buffer_timestamps[] = {
1654     {0, kSkip},
1655     {33, kSkip},
1656     {67, kSkip},
1657     {100, kSkip},
1658     {133, kSkip},
1659     {kSkip, kSkip},
1660   };
1661
1662   ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps,
1663                             base::TimeDelta::FromMilliseconds(2703),
1664                             HAS_VIDEO));
1665 }
1666
1667 TEST_F(ChunkDemuxerTest, WebMFile_AltRefFrames) {
1668   struct BufferTimestamps buffer_timestamps[] = {
1669     {0, 0},
1670     {33, 3},
1671     {33, 6},
1672     {67, 9},
1673     {100, 12},
1674     {kSkip, kSkip},
1675   };
1676
1677   ASSERT_TRUE(ParseWebMFile("bear-320x240-altref.webm", buffer_timestamps,
1678                             base::TimeDelta::FromMilliseconds(2767)));
1679 }
1680
1681 // Verify that we output buffers before the entire cluster has been parsed.
1682 TEST_F(ChunkDemuxerTest, IncrementalClusterParsing) {
1683   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1684   AppendEmptyCluster(0);
1685
1686   scoped_ptr<Cluster> cluster(GenerateCluster(0, 6));
1687
1688   bool audio_read_done = false;
1689   bool video_read_done = false;
1690   ReadAudio(base::Bind(&OnReadDone,
1691                        base::TimeDelta::FromMilliseconds(0),
1692                        &audio_read_done));
1693   ReadVideo(base::Bind(&OnReadDone,
1694                        base::TimeDelta::FromMilliseconds(0),
1695                        &video_read_done));
1696
1697   // Make sure the reads haven't completed yet.
1698   EXPECT_FALSE(audio_read_done);
1699   EXPECT_FALSE(video_read_done);
1700
1701   // Append data one byte at a time until the audio read completes.
1702   int i = 0;
1703   for (; i < cluster->size() && !audio_read_done; ++i) {
1704     AppendData(cluster->data() + i, 1);
1705     message_loop_.RunUntilIdle();
1706   }
1707
1708   EXPECT_TRUE(audio_read_done);
1709   EXPECT_FALSE(video_read_done);
1710   EXPECT_GT(i, 0);
1711   EXPECT_LT(i, cluster->size());
1712
1713   // Append data one byte at a time until the video read completes.
1714   for (; i < cluster->size() && !video_read_done; ++i) {
1715     AppendData(cluster->data() + i, 1);
1716     message_loop_.RunUntilIdle();
1717   }
1718
1719   EXPECT_TRUE(video_read_done);
1720   EXPECT_LT(i, cluster->size());
1721
1722   audio_read_done = false;
1723   video_read_done = false;
1724   ReadAudio(base::Bind(&OnReadDone,
1725                        base::TimeDelta::FromMilliseconds(23),
1726                        &audio_read_done));
1727   ReadVideo(base::Bind(&OnReadDone,
1728                        base::TimeDelta::FromMilliseconds(33),
1729                        &video_read_done));
1730
1731   // Make sure the reads haven't completed yet.
1732   EXPECT_FALSE(audio_read_done);
1733   EXPECT_FALSE(video_read_done);
1734
1735   // Append the remaining data.
1736   ASSERT_LT(i, cluster->size());
1737   AppendData(cluster->data() + i, cluster->size() - i);
1738
1739   message_loop_.RunUntilIdle();
1740
1741   EXPECT_TRUE(audio_read_done);
1742   EXPECT_TRUE(video_read_done);
1743 }
1744
1745 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) {
1746   EXPECT_CALL(*this, DemuxerOpened());
1747   demuxer_->Initialize(
1748       &host_, CreateInitDoneCB(
1749           kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
1750
1751   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
1752
1753   uint8 tmp = 0;
1754   demuxer_->AppendData(kSourceId, &tmp, 1);
1755 }
1756
1757 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) {
1758   EXPECT_CALL(*this, DemuxerOpened());
1759   demuxer_->Initialize(
1760       &host_, CreateInitDoneCB(kNoTimestamp(),
1761                                DEMUXER_ERROR_COULD_NOT_OPEN), true);
1762
1763   std::vector<std::string> codecs(1);
1764   codecs[0] = "vorbis";
1765   ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs),
1766             ChunkDemuxer::kOk);
1767
1768   AppendInitSegment(HAS_AUDIO | HAS_VIDEO);
1769 }
1770
1771 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) {
1772   EXPECT_CALL(*this, DemuxerOpened());
1773   demuxer_->Initialize(
1774       &host_, CreateInitDoneCB(kNoTimestamp(),
1775                                DEMUXER_ERROR_COULD_NOT_OPEN), true);
1776
1777   std::vector<std::string> codecs(1);
1778   codecs[0] = "vp8";
1779   ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs),
1780             ChunkDemuxer::kOk);
1781
1782   AppendInitSegment(HAS_AUDIO | HAS_VIDEO);
1783 }
1784
1785 TEST_F(ChunkDemuxerTest, MultipleHeaders) {
1786   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1787
1788   AppendCluster(kDefaultFirstCluster());
1789
1790   // Append another identical initialization segment.
1791   AppendInitSegment(HAS_AUDIO | HAS_VIDEO);
1792
1793   AppendCluster(kDefaultSecondCluster());
1794
1795   GenerateExpectedReads(0, 9);
1796 }
1797
1798 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) {
1799   std::string audio_id = "audio1";
1800   std::string video_id = "video1";
1801   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
1802
1803   // Append audio and video data into separate source ids.
1804   AppendCluster(audio_id,
1805       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1806   GenerateAudioStreamExpectedReads(0, 4);
1807   AppendCluster(video_id,
1808       GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
1809   GenerateVideoStreamExpectedReads(0, 4);
1810 }
1811
1812 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) {
1813   // TODO(matthewjheaney): Here and elsewhere, we need more tests
1814   // for inband text tracks (http://crbug/321455).
1815
1816   std::string audio_id = "audio1";
1817   std::string video_id = "video1";
1818
1819   EXPECT_CALL(host_, AddTextStream(_, _))
1820     .Times(Exactly(2));
1821   ASSERT_TRUE(InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, true));
1822
1823   // Append audio and video data into separate source ids.
1824   AppendCluster(audio_id,
1825       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1826   GenerateAudioStreamExpectedReads(0, 4);
1827   AppendCluster(video_id,
1828       GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
1829   GenerateVideoStreamExpectedReads(0, 4);
1830 }
1831
1832 TEST_F(ChunkDemuxerTest, AddIdFailures) {
1833   EXPECT_CALL(*this, DemuxerOpened());
1834   demuxer_->Initialize(
1835       &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
1836
1837   std::string audio_id = "audio1";
1838   std::string video_id = "video1";
1839
1840   ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk);
1841
1842   // Adding an id with audio/video should fail because we already added audio.
1843   ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit);
1844
1845   AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO);
1846
1847   // Adding an id after append should fail.
1848   ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit);
1849 }
1850
1851 // Test that Read() calls after a RemoveId() return "end of stream" buffers.
1852 TEST_F(ChunkDemuxerTest, RemoveId) {
1853   std::string audio_id = "audio1";
1854   std::string video_id = "video1";
1855   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
1856
1857   // Append audio and video data into separate source ids.
1858   AppendCluster(audio_id,
1859       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1860   AppendCluster(video_id,
1861       GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
1862
1863   // Read() from audio should return normal buffers.
1864   GenerateAudioStreamExpectedReads(0, 4);
1865
1866   // Remove the audio id.
1867   demuxer_->RemoveId(audio_id);
1868
1869   // Read() from audio should return "end of stream" buffers.
1870   bool audio_read_done = false;
1871   ReadAudio(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
1872   message_loop_.RunUntilIdle();
1873   EXPECT_TRUE(audio_read_done);
1874
1875   // Read() from video should still return normal buffers.
1876   GenerateVideoStreamExpectedReads(0, 4);
1877 }
1878
1879 // Test that removing an ID immediately after adding it does not interfere with
1880 // quota for new IDs in the future.
1881 TEST_F(ChunkDemuxerTest, RemoveAndAddId) {
1882   std::string audio_id_1 = "audio1";
1883   ASSERT_TRUE(AddId(audio_id_1, HAS_AUDIO) == ChunkDemuxer::kOk);
1884   demuxer_->RemoveId(audio_id_1);
1885
1886   std::string audio_id_2 = "audio2";
1887   ASSERT_TRUE(AddId(audio_id_2, HAS_AUDIO) == ChunkDemuxer::kOk);
1888 }
1889
1890 TEST_F(ChunkDemuxerTest, SeekCanceled) {
1891   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1892
1893   // Append cluster at the beginning of the stream.
1894   AppendCluster(GenerateCluster(0, 4));
1895
1896   // Seek to an unbuffered region.
1897   Seek(base::TimeDelta::FromSeconds(50));
1898
1899   // Attempt to read in unbuffered area; should not fulfill the read.
1900   bool audio_read_done = false;
1901   bool video_read_done = false;
1902   ReadAudio(base::Bind(&OnReadDone_AbortExpected, &audio_read_done));
1903   ReadVideo(base::Bind(&OnReadDone_AbortExpected, &video_read_done));
1904   EXPECT_FALSE(audio_read_done);
1905   EXPECT_FALSE(video_read_done);
1906
1907   // Now cancel the pending seek, which should flush the reads with empty
1908   // buffers.
1909   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(0);
1910   demuxer_->CancelPendingSeek(seek_time);
1911   message_loop_.RunUntilIdle();
1912   EXPECT_TRUE(audio_read_done);
1913   EXPECT_TRUE(video_read_done);
1914
1915   // A seek back to the buffered region should succeed.
1916   Seek(seek_time);
1917   GenerateExpectedReads(0, 4);
1918 }
1919
1920 TEST_F(ChunkDemuxerTest, SeekCanceledWhileWaitingForSeek) {
1921   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1922
1923   // Append cluster at the beginning of the stream.
1924   AppendCluster(GenerateCluster(0, 4));
1925
1926   // Start waiting for a seek.
1927   base::TimeDelta seek_time1 = base::TimeDelta::FromSeconds(50);
1928   base::TimeDelta seek_time2 = base::TimeDelta::FromSeconds(0);
1929   demuxer_->StartWaitingForSeek(seek_time1);
1930
1931   // Now cancel the upcoming seek to an unbuffered region.
1932   demuxer_->CancelPendingSeek(seek_time2);
1933   demuxer_->Seek(seek_time1, NewExpectedStatusCB(PIPELINE_OK));
1934
1935   // Read requests should be fulfilled with empty buffers.
1936   bool audio_read_done = false;
1937   bool video_read_done = false;
1938   ReadAudio(base::Bind(&OnReadDone_AbortExpected, &audio_read_done));
1939   ReadVideo(base::Bind(&OnReadDone_AbortExpected, &video_read_done));
1940   EXPECT_TRUE(audio_read_done);
1941   EXPECT_TRUE(video_read_done);
1942
1943   // A seek back to the buffered region should succeed.
1944   Seek(seek_time2);
1945   GenerateExpectedReads(0, 4);
1946 }
1947
1948 // Test that Seek() successfully seeks to all source IDs.
1949 TEST_F(ChunkDemuxerTest, SeekAudioAndVideoSources) {
1950   std::string audio_id = "audio1";
1951   std::string video_id = "video1";
1952   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
1953
1954   AppendCluster(
1955       audio_id,
1956       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1957   AppendCluster(
1958       video_id,
1959       GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
1960
1961   // Read() should return buffers at 0.
1962   bool audio_read_done = false;
1963   bool video_read_done = false;
1964   ReadAudio(base::Bind(&OnReadDone,
1965                        base::TimeDelta::FromMilliseconds(0),
1966                        &audio_read_done));
1967   ReadVideo(base::Bind(&OnReadDone,
1968                        base::TimeDelta::FromMilliseconds(0),
1969                        &video_read_done));
1970   EXPECT_TRUE(audio_read_done);
1971   EXPECT_TRUE(video_read_done);
1972
1973   // Seek to 3 (an unbuffered region).
1974   Seek(base::TimeDelta::FromSeconds(3));
1975
1976   audio_read_done = false;
1977   video_read_done = false;
1978   ReadAudio(base::Bind(&OnReadDone,
1979                        base::TimeDelta::FromSeconds(3),
1980                        &audio_read_done));
1981   ReadVideo(base::Bind(&OnReadDone,
1982                        base::TimeDelta::FromSeconds(3),
1983                        &video_read_done));
1984   // Read()s should not return until after data is appended at the Seek point.
1985   EXPECT_FALSE(audio_read_done);
1986   EXPECT_FALSE(video_read_done);
1987
1988   AppendCluster(audio_id,
1989                 GenerateSingleStreamCluster(
1990                     3000, 3092, kAudioTrackNum, kAudioBlockDuration));
1991   AppendCluster(video_id,
1992                 GenerateSingleStreamCluster(
1993                     3000, 3132, kVideoTrackNum, kVideoBlockDuration));
1994
1995   message_loop_.RunUntilIdle();
1996
1997   // Read() should return buffers at 3.
1998   EXPECT_TRUE(audio_read_done);
1999   EXPECT_TRUE(video_read_done);
2000 }
2001
2002 // Test that Seek() completes successfully when EndOfStream
2003 // is called before data is available for that seek point.
2004 // This scenario might be useful if seeking past the end of stream
2005 // of either audio or video (or both).
2006 TEST_F(ChunkDemuxerTest, EndOfStreamAfterPastEosSeek) {
2007   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2008
2009   AppendCluster(GenerateSingleStreamCluster(0, 120, kAudioTrackNum, 10));
2010   AppendCluster(GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 5));
2011
2012   // Seeking past the end of video.
2013   // Note: audio data is available for that seek point.
2014   bool seek_cb_was_called = false;
2015   base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(110);
2016   demuxer_->StartWaitingForSeek(seek_time);
2017   demuxer_->Seek(seek_time,
2018                  base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
2019   message_loop_.RunUntilIdle();
2020
2021   EXPECT_FALSE(seek_cb_was_called);
2022
2023   EXPECT_CALL(host_, SetDuration(
2024       base::TimeDelta::FromMilliseconds(120)));
2025   MarkEndOfStream(PIPELINE_OK);
2026   message_loop_.RunUntilIdle();
2027
2028   EXPECT_TRUE(seek_cb_was_called);
2029
2030   ShutdownDemuxer();
2031 }
2032
2033 // Test that EndOfStream is ignored if coming during a pending seek
2034 // whose seek time is before some existing ranges.
2035 TEST_F(ChunkDemuxerTest, EndOfStreamDuringPendingSeek) {
2036   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2037
2038   AppendCluster(GenerateSingleStreamCluster(0, 120, kAudioTrackNum, 10));
2039   AppendCluster(GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 5));
2040   AppendCluster(GenerateSingleStreamCluster(200, 300, kAudioTrackNum, 10));
2041   AppendCluster(GenerateSingleStreamCluster(200, 300, kVideoTrackNum, 5));
2042
2043   bool seek_cb_was_called = false;
2044   base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(160);
2045   demuxer_->StartWaitingForSeek(seek_time);
2046   demuxer_->Seek(seek_time,
2047                  base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
2048   message_loop_.RunUntilIdle();
2049
2050   EXPECT_FALSE(seek_cb_was_called);
2051
2052   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(300)));
2053   MarkEndOfStream(PIPELINE_OK);
2054   message_loop_.RunUntilIdle();
2055
2056   EXPECT_FALSE(seek_cb_was_called);
2057
2058   demuxer_->UnmarkEndOfStream();
2059
2060   AppendCluster(GenerateSingleStreamCluster(140, 180, kAudioTrackNum, 10));
2061   AppendCluster(GenerateSingleStreamCluster(140, 180, kVideoTrackNum, 5));
2062
2063   message_loop_.RunUntilIdle();
2064
2065   EXPECT_TRUE(seek_cb_was_called);
2066
2067   ShutdownDemuxer();
2068 }
2069
2070 // Test ranges in an audio-only stream.
2071 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) {
2072   EXPECT_CALL(*this, DemuxerOpened());
2073   demuxer_->Initialize(
2074       &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
2075
2076   ASSERT_EQ(AddId(kSourceId, HAS_AUDIO), ChunkDemuxer::kOk);
2077   AppendInitSegment(HAS_AUDIO);
2078
2079   // Test a simple cluster.
2080   AppendCluster(
2081       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
2082
2083   CheckExpectedRanges("{ [0,92) }");
2084
2085   // Append a disjoint cluster to check for two separate ranges.
2086   AppendCluster(GenerateSingleStreamCluster(
2087       150, 219, kAudioTrackNum, kAudioBlockDuration));
2088
2089   CheckExpectedRanges("{ [0,92) [150,219) }");
2090 }
2091
2092 // Test ranges in a video-only stream.
2093 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) {
2094   EXPECT_CALL(*this, DemuxerOpened());
2095   demuxer_->Initialize(
2096       &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
2097
2098   ASSERT_EQ(AddId(kSourceId, HAS_VIDEO), ChunkDemuxer::kOk);
2099   AppendInitSegment(HAS_VIDEO);
2100
2101   // Test a simple cluster.
2102   AppendCluster(
2103       GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
2104
2105   CheckExpectedRanges("{ [0,132) }");
2106
2107   // Append a disjoint cluster to check for two separate ranges.
2108   AppendCluster(GenerateSingleStreamCluster(
2109       200, 299, kVideoTrackNum, kVideoBlockDuration));
2110
2111   CheckExpectedRanges("{ [0,132) [200,299) }");
2112 }
2113
2114 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
2115   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2116
2117   // Audio: 0 -> 23
2118   // Video: 0 -> 33
2119   // Buffered Range: 0 -> 23
2120   // Audio block duration is smaller than video block duration,
2121   // so the buffered ranges should correspond to the audio blocks.
2122   AppendCluster(GenerateSingleStreamCluster(
2123       0, kAudioBlockDuration, kAudioTrackNum, kAudioBlockDuration));
2124   AppendCluster(GenerateSingleStreamCluster(
2125       0, kVideoBlockDuration, kVideoTrackNum, kVideoBlockDuration));
2126
2127   CheckExpectedRanges("{ [0,23) }");
2128
2129   // Audio: 300 -> 400
2130   // Video: 320 -> 420
2131   // Buffered Range: 320 -> 400  (end overlap)
2132   AppendCluster(GenerateSingleStreamCluster(300, 400, kAudioTrackNum, 50));
2133   AppendCluster(GenerateSingleStreamCluster(320, 420, kVideoTrackNum, 50));
2134
2135   CheckExpectedRanges("{ [0,23) [320,400) }");
2136
2137   // Audio: 520 -> 590
2138   // Video: 500 -> 570
2139   // Buffered Range: 520 -> 570  (front overlap)
2140   AppendCluster(GenerateSingleStreamCluster(520, 590, kAudioTrackNum, 70));
2141   AppendCluster(GenerateSingleStreamCluster(500, 570, kVideoTrackNum, 70));
2142
2143   CheckExpectedRanges("{ [0,23) [320,400) [520,570) }");
2144
2145   // Audio: 720 -> 750
2146   // Video: 700 -> 770
2147   // Buffered Range: 720 -> 750  (complete overlap, audio)
2148   AppendCluster(GenerateSingleStreamCluster(720, 750, kAudioTrackNum, 30));
2149   AppendCluster(GenerateSingleStreamCluster(700, 770, kVideoTrackNum, 70));
2150
2151   CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) }");
2152
2153   // Audio: 900 -> 970
2154   // Video: 920 -> 950
2155   // Buffered Range: 920 -> 950  (complete overlap, video)
2156   AppendCluster(GenerateSingleStreamCluster(900, 970, kAudioTrackNum, 70));
2157   AppendCluster(GenerateSingleStreamCluster(920, 950, kVideoTrackNum, 30));
2158
2159   CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
2160
2161   // Appending within buffered range should not affect buffered ranges.
2162   AppendCluster(GenerateSingleStreamCluster(930, 950, kAudioTrackNum, 20));
2163   CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
2164
2165   // Appending to single stream outside buffered ranges should not affect
2166   // buffered ranges.
2167   AppendCluster(GenerateSingleStreamCluster(1230, 1240, kVideoTrackNum, 10));
2168   CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
2169 }
2170
2171 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideoText) {
2172   EXPECT_CALL(host_, AddTextStream(_, _));
2173   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
2174
2175   // Append audio & video data
2176   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23");
2177   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 33");
2178
2179   // Verify that a text track with no cues does not result in an empty buffered
2180   // range.
2181   CheckExpectedRanges("{ [0,46) }");
2182
2183   // Add some text cues.
2184   AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K");
2185
2186   // Verify that the new cues did not affect the buffered ranges.
2187   CheckExpectedRanges("{ [0,46) }");
2188
2189   // Remove the buffered range.
2190   demuxer_->Remove(kSourceId, base::TimeDelta(),
2191                    base::TimeDelta::FromMilliseconds(46));
2192   CheckExpectedRanges("{ }");
2193 }
2194
2195 // Once MarkEndOfStream() is called, GetBufferedRanges should not cut off any
2196 // over-hanging tails at the end of the ranges as this is likely due to block
2197 // duration differences.
2198 TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) {
2199   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2200
2201   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23K");
2202   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 33");
2203
2204   CheckExpectedRanges("{ [0,46) }");
2205
2206   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(66)));
2207   MarkEndOfStream(PIPELINE_OK);
2208
2209   // Verify that the range extends to the end of the video data.
2210   CheckExpectedRanges("{ [0,66) }");
2211
2212   // Verify that the range reverts to the intersection when end of stream
2213   // has been cancelled.
2214   demuxer_->UnmarkEndOfStream();
2215   CheckExpectedRanges("{ [0,46) }");
2216
2217   // Append and remove data so that the 2 streams' end ranges do not overlap.
2218
2219   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(246)));
2220   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(366)));
2221   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "200K 223K");
2222   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
2223                             "200K 233 266 299 300K 333");
2224
2225   // At this point, the per-stream ranges are as follows:
2226   // Audio: [0,46) [200,246)
2227   // Video: [0,66) [200,366)
2228   CheckExpectedRanges("{ [0,46) [200,246) }");
2229
2230   demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(200),
2231                    base::TimeDelta::FromMilliseconds(300));
2232
2233   // At this point, the per-stream ranges are as follows:
2234   // Audio: [0,46)
2235   // Video: [0,66) [300,366)
2236   CheckExpectedRanges("{ [0,46) }");
2237
2238   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "200K 223K");
2239   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "200K 233");
2240
2241   // At this point, the per-stream ranges are as follows:
2242   // Audio: [0,46) [200,246)
2243   // Video: [0,66) [200,266) [300,366)
2244   // NOTE: The last range on each stream do not overlap in time.
2245   CheckExpectedRanges("{ [0,46) [200,246) }");
2246
2247   MarkEndOfStream(PIPELINE_OK);
2248
2249   // NOTE: The last range on each stream gets extended to the highest
2250   // end timestamp according to the spec. The last audio range gets extended
2251   // from [200,246) to [200,366) which is why the intersection results in the
2252   // middle range getting larger AND the new range appearing.
2253   CheckExpectedRanges("{ [0,46) [200,266) [300,366) }");
2254 }
2255
2256 TEST_F(ChunkDemuxerTest, DifferentStreamTimecodes) {
2257   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2258
2259   // Create a cluster where the video timecode begins 25ms after the audio.
2260   AppendCluster(GenerateCluster(0, 25, 8));
2261
2262   Seek(base::TimeDelta::FromSeconds(0));
2263   GenerateExpectedReads(0, 25, 8);
2264
2265   // Seek to 5 seconds.
2266   Seek(base::TimeDelta::FromSeconds(5));
2267
2268   // Generate a cluster to fulfill this seek, where audio timecode begins 25ms
2269   // after the video.
2270   AppendCluster(GenerateCluster(5025, 5000, 8));
2271   GenerateExpectedReads(5025, 5000, 8);
2272 }
2273
2274 TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesSeparateSources) {
2275   std::string audio_id = "audio1";
2276   std::string video_id = "video1";
2277   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2278
2279   // Generate two streams where the video stream starts 5ms after the audio
2280   // stream and append them.
2281   AppendCluster(audio_id, GenerateSingleStreamCluster(
2282       25, 4 * kAudioBlockDuration + 25, kAudioTrackNum, kAudioBlockDuration));
2283   AppendCluster(video_id, GenerateSingleStreamCluster(
2284       30, 4 * kVideoBlockDuration + 30, kVideoTrackNum, kVideoBlockDuration));
2285
2286   // Both streams should be able to fulfill a seek to 25.
2287   Seek(base::TimeDelta::FromMilliseconds(25));
2288   GenerateAudioStreamExpectedReads(25, 4);
2289   GenerateVideoStreamExpectedReads(30, 4);
2290 }
2291
2292 TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesOutOfRange) {
2293   std::string audio_id = "audio1";
2294   std::string video_id = "video1";
2295   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2296
2297   // Generate two streams where the video stream starts 10s after the audio
2298   // stream and append them.
2299   AppendCluster(audio_id, GenerateSingleStreamCluster(0,
2300       4 * kAudioBlockDuration + 0, kAudioTrackNum, kAudioBlockDuration));
2301   AppendCluster(video_id, GenerateSingleStreamCluster(10000,
2302       4 * kVideoBlockDuration + 10000, kVideoTrackNum, kVideoBlockDuration));
2303
2304   // Should not be able to fulfill a seek to 0.
2305   base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(0);
2306   demuxer_->StartWaitingForSeek(seek_time);
2307   demuxer_->Seek(seek_time,
2308                  NewExpectedStatusCB(PIPELINE_ERROR_ABORT));
2309   ExpectRead(DemuxerStream::AUDIO, 0);
2310   ExpectEndOfStream(DemuxerStream::VIDEO);
2311 }
2312
2313 TEST_F(ChunkDemuxerTest, ClusterWithNoBuffers) {
2314   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2315
2316   // Generate and append an empty cluster beginning at 0.
2317   AppendEmptyCluster(0);
2318
2319   // Sanity check that data can be appended after this cluster correctly.
2320   AppendCluster(GenerateCluster(0, 2));
2321   ExpectRead(DemuxerStream::AUDIO, 0);
2322   ExpectRead(DemuxerStream::VIDEO, 0);
2323 }
2324
2325 TEST_F(ChunkDemuxerTest, CodecPrefixMatching) {
2326   ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
2327
2328 #if defined(USE_PROPRIETARY_CODECS)
2329   expected = ChunkDemuxer::kOk;
2330 #endif
2331
2332   std::vector<std::string> codecs;
2333   codecs.push_back("avc1.4D4041");
2334
2335   EXPECT_EQ(demuxer_->AddId("source_id", "video/mp4", codecs), expected);
2336 }
2337
2338 // Test codec ID's that are not compliant with RFC6381, but have been
2339 // seen in the wild.
2340 TEST_F(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) {
2341   ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
2342
2343 #if defined(USE_PROPRIETARY_CODECS)
2344   expected = ChunkDemuxer::kOk;
2345 #endif
2346   const char* codec_ids[] = {
2347     // GPAC places leading zeros on the audio object type.
2348     "mp4a.40.02",
2349     "mp4a.40.05"
2350   };
2351
2352   for (size_t i = 0; i < arraysize(codec_ids); ++i) {
2353     std::vector<std::string> codecs;
2354     codecs.push_back(codec_ids[i]);
2355
2356     ChunkDemuxer::Status result =
2357         demuxer_->AddId("source_id", "audio/mp4", codecs);
2358
2359     EXPECT_EQ(result, expected)
2360         << "Fail to add codec_id '" << codec_ids[i] << "'";
2361
2362     if (result == ChunkDemuxer::kOk)
2363       demuxer_->RemoveId("source_id");
2364   }
2365 }
2366
2367 TEST_F(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) {
2368   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2369
2370   EXPECT_CALL(host_, SetDuration(_))
2371       .Times(AnyNumber());
2372
2373   base::TimeDelta kLastAudioTimestamp = base::TimeDelta::FromMilliseconds(92);
2374   base::TimeDelta kLastVideoTimestamp = base::TimeDelta::FromMilliseconds(99);
2375
2376   AppendCluster(kDefaultFirstCluster());
2377   AppendCluster(kDefaultSecondCluster());
2378   MarkEndOfStream(PIPELINE_OK);
2379
2380   DemuxerStream::Status status;
2381   base::TimeDelta last_timestamp;
2382
2383   // Verify that we can read audio & video to the end w/o problems.
2384   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
2385   EXPECT_EQ(DemuxerStream::kOk, status);
2386   EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
2387
2388   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2389   EXPECT_EQ(DemuxerStream::kOk, status);
2390   EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
2391
2392   // Seek back to 0 and verify that we can read to the end again..
2393   Seek(base::TimeDelta::FromMilliseconds(0));
2394
2395   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
2396   EXPECT_EQ(DemuxerStream::kOk, status);
2397   EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
2398
2399   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2400   EXPECT_EQ(DemuxerStream::kOk, status);
2401   EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
2402 }
2403
2404 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) {
2405   EXPECT_CALL(*this, DemuxerOpened());
2406   demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true);
2407   ASSERT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
2408   ASSERT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk);
2409
2410   CheckExpectedRanges("audio", "{ }");
2411   CheckExpectedRanges("video", "{ }");
2412 }
2413
2414 // Test that Seek() completes successfully when the first cluster
2415 // arrives.
2416 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) {
2417   InSequence s;
2418
2419   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2420
2421   AppendCluster(kDefaultFirstCluster());
2422
2423   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(0);
2424   demuxer_->StartWaitingForSeek(seek_time);
2425
2426   AppendCluster(kDefaultSecondCluster());
2427   EXPECT_CALL(host_, SetDuration(
2428       base::TimeDelta::FromMilliseconds(kDefaultSecondClusterEndTimestamp)));
2429   MarkEndOfStream(PIPELINE_OK);
2430
2431   demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
2432
2433   GenerateExpectedReads(0, 4);
2434   GenerateExpectedReads(46, 66, 5);
2435
2436   EndOfStreamHelper end_of_stream_helper(demuxer_.get());
2437   end_of_stream_helper.RequestReads();
2438   end_of_stream_helper.CheckIfReadDonesWereCalled(true);
2439 }
2440
2441 TEST_F(ChunkDemuxerTest, ConfigChange_Video) {
2442   InSequence s;
2443
2444   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
2445
2446   DemuxerStream::Status status;
2447   base::TimeDelta last_timestamp;
2448
2449   DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
2450
2451   // Fetch initial video config and verify it matches what we expect.
2452   const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
2453   ASSERT_TRUE(video_config_1.IsValidConfig());
2454   EXPECT_EQ(video_config_1.natural_size().width(), 320);
2455   EXPECT_EQ(video_config_1.natural_size().height(), 240);
2456
2457   ExpectRead(DemuxerStream::VIDEO, 0);
2458
2459   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2460
2461   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
2462   EXPECT_EQ(last_timestamp.InMilliseconds(), 501);
2463
2464   // Fetch the new decoder config.
2465   const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
2466   ASSERT_TRUE(video_config_2.IsValidConfig());
2467   EXPECT_EQ(video_config_2.natural_size().width(), 640);
2468   EXPECT_EQ(video_config_2.natural_size().height(), 360);
2469
2470   ExpectRead(DemuxerStream::VIDEO, 527);
2471
2472   // Read until the next config change.
2473   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2474   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
2475   EXPECT_EQ(last_timestamp.InMilliseconds(), 793);
2476
2477   // Get the new config and verify that it matches the first one.
2478   ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
2479
2480   ExpectRead(DemuxerStream::VIDEO, 801);
2481
2482   // Read until the end of the stream just to make sure there aren't any other
2483   // config changes.
2484   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2485   ASSERT_EQ(status, DemuxerStream::kOk);
2486 }
2487
2488 TEST_F(ChunkDemuxerTest, ConfigChange_Audio) {
2489   InSequence s;
2490
2491   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
2492
2493   DemuxerStream::Status status;
2494   base::TimeDelta last_timestamp;
2495
2496   DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
2497
2498   // Fetch initial audio config and verify it matches what we expect.
2499   const AudioDecoderConfig& audio_config_1 = audio->audio_decoder_config();
2500   ASSERT_TRUE(audio_config_1.IsValidConfig());
2501   EXPECT_EQ(audio_config_1.samples_per_second(), 44100);
2502   EXPECT_EQ(audio_config_1.extra_data_size(), 3863u);
2503
2504   ExpectRead(DemuxerStream::AUDIO, 0);
2505
2506   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
2507
2508   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
2509   EXPECT_EQ(last_timestamp.InMilliseconds(), 524);
2510
2511   // Fetch the new decoder config.
2512   const AudioDecoderConfig& audio_config_2 = audio->audio_decoder_config();
2513   ASSERT_TRUE(audio_config_2.IsValidConfig());
2514   EXPECT_EQ(audio_config_2.samples_per_second(), 44100);
2515   EXPECT_EQ(audio_config_2.extra_data_size(), 3935u);
2516
2517   ExpectRead(DemuxerStream::AUDIO, 527);
2518
2519   // Read until the next config change.
2520   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
2521   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
2522   EXPECT_EQ(last_timestamp.InMilliseconds(), 759);
2523
2524   // Get the new config and verify that it matches the first one.
2525   ASSERT_TRUE(audio_config_1.Matches(audio->audio_decoder_config()));
2526
2527   ExpectRead(DemuxerStream::AUDIO, 779);
2528
2529   // Read until the end of the stream just to make sure there aren't any other
2530   // config changes.
2531   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
2532   ASSERT_EQ(status, DemuxerStream::kOk);
2533 }
2534
2535 TEST_F(ChunkDemuxerTest, ConfigChange_Seek) {
2536   InSequence s;
2537
2538   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
2539
2540   DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
2541
2542   // Fetch initial video config and verify it matches what we expect.
2543   const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
2544   ASSERT_TRUE(video_config_1.IsValidConfig());
2545   EXPECT_EQ(video_config_1.natural_size().width(), 320);
2546   EXPECT_EQ(video_config_1.natural_size().height(), 240);
2547
2548   ExpectRead(DemuxerStream::VIDEO, 0);
2549
2550   // Seek to a location with a different config.
2551   Seek(base::TimeDelta::FromMilliseconds(527));
2552
2553   // Verify that the config change is signalled.
2554   ExpectConfigChanged(DemuxerStream::VIDEO);
2555
2556   // Fetch the new decoder config and verify it is what we expect.
2557   const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
2558   ASSERT_TRUE(video_config_2.IsValidConfig());
2559   EXPECT_EQ(video_config_2.natural_size().width(), 640);
2560   EXPECT_EQ(video_config_2.natural_size().height(), 360);
2561
2562   // Verify that Read() will return a buffer now.
2563   ExpectRead(DemuxerStream::VIDEO, 527);
2564
2565   // Seek back to the beginning and verify we get another config change.
2566   Seek(base::TimeDelta::FromMilliseconds(0));
2567   ExpectConfigChanged(DemuxerStream::VIDEO);
2568   ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
2569   ExpectRead(DemuxerStream::VIDEO, 0);
2570
2571   // Seek to a location that requires a config change and then
2572   // seek to a new location that has the same configuration as
2573   // the start of the file without a Read() in the middle.
2574   Seek(base::TimeDelta::FromMilliseconds(527));
2575   Seek(base::TimeDelta::FromMilliseconds(801));
2576
2577   // Verify that no config change is signalled.
2578   ExpectRead(DemuxerStream::VIDEO, 801);
2579   ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
2580 }
2581
2582 TEST_F(ChunkDemuxerTest, TimestampPositiveOffset) {
2583   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2584
2585   ASSERT_TRUE(demuxer_->SetTimestampOffset(
2586       kSourceId, base::TimeDelta::FromSeconds(30)));
2587   AppendCluster(GenerateCluster(0, 2));
2588
2589   Seek(base::TimeDelta::FromMilliseconds(30000));
2590
2591   GenerateExpectedReads(30000, 2);
2592 }
2593
2594 TEST_F(ChunkDemuxerTest, TimestampNegativeOffset) {
2595   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2596
2597   ASSERT_TRUE(demuxer_->SetTimestampOffset(
2598       kSourceId, base::TimeDelta::FromSeconds(-1)));
2599   AppendCluster(GenerateCluster(1000, 2));
2600
2601   GenerateExpectedReads(0, 2);
2602 }
2603
2604 TEST_F(ChunkDemuxerTest, TimestampOffsetSeparateStreams) {
2605   std::string audio_id = "audio1";
2606   std::string video_id = "video1";
2607   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2608
2609   ASSERT_TRUE(demuxer_->SetTimestampOffset(
2610       audio_id, base::TimeDelta::FromMilliseconds(-2500)));
2611   ASSERT_TRUE(demuxer_->SetTimestampOffset(
2612       video_id, base::TimeDelta::FromMilliseconds(-2500)));
2613   AppendCluster(audio_id, GenerateSingleStreamCluster(2500,
2614       2500 + kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration));
2615   AppendCluster(video_id, GenerateSingleStreamCluster(2500,
2616       2500 + kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration));
2617   GenerateAudioStreamExpectedReads(0, 4);
2618   GenerateVideoStreamExpectedReads(0, 4);
2619
2620   Seek(base::TimeDelta::FromMilliseconds(27300));
2621
2622   ASSERT_TRUE(demuxer_->SetTimestampOffset(
2623       audio_id, base::TimeDelta::FromMilliseconds(27300)));
2624   ASSERT_TRUE(demuxer_->SetTimestampOffset(
2625       video_id, base::TimeDelta::FromMilliseconds(27300)));
2626   AppendCluster(audio_id, GenerateSingleStreamCluster(
2627       0, kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration));
2628   AppendCluster(video_id, GenerateSingleStreamCluster(
2629       0, kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration));
2630   GenerateVideoStreamExpectedReads(27300, 4);
2631   GenerateAudioStreamExpectedReads(27300, 4);
2632 }
2633
2634 TEST_F(ChunkDemuxerTest, TimestampOffsetMidMediaSegment) {
2635   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2636
2637   scoped_ptr<Cluster> cluster = GenerateCluster(0, 2);
2638   // Append only part of the cluster data.
2639   AppendData(cluster->data(), cluster->size() - 13);
2640
2641   // Setting a timestamp should fail because we're in the middle of a cluster.
2642   ASSERT_FALSE(demuxer_->SetTimestampOffset(
2643       kSourceId, base::TimeDelta::FromSeconds(25)));
2644
2645   demuxer_->Abort(kSourceId);
2646   // After Abort(), setting a timestamp should succeed since we're no longer
2647   // in the middle of a cluster
2648   ASSERT_TRUE(demuxer_->SetTimestampOffset(
2649       kSourceId, base::TimeDelta::FromSeconds(25)));
2650 }
2651
2652 TEST_F(ChunkDemuxerTest, WebMParsingMediaSegmentDetection) {
2653   // TODO(wolenetz): Also test 'unknown' sized clusters.
2654   // See http://crbug.com/335676.
2655   const uint8 kBuffer[] = {
2656     0x1F, 0x43, 0xB6, 0x75, 0x83,  // CLUSTER (size = 3)
2657     0xE7, 0x81, 0x01,                // Cluster TIMECODE (value = 1)
2658   };
2659
2660   // Setting timestamp offset or append mode is allowed only while not
2661   // parsing a media segment. This array indicates whether or not these
2662   // operations are allowed following each incrementally appended byte in
2663   // |kBuffer|.
2664   const bool kExpectedReturnValues[] = {
2665     true, true, true, true, false,
2666     false, false, true,
2667   };
2668
2669   COMPILE_ASSERT(arraysize(kBuffer) == arraysize(kExpectedReturnValues),
2670       test_arrays_out_of_sync);
2671   COMPILE_ASSERT(arraysize(kBuffer) == sizeof(kBuffer), not_one_byte_per_index);
2672
2673   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2674
2675   for (size_t i = 0; i < sizeof(kBuffer); i++) {
2676     DVLOG(3) << "Appending and testing index " << i;
2677     AppendData(kBuffer + i, 1);
2678     bool expected_return_value = kExpectedReturnValues[i];
2679     EXPECT_EQ(expected_return_value, demuxer_->SetTimestampOffset(
2680         kSourceId, base::TimeDelta::FromSeconds(25)));
2681     EXPECT_EQ(expected_return_value, demuxer_->SetSequenceMode(
2682         kSourceId, true));
2683     EXPECT_EQ(expected_return_value, demuxer_->SetSequenceMode(
2684         kSourceId, false));
2685   }
2686 }
2687
2688 TEST_F(ChunkDemuxerTest, SetSequenceModeMidMediaSegment) {
2689   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2690
2691   scoped_ptr<Cluster> cluster = GenerateCluster(0, 2);
2692   // Append only part of the cluster data.
2693   AppendData(cluster->data(), cluster->size() - 13);
2694
2695   // Setting append mode should fail because we're in the middle of a cluster.
2696   ASSERT_FALSE(demuxer_->SetSequenceMode(kSourceId, true));
2697   ASSERT_FALSE(demuxer_->SetSequenceMode(kSourceId, false));
2698
2699   demuxer_->Abort(kSourceId);
2700   // After Abort(), setting append mode should succeed since we're no longer
2701   // in the middle of a cluster.
2702   ASSERT_TRUE(demuxer_->SetSequenceMode(kSourceId, true));
2703   ASSERT_TRUE(demuxer_->SetSequenceMode(kSourceId, false));
2704 }
2705
2706 TEST_F(ChunkDemuxerTest, DurationChange) {
2707   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2708   const int kStreamDuration = kDefaultDuration().InMilliseconds();
2709
2710   // Add data leading up to the currently set duration.
2711   AppendCluster(GenerateCluster(kStreamDuration - kAudioBlockDuration,
2712                                 kStreamDuration - kVideoBlockDuration,
2713                                 2));
2714
2715   CheckExpectedRanges(kSourceId, "{ [201191,201224) }");
2716
2717   // Add data at the currently set duration. The duration should not increase.
2718   AppendCluster(GenerateCluster(kDefaultDuration().InMilliseconds(), 2));
2719
2720   // Range should not be affected.
2721   CheckExpectedRanges(kSourceId, "{ [201191,201224) }");
2722
2723   // Now add data past the duration and expect a new duration to be signalled.
2724   const int kNewStreamDuration = kStreamDuration + kAudioBlockDuration * 2;
2725   EXPECT_CALL(host_, SetDuration(
2726       base::TimeDelta::FromMilliseconds(kNewStreamDuration)));
2727   AppendCluster(GenerateCluster(kStreamDuration + kAudioBlockDuration,
2728                                 kStreamDuration + kVideoBlockDuration,
2729                                 2));
2730
2731   // See that the range has increased appropriately.
2732   CheckExpectedRanges(kSourceId, "{ [201191,201270) }");
2733 }
2734
2735 TEST_F(ChunkDemuxerTest, DurationChangeTimestampOffset) {
2736   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2737
2738   ASSERT_TRUE(demuxer_->SetTimestampOffset(kSourceId, kDefaultDuration()));
2739
2740   EXPECT_CALL(host_, SetDuration(
2741       kDefaultDuration() + base::TimeDelta::FromMilliseconds(
2742           kAudioBlockDuration * 2)));
2743   AppendCluster(GenerateCluster(0, 4));
2744 }
2745
2746 TEST_F(ChunkDemuxerTest, EndOfStreamTruncateDuration) {
2747   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2748
2749   AppendCluster(kDefaultFirstCluster());
2750
2751   EXPECT_CALL(host_, SetDuration(
2752       base::TimeDelta::FromMilliseconds(kDefaultFirstClusterEndTimestamp)));
2753   MarkEndOfStream(PIPELINE_OK);
2754 }
2755
2756
2757 TEST_F(ChunkDemuxerTest, ZeroLengthAppend) {
2758   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2759   AppendData(NULL, 0);
2760 }
2761
2762 TEST_F(ChunkDemuxerTest, AppendAfterEndOfStream) {
2763   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2764
2765   EXPECT_CALL(host_, SetDuration(_))
2766       .Times(AnyNumber());
2767
2768   AppendCluster(kDefaultFirstCluster());
2769   MarkEndOfStream(PIPELINE_OK);
2770
2771   demuxer_->UnmarkEndOfStream();
2772
2773   AppendCluster(kDefaultSecondCluster());
2774   MarkEndOfStream(PIPELINE_OK);
2775 }
2776
2777 // Test receiving a Shutdown() call before we get an Initialize()
2778 // call. This can happen if video element gets destroyed before
2779 // the pipeline has a chance to initialize the demuxer.
2780 TEST_F(ChunkDemuxerTest, Shutdown_BeforeInitialize) {
2781   demuxer_->Shutdown();
2782   demuxer_->Initialize(
2783       &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
2784   message_loop_.RunUntilIdle();
2785 }
2786
2787 TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) {
2788   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2789   AppendCluster(kDefaultFirstCluster());
2790
2791   DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
2792   ASSERT_TRUE(stream);
2793
2794   // The stream should no longer be present.
2795   demuxer_->OnAudioRendererDisabled();
2796   ASSERT_FALSE(demuxer_->GetStream(DemuxerStream::AUDIO));
2797
2798   // Normally this would return an audio buffer at timestamp zero, but
2799   // all reads should return EOS buffers when disabled.
2800   bool audio_read_done = false;
2801   stream->Read(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
2802   message_loop_.RunUntilIdle();
2803
2804   EXPECT_TRUE(audio_read_done);
2805 }
2806
2807 // Verifies that signalling end of stream while stalled at a gap
2808 // boundary does not trigger end of stream buffers to be returned.
2809 TEST_F(ChunkDemuxerTest, EndOfStreamWhileWaitingForGapToBeFilled) {
2810   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2811
2812   AppendCluster(0, 10);
2813   AppendCluster(300, 10);
2814   CheckExpectedRanges(kSourceId, "{ [0,132) [300,432) }");
2815
2816
2817   GenerateExpectedReads(0, 10);
2818
2819   bool audio_read_done = false;
2820   bool video_read_done = false;
2821   ReadAudio(base::Bind(&OnReadDone,
2822                        base::TimeDelta::FromMilliseconds(138),
2823                        &audio_read_done));
2824   ReadVideo(base::Bind(&OnReadDone,
2825                        base::TimeDelta::FromMilliseconds(138),
2826                        &video_read_done));
2827
2828   // Verify that the reads didn't complete
2829   EXPECT_FALSE(audio_read_done);
2830   EXPECT_FALSE(video_read_done);
2831
2832   EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(438)));
2833   MarkEndOfStream(PIPELINE_OK);
2834
2835   // Verify that the reads still haven't completed.
2836   EXPECT_FALSE(audio_read_done);
2837   EXPECT_FALSE(video_read_done);
2838
2839   demuxer_->UnmarkEndOfStream();
2840
2841   AppendCluster(138, 24);
2842
2843   message_loop_.RunUntilIdle();
2844
2845   CheckExpectedRanges(kSourceId, "{ [0,438) }");
2846
2847   // Verify that the reads have completed.
2848   EXPECT_TRUE(audio_read_done);
2849   EXPECT_TRUE(video_read_done);
2850
2851   // Read the rest of the buffers.
2852   GenerateExpectedReads(161, 171, 22);
2853
2854   // Verify that reads block because the append cleared the end of stream state.
2855   audio_read_done = false;
2856   video_read_done = false;
2857   ReadAudio(base::Bind(&OnReadDone_EOSExpected,
2858                        &audio_read_done));
2859   ReadVideo(base::Bind(&OnReadDone_EOSExpected,
2860                        &video_read_done));
2861
2862   // Verify that the reads don't complete.
2863   EXPECT_FALSE(audio_read_done);
2864   EXPECT_FALSE(video_read_done);
2865
2866   MarkEndOfStream(PIPELINE_OK);
2867
2868   EXPECT_TRUE(audio_read_done);
2869   EXPECT_TRUE(video_read_done);
2870 }
2871
2872 TEST_F(ChunkDemuxerTest, CanceledSeekDuringInitialPreroll) {
2873   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2874
2875   // Cancel preroll.
2876   base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(200);
2877   demuxer_->CancelPendingSeek(seek_time);
2878
2879   // Initiate the seek to the new location.
2880   Seek(seek_time);
2881
2882   // Append data to satisfy the seek.
2883   AppendCluster(seek_time.InMilliseconds(), 10);
2884 }
2885
2886 TEST_F(ChunkDemuxerTest, GCDuringSeek) {
2887   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
2888
2889   demuxer_->SetMemoryLimitsForTesting(5 * kBlockSize);
2890
2891   base::TimeDelta seek_time1 = base::TimeDelta::FromMilliseconds(1000);
2892   base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(500);
2893
2894   // Initiate a seek to |seek_time1|.
2895   Seek(seek_time1);
2896
2897   // Append data to satisfy the first seek request.
2898   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
2899                             seek_time1.InMilliseconds(), 5);
2900   CheckExpectedRanges(kSourceId, "{ [1000,1115) }");
2901
2902   // Signal that the second seek is starting.
2903   demuxer_->StartWaitingForSeek(seek_time2);
2904
2905   // Append data to satisfy the second seek. This append triggers
2906   // the garbage collection logic since we set the memory limit to
2907   // 5 blocks.
2908   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
2909                             seek_time2.InMilliseconds(), 5);
2910
2911   // Verify that the buffers that cover |seek_time2| do not get
2912   // garbage collected.
2913   CheckExpectedRanges(kSourceId, "{ [500,615) }");
2914
2915   // Complete the seek.
2916   demuxer_->Seek(seek_time2, NewExpectedStatusCB(PIPELINE_OK));
2917
2918
2919   // Append more data and make sure that the blocks for |seek_time2|
2920   // don't get removed.
2921   //
2922   // NOTE: The current GC algorithm tries to preserve the GOP at the
2923   //  current position as well as the last appended GOP. This is
2924   //  why there are 2 ranges in the expectations.
2925   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5);
2926   CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }");
2927 }
2928
2929 TEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) {
2930     EXPECT_CALL(*this, DemuxerOpened());
2931     demuxer_->Initialize(
2932         &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK), true);
2933
2934     EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO));
2935
2936     demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0),
2937                      base::TimeDelta::FromMilliseconds(1));
2938 }
2939
2940 TEST_F(ChunkDemuxerTest, AppendWindow_Video) {
2941   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
2942   DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
2943
2944   // Set the append window to [20,280).
2945   demuxer_->SetAppendWindowStart(kSourceId,
2946                                  base::TimeDelta::FromMilliseconds(20));
2947   demuxer_->SetAppendWindowEnd(kSourceId,
2948                                base::TimeDelta::FromMilliseconds(280));
2949
2950   // Append a cluster that starts before and ends after the append window.
2951   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
2952                             "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
2953
2954   // Verify that GOPs that start outside the window are not included
2955   // in the buffer. Also verify that buffers that start inside the
2956   // window and extend beyond the end of the window are included.
2957   CheckExpectedRanges(kSourceId, "{ [120,300) }");
2958   CheckExpectedBuffers(stream, "120 150 180 210 240 270");
2959
2960   // Extend the append window to [20,650).
2961   demuxer_->SetAppendWindowEnd(kSourceId,
2962                                base::TimeDelta::FromMilliseconds(650));
2963
2964   // Append more data and verify that adding buffers start at the next
2965   // keyframe.
2966   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
2967                             "360 390 420K 450 480 510 540K 570 600 630K");
2968   CheckExpectedRanges(kSourceId, "{ [120,300) [420,660) }");
2969 }
2970
2971 TEST_F(ChunkDemuxerTest, AppendWindow_Audio) {
2972   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
2973   DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
2974
2975   // Set the append window to [20,280).
2976   demuxer_->SetAppendWindowStart(kSourceId,
2977                                  base::TimeDelta::FromMilliseconds(20));
2978   demuxer_->SetAppendWindowEnd(kSourceId,
2979                                base::TimeDelta::FromMilliseconds(280));
2980
2981   // Append a cluster that starts before and ends after the append window.
2982   AppendSingleStreamCluster(
2983       kSourceId, kAudioTrackNum,
2984       "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K");
2985
2986   // Verify that frames that start outside the window are not included
2987   // in the buffer. Also verify that buffers that start inside the
2988   // window and extend beyond the end of the window are included.
2989   CheckExpectedRanges(kSourceId, "{ [30,300) }");
2990   CheckExpectedBuffers(stream, "30 60 90 120 150 180 210 240 270");
2991
2992   // Extend the append window to [20,650).
2993   demuxer_->SetAppendWindowEnd(kSourceId,
2994                                base::TimeDelta::FromMilliseconds(650));
2995
2996   // Append more data and verify that a new range is created.
2997   AppendSingleStreamCluster(
2998       kSourceId, kAudioTrackNum,
2999       "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K");
3000   CheckExpectedRanges(kSourceId, "{ [30,300) [360,660) }");
3001 }
3002
3003 TEST_F(ChunkDemuxerTest, AppendWindow_Text) {
3004   DemuxerStream* text_stream = NULL;
3005   EXPECT_CALL(host_, AddTextStream(_, _))
3006       .WillOnce(SaveArg<0>(&text_stream));
3007   ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT));
3008   DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3009
3010   // Set the append window to [20,280).
3011   demuxer_->SetAppendWindowStart(kSourceId,
3012                                  base::TimeDelta::FromMilliseconds(20));
3013   demuxer_->SetAppendWindowEnd(kSourceId,
3014                                base::TimeDelta::FromMilliseconds(280));
3015
3016   // Append a cluster that starts before and ends after the append
3017   // window.
3018   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3019                             "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
3020   AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K 200K 300K");
3021
3022   // Verify that text cues that start outside the window are not included
3023   // in the buffer. Also verify that cues that extend beyond the
3024   // window are included.
3025   CheckExpectedRanges(kSourceId, "{ [120,300) }");
3026   CheckExpectedBuffers(video_stream, "120 150 180 210 240 270");
3027   CheckExpectedBuffers(text_stream, "100 200");
3028
3029   // Extend the append window to [20,650).
3030   demuxer_->SetAppendWindowEnd(kSourceId,
3031                                base::TimeDelta::FromMilliseconds(650));
3032
3033   // Append more data and verify that a new range is created.
3034   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3035                             "360 390 420K 450 480 510 540K 570 600 630K");
3036   AppendSingleStreamCluster(kSourceId, kTextTrackNum, "400K 500K 600K 700K");
3037   CheckExpectedRanges(kSourceId, "{ [120,300) [420,660) }");
3038
3039   // Seek to the new range and verify that the expected buffers are returned.
3040   Seek(base::TimeDelta::FromMilliseconds(420));
3041   CheckExpectedBuffers(video_stream, "420 450 480 510 540 570 600 630");
3042   CheckExpectedBuffers(text_stream, "400 500 600");
3043 }
3044
3045 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) {
3046   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3047   EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
3048   AppendGarbage();
3049   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50);
3050   demuxer_->StartWaitingForSeek(seek_time);
3051 }
3052
3053 TEST_F(ChunkDemuxerTest, Remove_AudioVideoText) {
3054   DemuxerStream* text_stream = NULL;
3055   EXPECT_CALL(host_, AddTextStream(_, _))
3056       .WillOnce(SaveArg<0>(&text_stream));
3057   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
3058
3059   DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
3060   DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3061
3062   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3063                             "0K 20K 40K 60K 80K 100K 120K 140K");
3064   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3065                             "0K 30 60 90 120K 150 180");
3066   AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K 200K");
3067
3068   CheckExpectedBuffers(audio_stream, "0 20 40 60 80 100 120 140");
3069   CheckExpectedBuffers(video_stream, "0 30 60 90 120 150 180");
3070   CheckExpectedBuffers(text_stream, "0 100 200");
3071
3072   // Remove the buffers that were added.
3073   demuxer_->Remove(kSourceId, base::TimeDelta(),
3074                    base::TimeDelta::FromMilliseconds(300));
3075
3076   // Verify that all the appended data has been removed.
3077   CheckExpectedRanges(kSourceId, "{ }");
3078
3079   // Append new buffers that are clearly different than the original
3080   // ones and verify that only the new buffers are returned.
3081   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3082                             "1K 21K 41K 61K 81K 101K 121K 141K");
3083   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3084                             "1K 31 61 91 121K 151 181");
3085   AppendSingleStreamCluster(kSourceId, kTextTrackNum, "1K 101K 201K");
3086
3087   Seek(base::TimeDelta());
3088   CheckExpectedBuffers(audio_stream, "1 21 41 61 81 101 121 141");
3089   CheckExpectedBuffers(video_stream, "1 31 61 91 121 151 181");
3090   CheckExpectedBuffers(text_stream, "1 101 201");
3091 }
3092
3093 // Verifies that a Seek() will complete without text cues for
3094 // the seek point and will return cues after the seek position
3095 // when they are eventually appended.
3096 TEST_F(ChunkDemuxerTest, SeekCompletesWithoutTextCues) {
3097   DemuxerStream* text_stream = NULL;
3098   EXPECT_CALL(host_, AddTextStream(_, _))
3099       .WillOnce(SaveArg<0>(&text_stream));
3100   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
3101
3102   DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
3103   DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3104
3105   base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(120);
3106   bool seek_cb_was_called = false;
3107   demuxer_->StartWaitingForSeek(seek_time);
3108   demuxer_->Seek(seek_time,
3109                  base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
3110   message_loop_.RunUntilIdle();
3111
3112   EXPECT_FALSE(seek_cb_was_called);
3113
3114   bool text_read_done = false;
3115   text_stream->Read(base::Bind(&OnReadDone,
3116                                base::TimeDelta::FromMilliseconds(125),
3117                                &text_read_done));
3118
3119   // Append audio & video data so the seek completes.
3120   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3121                             "0K 20K 40K 60K 80K 100K 120K 140K 160K 180K");
3122   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3123                             "0K 30 60 90 120K 150 180 210");
3124
3125   message_loop_.RunUntilIdle();
3126   EXPECT_TRUE(seek_cb_was_called);
3127   EXPECT_FALSE(text_read_done);
3128
3129   // Read some audio & video buffers to further verify seek completion.
3130   CheckExpectedBuffers(audio_stream, "120 140");
3131   CheckExpectedBuffers(video_stream, "120 150");
3132
3133   EXPECT_FALSE(text_read_done);
3134
3135   // Append text cues that start after the seek point and verify that
3136   // they are returned by Read() calls.
3137   AppendSingleStreamCluster(kSourceId, kTextTrackNum, "125K 175K 225K");
3138
3139   message_loop_.RunUntilIdle();
3140   EXPECT_TRUE(text_read_done);
3141
3142   // NOTE: we start at 175 here because the buffer at 125 was returned
3143   // to the pending read initiated above.
3144   CheckExpectedBuffers(text_stream, "175 225");
3145
3146   // Verify that audio & video streams contiue to return expected values.
3147   CheckExpectedBuffers(audio_stream, "160 180");
3148   CheckExpectedBuffers(video_stream, "180 210");
3149 }
3150
3151 }  // namespace media