Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / chunk_demuxer_unittest.cc
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/filters/chunk_demuxer.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <algorithm>
11 #include <memory>
12 #include <queue>
13 #include <utility>
14
15 #include "base/bind.h"
16 #include "base/callback_helpers.h"
17 #include "base/command_line.h"
18 #include "base/memory/raw_ptr.h"
19 #include "base/run_loop.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_split.h"
22 #include "base/strings/string_util.h"
23 #include "base/synchronization/waitable_event.h"
24 #include "base/test/task_environment.h"
25 #include "base/time/time.h"
26 #include "build/build_config.h"
27 #include "media/base/audio_decoder_config.h"
28 #include "media/base/decoder_buffer.h"
29 #include "media/base/decrypt_config.h"
30 #include "media/base/media.h"
31 #include "media/base/media_switches.h"
32 #include "media/base/media_tracks.h"
33 #include "media/base/mock_demuxer_host.h"
34 #include "media/base/mock_media_log.h"
35 #include "media/base/test_data_util.h"
36 #include "media/base/test_helpers.h"
37 #include "media/base/timestamp_constants.h"
38 #include "media/formats/webm/cluster_builder.h"
39 #include "media/formats/webm/webm_cluster_parser.h"
40 #include "media/formats/webm/webm_constants.h"
41 #include "media/media_buildflags.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43
44 using ::testing::AnyNumber;
45 using ::testing::AtLeast;
46 using ::testing::Exactly;
47 using ::testing::HasSubstr;
48 using ::testing::InSequence;
49 using ::testing::NotNull;
50 using ::testing::Return;
51 using ::testing::SaveArg;
52 using ::testing::SetArgPointee;
53 using ::testing::StrictMock;
54 using ::testing::WithParamInterface;
55 using ::testing::_;
56
57 namespace media {
58
59 const uint8_t kTracksHeader[] = {
60     0x16, 0x54, 0xAE, 0x6B,                          // Tracks ID
61     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // tracks(size = 0)
62 };
63
64 const uint8_t kCuesHeader[] = {
65     0x1C, 0x53, 0xBB, 0x6B,                          // Cues ID
66     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // cues(size = 0)
67 };
68
69 const uint8_t kEncryptedMediaInitData[] = {
70     0x68, 0xFE, 0xF9, 0xA1, 0xB3, 0x0D, 0x6B, 0x4D,
71     0xF2, 0x22, 0xB5, 0x0B, 0x4D, 0xE9, 0xE9, 0x95,
72 };
73
74 const int kTracksHeaderSize = sizeof(kTracksHeader);
75 const int kTracksSizeOffset = 4;
76
77 // The size of TrackEntry element in test file "webm_vorbis_track_entry" starts
78 // at index 1 and spans 8 bytes.
79 const int kAudioTrackSizeOffset = 1;
80 const int kAudioTrackSizeWidth = 8;
81 const int kAudioTrackEntryHeaderSize =
82     kAudioTrackSizeOffset + kAudioTrackSizeWidth;
83
84 // The size of TrackEntry element in test file "webm_vp8_track_entry" starts at
85 // index 1 and spans 8 bytes.
86 const int kVideoTrackSizeOffset = 1;
87 const int kVideoTrackSizeWidth = 8;
88 const int kVideoTrackEntryHeaderSize =
89     kVideoTrackSizeOffset + kVideoTrackSizeWidth;
90
91 const int kVideoTrackNum = 1;
92 const int kAudioTrackNum = 2;
93 const int kAlternateVideoTrackNum = 4;
94 const int kAlternateAudioTrackNum = 5;
95 const int kAlternateTextTrackNum = 6;
96
97 const int kAudioBlockDuration = 23;
98 const int kVideoBlockDuration = 33;
99 const int kTextBlockDuration = 100;
100 const int kBlockSize = 10;
101
102 const char kSourceId[] = "SourceId";
103 const char kDefaultFirstClusterRange[] = "{ [0,46) }";
104 const int kDefaultFirstClusterEndTimestamp = 66;
105 const int kDefaultSecondClusterEndTimestamp = 132;
106
107 base::TimeDelta kDefaultDuration() {
108   return base::Milliseconds(201224);
109 }
110
111 // Write an integer into buffer in the form of vint that spans 8 bytes.
112 // The data pointed by |buffer| should be at least 8 bytes long.
113 // |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF.
114 static void WriteInt64(uint8_t* buffer, int64_t number) {
115   DCHECK(number >= 0 && number < 0x00FFFFFFFFFFFFFFLL);
116   buffer[0] = 0x01;
117   int64_t tmp = number;
118   for (int i = 7; i > 0; i--) {
119     buffer[i] = tmp & 0xff;
120     tmp >>= 8;
121   }
122 }
123
124 static void OnReadDone(const base::TimeDelta& expected_time,
125                        bool* called,
126                        DemuxerStream::Status status,
127                        scoped_refptr<DecoderBuffer> buffer) {
128   EXPECT_EQ(status, DemuxerStream::kOk);
129   EXPECT_EQ(expected_time, buffer->timestamp());
130   *called = true;
131 }
132
133 static void OnReadDone_AbortExpected(bool* called,
134                                      DemuxerStream::Status status,
135                                      scoped_refptr<DecoderBuffer> buffer) {
136   EXPECT_EQ(status, DemuxerStream::kAborted);
137   EXPECT_EQ(NULL, buffer.get());
138   *called = true;
139 }
140
141 static void OnReadDone_EOSExpected(bool* called,
142                                    DemuxerStream::Status status,
143                                    scoped_refptr<DecoderBuffer> buffer) {
144   EXPECT_EQ(status, DemuxerStream::kOk);
145   EXPECT_TRUE(buffer->end_of_stream());
146   *called = true;
147 }
148
149 static void OnSeekDone_OKExpected(bool* called, PipelineStatus status) {
150   EXPECT_EQ(status, PIPELINE_OK);
151   *called = true;
152 }
153
154 class ChunkDemuxerTest : public ::testing::Test {
155  public:
156   // Public method because test cases use it directly.
157   MOCK_METHOD1(DemuxerInitialized, void(PipelineStatus));
158
159  protected:
160   enum CodecsIndex {
161     AUDIO,
162     VIDEO,
163     MAX_CODECS_INDEX
164   };
165
166   // Default cluster to append first for simple tests.
167   std::unique_ptr<Cluster> kDefaultFirstCluster() {
168     return GenerateCluster(0, 4);
169   }
170
171   // Default cluster to append after kDefaultFirstCluster()
172   // has been appended. This cluster starts with blocks that
173   // have timestamps consistent with the end times of the blocks
174   // in kDefaultFirstCluster() so that these two clusters represent
175   // a continuous region.
176   std::unique_ptr<Cluster> kDefaultSecondCluster() {
177     return GenerateCluster(46, 66, 5);
178   }
179
180   ChunkDemuxerTest()
181       : did_progress_(false),
182         append_window_end_for_next_append_(kInfiniteDuration) {
183     init_segment_received_cb_ = base::BindRepeating(
184         &ChunkDemuxerTest::InitSegmentReceived, base::Unretained(this));
185     CreateNewDemuxer();
186   }
187
188   ChunkDemuxerTest(const ChunkDemuxerTest&) = delete;
189   ChunkDemuxerTest& operator=(const ChunkDemuxerTest&) = delete;
190
191   void CreateNewDemuxer() {
192     base::OnceClosure open_cb = base::BindOnce(&ChunkDemuxerTest::DemuxerOpened,
193                                                base::Unretained(this));
194     base::RepeatingClosure progress_cb = base::BindRepeating(
195         &ChunkDemuxerTest::OnProgress, base::Unretained(this));
196     Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb =
197         base::BindRepeating(&ChunkDemuxerTest::OnEncryptedMediaInitData,
198                             base::Unretained(this));
199     EXPECT_MEDIA_LOG(ChunkDemuxerCtor());
200     demuxer_ = std::make_unique<ChunkDemuxer>(std::move(open_cb), progress_cb,
201                                               encrypted_media_init_data_cb,
202                                               &media_log_);
203   }
204
205   ~ChunkDemuxerTest() override { ShutdownDemuxer(); }
206
207   void CreateInitSegment(int stream_flags,
208                          bool is_audio_encrypted,
209                          bool is_video_encrypted,
210                          std::unique_ptr<uint8_t[]>* buffer,
211                          int* size) {
212     bool has_audio = (stream_flags & HAS_AUDIO) != 0;
213     bool has_video = (stream_flags & HAS_VIDEO) != 0;
214     scoped_refptr<DecoderBuffer> ebml_header;
215     scoped_refptr<DecoderBuffer> info;
216     scoped_refptr<DecoderBuffer> audio_track_entry;
217     scoped_refptr<DecoderBuffer> video_track_entry;
218     scoped_refptr<DecoderBuffer> audio_content_encodings;
219     scoped_refptr<DecoderBuffer> video_content_encodings;
220     scoped_refptr<DecoderBuffer> text_track_entry;
221
222     ebml_header = ReadTestDataFile("webm_ebml_element");
223
224     info = ReadTestDataFile("webm_info_element");
225
226     int tracks_element_size = 0;
227
228     if (has_audio) {
229       audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry");
230       tracks_element_size += audio_track_entry->data_size();
231       // Verify that we have TrackNum (0xD7) EBML element at expected offset.
232       DCHECK_EQ(audio_track_entry->data()[9], kWebMIdTrackNumber);
233       // Verify that the size of TrackNum element is 1. The actual value is 0x81
234       // due to how element sizes are encoded in EBML.
235       DCHECK_EQ(audio_track_entry->data()[10], 0x81);
236       // Ensure the track id in TrackNum EBML element matches kAudioTrackNum.
237       DCHECK_EQ(audio_track_entry->data()[11], kAudioTrackNum);
238       if (stream_flags & USE_ALTERNATE_AUDIO_TRACK_ID)
239         audio_track_entry->writable_data()[11] = kAlternateAudioTrackNum;
240       if (is_audio_encrypted) {
241         audio_content_encodings = ReadTestDataFile("webm_content_encodings");
242         tracks_element_size += audio_content_encodings->data_size();
243       }
244     }
245
246     if (has_video) {
247       video_track_entry = ReadTestDataFile("webm_vp8_track_entry");
248       tracks_element_size += video_track_entry->data_size();
249       // Verify that we have TrackNum (0xD7) EBML element at expected offset.
250       DCHECK_EQ(video_track_entry->data()[9], kWebMIdTrackNumber);
251       // Verify that the size of TrackNum element is 1. The actual value is 0x81
252       // due to how element sizes are encoded in EBML.
253       DCHECK_EQ(video_track_entry->data()[10], 0x81);
254       // Ensure the track id in TrackNum EBML element matches kVideoTrackNum.
255       DCHECK_EQ(video_track_entry->data()[11], kVideoTrackNum);
256       if (stream_flags & USE_ALTERNATE_VIDEO_TRACK_ID)
257         video_track_entry->writable_data()[11] = kAlternateVideoTrackNum;
258       if (is_video_encrypted) {
259         video_content_encodings = ReadTestDataFile("webm_content_encodings");
260         tracks_element_size += video_content_encodings->data_size();
261       }
262     }
263
264     *size = ebml_header->data_size() + info->data_size() +
265         kTracksHeaderSize + tracks_element_size;
266
267     buffer->reset(new uint8_t[*size]);
268
269     uint8_t* buf = buffer->get();
270     memcpy(buf, ebml_header->data(), ebml_header->data_size());
271     buf += ebml_header->data_size();
272
273     memcpy(buf, info->data(), info->data_size());
274     buf += info->data_size();
275
276     memcpy(buf, kTracksHeader, kTracksHeaderSize);
277     WriteInt64(buf + kTracksSizeOffset, tracks_element_size);
278     buf += kTracksHeaderSize;
279
280     // TODO(xhwang): Simplify this! Probably have test data files that contain
281     // ContentEncodings directly instead of trying to create one at run-time.
282     if (has_video) {
283       memcpy(buf, video_track_entry->data(),
284              video_track_entry->data_size());
285       if (is_video_encrypted) {
286         memcpy(buf + video_track_entry->data_size(),
287                video_content_encodings->data(),
288                video_content_encodings->data_size());
289         WriteInt64(buf + kVideoTrackSizeOffset,
290                    video_track_entry->data_size() +
291                    video_content_encodings->data_size() -
292                    kVideoTrackEntryHeaderSize);
293         buf += video_content_encodings->data_size();
294       }
295       buf += video_track_entry->data_size();
296     }
297
298     if (has_audio) {
299       memcpy(buf, audio_track_entry->data(), audio_track_entry->data_size());
300       if (is_audio_encrypted) {
301         memcpy(buf + audio_track_entry->data_size(),
302                audio_content_encodings->data(),
303                audio_content_encodings->data_size());
304         WriteInt64(buf + kAudioTrackSizeOffset,
305                    audio_track_entry->data_size() +
306                        audio_content_encodings->data_size() -
307                        kAudioTrackEntryHeaderSize);
308         buf += audio_content_encodings->data_size();
309       }
310       buf += audio_track_entry->data_size();
311     }
312   }
313
314   ChunkDemuxer::Status AddId() {
315     return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
316   }
317
318   ChunkDemuxer::Status AddId(const std::string& source_id, int stream_flags) {
319     bool has_audio = (stream_flags & HAS_AUDIO) != 0;
320     bool has_video = (stream_flags & HAS_VIDEO) != 0;
321     std::string codecs;
322     std::string type;
323
324     if (has_audio) {
325       codecs += "vorbis";
326       type = "audio/webm";
327     }
328
329     if (has_video) {
330       if (codecs == "")
331         codecs = "vp8";
332       else
333         codecs += ",vp8";
334       type = "video/webm";
335     }
336
337     if (!has_audio && !has_video) {
338       return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
339     }
340
341     return AddId(source_id, type, codecs);
342   }
343
344   ChunkDemuxer::Status AddId(const std::string& source_id,
345                              const std::string& mime_type,
346                              const std::string& codecs) {
347     ChunkDemuxer::Status status = demuxer_->AddId(source_id, mime_type, codecs);
348     if (status == ChunkDemuxer::kOk) {
349       demuxer_->SetTracksWatcher(source_id, init_segment_received_cb_);
350       demuxer_->SetParseWarningCallback(
351           source_id, base::BindRepeating(&ChunkDemuxerTest::OnParseWarningMock,
352                                          base::Unretained(this)));
353     }
354     return status;
355   }
356
357   bool AppendData(const uint8_t* data, size_t length) {
358     return AppendData(kSourceId, data, length);
359   }
360
361   bool AppendCluster(const std::string& source_id,
362                      std::unique_ptr<Cluster> cluster) {
363     return AppendData(source_id, cluster->data(), cluster->size());
364   }
365
366   bool AppendCluster(std::unique_ptr<Cluster> cluster) {
367     return AppendCluster(kSourceId, std::move(cluster));
368   }
369
370   bool AppendCluster(int timecode, int block_count) {
371     return AppendCluster(GenerateCluster(timecode, block_count));
372   }
373
374   void AppendSingleStreamCluster(const std::string& source_id, int track_number,
375                                  int timecode, int block_count) {
376     int block_duration = 0;
377     switch (track_number) {
378       case kVideoTrackNum:
379       case kAlternateVideoTrackNum:
380         block_duration = kVideoBlockDuration;
381         break;
382       case kAudioTrackNum:
383       case kAlternateAudioTrackNum:
384         block_duration = kAudioBlockDuration;
385         break;
386       case kAlternateTextTrackNum:
387         block_duration = kTextBlockDuration;
388         break;
389     }
390     ASSERT_NE(block_duration, 0);
391     int end_timecode = timecode + block_count * block_duration;
392     ASSERT_TRUE(AppendCluster(
393         source_id, GenerateSingleStreamCluster(timecode, end_timecode,
394                                                track_number, block_duration)));
395   }
396
397   struct BlockInfo {
398     BlockInfo()
399         : track_number(0),
400           timestamp_in_ms(0),
401           flags(0),
402           duration(0) {
403     }
404
405     BlockInfo(int tn, int ts, int f, int d)
406         : track_number(tn),
407           timestamp_in_ms(ts),
408           flags(f),
409           duration(d) {
410     }
411
412     int track_number;
413     int timestamp_in_ms;
414     int flags;
415     int duration;
416
417     bool operator< (const BlockInfo& rhs) const {
418       return timestamp_in_ms < rhs.timestamp_in_ms;
419     }
420   };
421
422   // |track_number| - The track number to place in
423   // |block_descriptions| - A space delimited string of block info that
424   //  is used to populate |blocks|. Each block info has a timestamp in
425   //  milliseconds and optionally followed by a 'K' to indicate that a block
426   //  should be marked as a key frame. For example "0K 30 60" should populate
427   //  |blocks| with 3 BlockInfo objects: a key frame with timestamp 0 and 2
428   //  non-key-frames at 30ms and 60ms.
429   //  Every block will be a SimpleBlock, with the exception that the last block
430   //  may have an optional duration delimited with a 'D' and appended to the
431   //  block info timestamp, prior to the optional keyframe 'K'. For example "0K
432   //  30 60D10K" indicates that the last block will be a keyframe BlockGroup
433   //  with duration 10ms.
434   void ParseBlockDescriptions(int track_number,
435                               const std::string block_descriptions,
436                               std::vector<BlockInfo>* blocks) {
437     std::vector<std::string> timestamps = base::SplitString(
438         block_descriptions, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
439
440     for (size_t i = 0; i < timestamps.size(); ++i) {
441       std::string timestamp_str = timestamps[i];
442       BlockInfo block_info;
443       block_info.track_number = track_number;
444       block_info.flags = 0;
445       block_info.duration = 0;
446
447       if (base::EndsWith(timestamp_str, "K", base::CompareCase::SENSITIVE)) {
448         block_info.flags = kWebMFlagKeyframe;
449         // Remove the "K" off of the token.
450         timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1);
451       }
452
453       size_t duration_pos = timestamp_str.find('D');
454       const bool explicit_duration = duration_pos != std::string::npos;
455       const bool is_last_block = i == timestamps.size() - 1;
456       CHECK(!explicit_duration || is_last_block);
457       if (explicit_duration) {
458         CHECK(base::StringToInt(timestamp_str.substr(duration_pos + 1),
459                                 &block_info.duration));
460         timestamp_str = timestamp_str.substr(0, duration_pos);
461       }
462
463       CHECK(base::StringToInt(timestamp_str, &block_info.timestamp_in_ms));
464
465       if (track_number == kAlternateTextTrackNum) {
466         block_info.duration = kTextBlockDuration;
467         ASSERT_EQ(kWebMFlagKeyframe, block_info.flags)
468             << "Text block with timestamp " << block_info.timestamp_in_ms
469             << " was not marked as a key frame."
470             << " All text blocks must be key frames";
471       }
472
473       if (track_number == kAudioTrackNum ||
474           track_number == kAlternateAudioTrackNum)
475         ASSERT_TRUE(block_info.flags & kWebMFlagKeyframe);
476
477       blocks->push_back(block_info);
478     }
479   }
480
481   std::unique_ptr<Cluster> GenerateCluster(const std::vector<BlockInfo>& blocks,
482                                            bool unknown_size) {
483     DCHECK_GT(blocks.size(), 0u);
484     ClusterBuilder cb;
485
486     // Ensure we can obtain a valid pointer to a region of data of |block_size_|
487     // length.
488     std::vector<uint8_t> data(block_size_ ? block_size_ : 1);
489
490     for (size_t i = 0; i < blocks.size(); ++i) {
491       if (i == 0)
492         cb.SetClusterTimecode(blocks[i].timestamp_in_ms);
493
494       if (blocks[i].duration) {
495         cb.AddBlockGroup(blocks[i].track_number, blocks[i].timestamp_in_ms,
496                          blocks[i].duration, blocks[i].flags,
497                          blocks[i].flags & kWebMFlagKeyframe, &data[0],
498                          block_size_);
499       } else {
500         cb.AddSimpleBlock(blocks[i].track_number, blocks[i].timestamp_in_ms,
501                           blocks[i].flags, &data[0], block_size_);
502       }
503     }
504
505     return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish();
506   }
507
508   std::unique_ptr<Cluster> GenerateCluster(
509       std::priority_queue<BlockInfo> block_queue,
510       bool unknown_size) {
511     std::vector<BlockInfo> blocks(block_queue.size());
512     for (size_t i = block_queue.size() - 1; !block_queue.empty(); --i) {
513       blocks[i] = block_queue.top();
514       block_queue.pop();
515     }
516
517     return GenerateCluster(blocks, unknown_size);
518   }
519
520   // |block_descriptions| - The block descriptions used to construct the
521   // cluster. See the documentation for ParseBlockDescriptions() for details on
522   // the string format.
523   void AppendSingleStreamCluster(const std::string& source_id, int track_number,
524                                  const std::string& block_descriptions) {
525     std::vector<BlockInfo> blocks;
526     ParseBlockDescriptions(track_number, block_descriptions, &blocks);
527     ASSERT_TRUE(AppendCluster(source_id, GenerateCluster(blocks, false)));
528   }
529
530   struct MuxedStreamInfo {
531     MuxedStreamInfo()
532         : track_number(0),
533           block_descriptions(""),
534           last_blocks_estimated_duration(-1) {}
535
536     MuxedStreamInfo(int track_num, const char* block_desc)
537         : track_number(track_num),
538           block_descriptions(block_desc),
539           last_blocks_estimated_duration(-1) {}
540
541     MuxedStreamInfo(int track_num,
542                     const char* block_desc,
543                     int last_block_duration_estimate)
544         : track_number(track_num),
545           block_descriptions(block_desc),
546           last_blocks_estimated_duration(last_block_duration_estimate) {}
547
548     int track_number;
549     // The block description passed to ParseBlockDescriptions().
550     // See the documentation for that method for details on the string format.
551     const char* block_descriptions;
552
553     // If -1, no WebMSimpleBlockDurationEstimated MediaLog expectation is added
554     // when appending the resulting cluster. Otherwise, an expectation (in ms)
555     // is added.
556     int last_blocks_estimated_duration;
557   };
558
559   void AppendMuxedCluster(const MuxedStreamInfo& msi_1,
560                           const MuxedStreamInfo& msi_2) {
561     std::vector<MuxedStreamInfo> msi(2);
562     msi[0] = msi_1;
563     msi[1] = msi_2;
564     AppendMuxedCluster(msi);
565   }
566
567   void AppendMuxedCluster(const MuxedStreamInfo& msi_1,
568                           const MuxedStreamInfo& msi_2,
569                           const MuxedStreamInfo& msi_3) {
570     std::vector<MuxedStreamInfo> msi(3);
571     msi[0] = msi_1;
572     msi[1] = msi_2;
573     msi[2] = msi_3;
574     AppendMuxedCluster(msi);
575   }
576
577   std::unique_ptr<Cluster> GenerateMuxedCluster(
578       const std::vector<MuxedStreamInfo> msi) {
579     std::priority_queue<BlockInfo> block_queue;
580     for (size_t i = 0; i < msi.size(); ++i) {
581       std::vector<BlockInfo> track_blocks;
582       ParseBlockDescriptions(msi[i].track_number, msi[i].block_descriptions,
583                              &track_blocks);
584
585       for (size_t j = 0; j < track_blocks.size(); ++j) {
586         block_queue.push(track_blocks[j]);
587       }
588
589       if (msi[i].last_blocks_estimated_duration != -1) {
590         EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(
591             msi[i].last_blocks_estimated_duration));
592       }
593     }
594     return GenerateCluster(block_queue, false);
595   }
596
597   void AppendMuxedCluster(const std::vector<MuxedStreamInfo> msi) {
598     ASSERT_TRUE(AppendCluster(kSourceId, GenerateMuxedCluster(msi)));
599   }
600
601   bool AppendData(const std::string& source_id,
602                   const uint8_t* data,
603                   size_t length) {
604     EXPECT_CALL(host_, OnBufferedTimeRangesChanged(_)).Times(AnyNumber());
605
606     return demuxer_->AppendData(
607         source_id, data, length, append_window_start_for_next_append_,
608         append_window_end_for_next_append_, &timestamp_offset_map_[source_id]);
609   }
610
611   bool AppendDataInPieces(const uint8_t* data, size_t length) {
612     return AppendDataInPieces(data, length, 7);
613   }
614
615   bool AppendDataInPieces(const uint8_t* data,
616                           size_t length,
617                           size_t piece_size) {
618     const uint8_t* start = data;
619     const uint8_t* end = data + length;
620     while (start < end) {
621       size_t append_size = std::min(piece_size,
622                                     static_cast<size_t>(end - start));
623       if (!AppendData(start, append_size))
624         return false;
625       start += append_size;
626     }
627     return true;
628   }
629
630   bool AppendInitSegment(int stream_flags) {
631     return AppendInitSegmentWithSourceId(kSourceId, stream_flags);
632   }
633
634   bool AppendInitSegmentWithSourceId(const std::string& source_id,
635                                      int stream_flags) {
636     return AppendInitSegmentWithEncryptedInfo(source_id, stream_flags, false,
637                                               false);
638   }
639
640   bool AppendInitSegmentWithEncryptedInfo(const std::string& source_id,
641                                           int stream_flags,
642                                           bool is_audio_encrypted,
643                                           bool is_video_encrypted) {
644     std::unique_ptr<uint8_t[]> info_tracks;
645     int info_tracks_size = 0;
646     CreateInitSegment(stream_flags,
647                       is_audio_encrypted, is_video_encrypted,
648                       &info_tracks, &info_tracks_size);
649     return AppendData(source_id, info_tracks.get(), info_tracks_size);
650   }
651
652   void AppendGarbage() {
653     // Fill up an array with gibberish.
654     int garbage_cluster_size = 10;
655     std::unique_ptr<uint8_t[]> garbage_cluster(
656         new uint8_t[garbage_cluster_size]);
657     for (int i = 0; i < garbage_cluster_size; ++i)
658       garbage_cluster[i] = i;
659     ASSERT_FALSE(AppendData(garbage_cluster.get(), garbage_cluster_size));
660   }
661
662   PipelineStatusCallback CreateInitDoneCallback(
663       base::TimeDelta expected_duration,
664       PipelineStatus expected_status) {
665     if (expected_duration != kNoTimestamp)
666       EXPECT_CALL(host_, SetDuration(expected_duration));
667     return CreateInitDoneCallback(expected_status);
668   }
669
670   PipelineStatusCallback CreateInitDoneCallback(
671       PipelineStatus expected_status) {
672     EXPECT_CALL(*this, DemuxerInitialized(expected_status));
673     return base::BindOnce(&ChunkDemuxerTest::DemuxerInitialized,
674                           base::Unretained(this));
675   }
676
677   enum StreamFlags {
678     HAS_AUDIO = 1 << 0,
679     HAS_VIDEO = 1 << 1,
680     USE_ALTERNATE_AUDIO_TRACK_ID = 1 << 3,
681     USE_ALTERNATE_VIDEO_TRACK_ID = 1 << 4,
682     USE_ALTERNATE_TEXT_TRACK_ID = 1 << 5,
683   };
684
685   bool InitDemuxer(int stream_flags) {
686     return InitDemuxerWithEncryptionInfo(stream_flags, false, false);
687   }
688
689   void ExpectInitMediaLogs(int stream_flags) {
690     if (stream_flags & HAS_VIDEO)
691       EXPECT_FOUND_CODEC_NAME(Video, "vp8");
692     if (stream_flags & HAS_AUDIO)
693       EXPECT_FOUND_CODEC_NAME(Audio, "vorbis");
694   }
695
696   bool InitDemuxerWithEncryptionInfo(
697       int stream_flags, bool is_audio_encrypted, bool is_video_encrypted) {
698     PipelineStatus expected_status =
699         (stream_flags != 0) ? PIPELINE_OK : CHUNK_DEMUXER_ERROR_APPEND_FAILED;
700
701     base::TimeDelta expected_duration = kNoTimestamp;
702     if (expected_status == PIPELINE_OK)
703       expected_duration = kDefaultDuration();
704
705     EXPECT_CALL(*this, DemuxerOpened());
706
707     if (is_audio_encrypted || is_video_encrypted) {
708       DCHECK(!is_audio_encrypted || stream_flags & HAS_AUDIO);
709       DCHECK(!is_video_encrypted || stream_flags & HAS_VIDEO);
710
711       int need_key_count =
712           (is_audio_encrypted ? 1 : 0) + (is_video_encrypted ? 1 : 0);
713       EXPECT_CALL(*this, OnEncryptedMediaInitData(
714                              EmeInitDataType::WEBM,
715                              std::vector<uint8_t>(
716                                  kEncryptedMediaInitData,
717                                  kEncryptedMediaInitData +
718                                      std::size(kEncryptedMediaInitData))))
719           .Times(Exactly(need_key_count));
720     }
721
722     // Adding expectations prior to CreateInitDoneCallback() here because
723     // InSequence tests require init segment received before duration set. Also,
724     // only expect an init segment received callback if there is actually a
725     // track in it.
726     if (stream_flags != 0) {
727       ExpectInitMediaLogs(stream_flags);
728       EXPECT_CALL(*this, InitSegmentReceivedMock(_));
729     } else {
730       // OnNewConfigs() requires at least one audio, video, or text track.
731       EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vorbis"));
732       EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vp8"));
733       EXPECT_MEDIA_LOG(StreamParsingFailed());
734     }
735
736     demuxer_->Initialize(
737         &host_, CreateInitDoneCallback(expected_duration, expected_status));
738
739     if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk)
740       return false;
741
742     return AppendInitSegmentWithEncryptedInfo(
743         kSourceId, stream_flags, is_audio_encrypted, is_video_encrypted);
744   }
745
746   bool InitDemuxerAudioAndVideoSourcesText(const std::string& audio_id,
747                                            const std::string& video_id) {
748     EXPECT_CALL(*this, DemuxerOpened());
749     demuxer_->Initialize(
750         &host_, CreateInitDoneCallback(kDefaultDuration(), PIPELINE_OK));
751
752     if (AddId(audio_id, HAS_AUDIO) != ChunkDemuxer::kOk)
753       return false;
754     if (AddId(video_id, HAS_VIDEO) != ChunkDemuxer::kOk)
755       return false;
756
757     int audio_flags = HAS_AUDIO;
758     int video_flags = HAS_VIDEO;
759
760     // Note: Unlike InitDemuxerWithEncryptionInfo, this method is currently
761     // incompatible with InSequence tests. Refactoring of the duration
762     // set expectation to not be added during CreateInitDoneCallback() could fix
763     // this.
764     ExpectInitMediaLogs(audio_flags);
765     EXPECT_CALL(*this, InitSegmentReceivedMock(_));
766     EXPECT_TRUE(AppendInitSegmentWithSourceId(audio_id, audio_flags));
767
768     ExpectInitMediaLogs(video_flags);
769     EXPECT_CALL(*this, InitSegmentReceivedMock(_));
770     EXPECT_TRUE(AppendInitSegmentWithSourceId(video_id, video_flags));
771     return true;
772   }
773
774   bool InitDemuxerAudioAndVideoSources(const std::string& audio_id,
775                                        const std::string& video_id) {
776     return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id);
777   }
778
779   // Initializes the demuxer with data from 2 files with different
780   // decoder configurations. This is used to test the decoder config change
781   // logic.
782   //
783   // bear-320x240.webm VideoDecoderConfig returns 320x240 for its natural_size()
784   // bear-640x360.webm VideoDecoderConfig returns 640x360 for its natural_size()
785   // The resulting video stream returns data from each file for the following
786   // time ranges.
787   // bear-320x240.webm : [0-501)       [801-2736)
788   // bear-640x360.webm :       [527-760)
789   //
790   // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data size.
791   // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data size.
792   // The resulting audio stream returns data from each file for the following
793   // time ranges.
794   // bear-320x240.webm : [0-524)       [779-2736)
795   // bear-640x360.webm :       [527-759)
796   bool InitDemuxerWithConfigChangeData() {
797     scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm");
798     scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm");
799
800     EXPECT_CALL(*this, DemuxerOpened());
801
802     // Adding expectation prior to CreateInitDoneCallback() here because
803     // InSequence tests require init segment received before duration set.
804     ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO);
805     EXPECT_CALL(*this, InitSegmentReceivedMock(_));
806     demuxer_->Initialize(
807         &host_, CreateInitDoneCallback(base::Milliseconds(2744), PIPELINE_OK));
808
809     if (AddId(kSourceId, HAS_AUDIO | HAS_VIDEO) != ChunkDemuxer::kOk)
810       return false;
811
812     // Append the whole bear1 file.
813     EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)).Times(7);
814     // Expect duration adjustment since actual duration differs slightly from
815     // duration in the init segment.
816     EXPECT_CALL(host_, SetDuration(base::Milliseconds(2768)));
817     EXPECT_TRUE(AppendData(bear1->data(), bear1->data_size()));
818     // Last audio frame has timestamp 2721 and duration 24 (estimated from max
819     // seen so far for audio track).
820     // Last video frame has timestamp 2703 and duration 33 (from TrackEntry
821     // DefaultDuration for video track).
822     CheckExpectedRanges("{ [0,2736) }");
823
824     // Append initialization segment for bear2.
825     // Note: Offsets here and below are derived from
826     // media/test/data/bear-640x360-manifest.js and
827     // media/test/data/bear-320x240-manifest.js which were
828     // generated from media/test/data/bear-640x360.webm and
829     // media/test/data/bear-320x240.webm respectively.
830     EXPECT_CALL(*this, InitSegmentReceivedMock(_));
831     EXPECT_TRUE(AppendData(bear2->data(), 4340));
832
833     // Append a media segment that goes from [0.527000, 1.014000).
834     EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2));
835     EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(527000, 524000, 20000));
836     EXPECT_TRUE(AppendData(bear2->data() + 55290, 18785));
837     CheckExpectedRanges("{ [0,2736) }");
838
839     // Append initialization segment for bear1 and buffer [779-1197)
840     // segment.
841     EXPECT_CALL(*this, InitSegmentReceivedMock(_));
842     EXPECT_TRUE(AppendData(bear1->data(), 4370));
843     EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(24));
844     EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(779000, 759000, 3000));
845     EXPECT_TRUE(AppendData(bear1->data() + 72737, 28183));
846     CheckExpectedRanges("{ [0,2736) }");
847
848     MarkEndOfStream(PIPELINE_OK);
849     return true;
850   }
851
852   void ShutdownDemuxer() {
853     if (demuxer_) {
854       demuxer_->Shutdown();
855       base::RunLoop().RunUntilIdle();
856     }
857   }
858
859   void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64_t timecode) {
860     uint8_t data[] = {0x00};
861     cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
862   }
863
864   std::unique_ptr<Cluster> GenerateCluster(int timecode, int block_count) {
865     return GenerateCluster(timecode, timecode, block_count);
866   }
867
868   std::unique_ptr<Cluster> GenerateCluster(int first_audio_timecode,
869                                            int first_video_timecode,
870                                            int block_count) {
871     return GenerateCluster(first_audio_timecode, first_video_timecode,
872                            block_count, false);
873   }
874   std::unique_ptr<Cluster> GenerateCluster(int first_audio_timecode,
875                                            int first_video_timecode,
876                                            int block_count,
877                                            bool unknown_size) {
878     CHECK_GT(block_count, 0);
879
880     std::priority_queue<BlockInfo> block_queue;
881
882     if (block_count == 1) {
883       block_queue.push(BlockInfo(kAudioTrackNum,
884                                  first_audio_timecode,
885                                  kWebMFlagKeyframe,
886                                  kAudioBlockDuration));
887       return GenerateCluster(block_queue, unknown_size);
888     }
889
890     int audio_timecode = first_audio_timecode;
891     int video_timecode = first_video_timecode;
892
893     // Create simple blocks for everything except the last 2 blocks.
894     // The first video frame must be a key frame.
895     uint8_t video_flag = kWebMFlagKeyframe;
896     for (int i = 0; i < block_count - 2; i++) {
897       if (audio_timecode <= video_timecode) {
898         block_queue.push(BlockInfo(kAudioTrackNum,
899                                    audio_timecode,
900                                    kWebMFlagKeyframe,
901                                    0));
902         audio_timecode += kAudioBlockDuration;
903         continue;
904       }
905
906       block_queue.push(BlockInfo(kVideoTrackNum,
907                                  video_timecode,
908                                  video_flag,
909                                  0));
910       video_timecode += kVideoBlockDuration;
911       video_flag = 0;
912     }
913
914     // Make the last 2 blocks BlockGroups so that they don't get delayed by the
915     // block duration calculation logic.
916     block_queue.push(BlockInfo(kAudioTrackNum,
917                                audio_timecode,
918                                kWebMFlagKeyframe,
919                                kAudioBlockDuration));
920     block_queue.push(BlockInfo(kVideoTrackNum,
921                                video_timecode,
922                                video_flag,
923                                kVideoBlockDuration));
924
925     return GenerateCluster(block_queue, unknown_size);
926   }
927
928   std::unique_ptr<Cluster> GenerateSingleStreamCluster(int timecode,
929                                                        int end_timecode,
930                                                        int track_number,
931                                                        int block_duration) {
932     CHECK_GT(end_timecode, timecode);
933
934     // Ensure we can obtain a valid pointer to a region of data of |block_size_|
935     // length.
936     std::vector<uint8_t> data(block_size_ ? block_size_ : 1);
937
938     ClusterBuilder cb;
939     cb.SetClusterTimecode(timecode);
940
941     // Create simple blocks for everything except the last block.
942     while (timecode < (end_timecode - block_duration)) {
943       cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe, &data[0],
944                         block_size_);
945       timecode += block_duration;
946     }
947
948     cb.AddBlockGroup(track_number, timecode, block_duration, kWebMFlagKeyframe,
949                      static_cast<bool>(kWebMFlagKeyframe), &data[0],
950                      block_size_);
951
952     return cb.Finish();
953   }
954
955   DemuxerStream* GetStream(DemuxerStream::Type type) {
956     std::vector<DemuxerStream*> streams = demuxer_->GetAllStreams();
957     for (auto* stream : streams) {
958       if (stream->type() == type)
959         return stream;
960     }
961     return nullptr;
962   }
963
964   void Read(DemuxerStream::Type type, DemuxerStream::ReadCB read_cb) {
965     GetStream(type)->Read(std::move(read_cb));
966     base::RunLoop().RunUntilIdle();
967   }
968
969   void ReadAudio(DemuxerStream::ReadCB read_cb) {
970     Read(DemuxerStream::AUDIO, std::move(read_cb));
971   }
972
973   void ReadVideo(DemuxerStream::ReadCB read_cb) {
974     Read(DemuxerStream::VIDEO, std::move(read_cb));
975   }
976
977   void GenerateExpectedReads(int timecode, int block_count) {
978     GenerateExpectedReads(timecode, timecode, block_count);
979   }
980
981   void GenerateExpectedReads(int start_audio_timecode,
982                              int start_video_timecode,
983                              int block_count) {
984     CHECK_GT(block_count, 0);
985
986     if (block_count == 1) {
987       ExpectRead(DemuxerStream::AUDIO, start_audio_timecode);
988       return;
989     }
990
991     int audio_timecode = start_audio_timecode;
992     int video_timecode = start_video_timecode;
993
994     for (int i = 0; i < block_count; i++) {
995       if (audio_timecode <= video_timecode) {
996         ExpectRead(DemuxerStream::AUDIO, audio_timecode);
997         audio_timecode += kAudioBlockDuration;
998         continue;
999       }
1000
1001       ExpectRead(DemuxerStream::VIDEO, video_timecode);
1002       video_timecode += kVideoBlockDuration;
1003     }
1004   }
1005
1006   void GenerateSingleStreamExpectedReads(int timecode,
1007                                          int block_count,
1008                                          DemuxerStream::Type type,
1009                                          int block_duration) {
1010     CHECK_GT(block_count, 0);
1011     int stream_timecode = timecode;
1012
1013     for (int i = 0; i < block_count; i++) {
1014       ExpectRead(type, stream_timecode);
1015       stream_timecode += block_duration;
1016     }
1017   }
1018
1019   void GenerateAudioStreamExpectedReads(int timecode, int block_count) {
1020     GenerateSingleStreamExpectedReads(
1021         timecode, block_count, DemuxerStream::AUDIO, kAudioBlockDuration);
1022   }
1023
1024   void GenerateVideoStreamExpectedReads(int timecode, int block_count) {
1025     GenerateSingleStreamExpectedReads(
1026         timecode, block_count, DemuxerStream::VIDEO, kVideoBlockDuration);
1027   }
1028
1029   std::unique_ptr<Cluster> GenerateEmptyCluster(int timecode) {
1030     ClusterBuilder cb;
1031     cb.SetClusterTimecode(timecode);
1032     return cb.Finish();
1033   }
1034
1035   void CheckExpectedRangesForMediaSource(const std::string& expected) {
1036     CheckExpectedRanges(demuxer_->GetBufferedRanges(), expected);
1037   }
1038
1039   void CheckExpectedRanges(const std::string& expected) {
1040     CheckExpectedRanges(kSourceId, expected);
1041     CheckExpectedRangesForMediaSource(expected);
1042   }
1043
1044   void CheckExpectedRanges(const std::string& id, const std::string& expected) {
1045     CheckExpectedRanges(demuxer_->GetBufferedRanges(id), expected);
1046   }
1047
1048   void CheckExpectedRanges(DemuxerStream::Type type,
1049                            const std::string& expected) {
1050     ChunkDemuxerStream* stream =
1051         static_cast<ChunkDemuxerStream*>(GetStream(type));
1052     CheckExpectedRanges(stream->GetBufferedRanges(kDefaultDuration()),
1053                         expected);
1054   }
1055
1056   void CheckExpectedRanges(const Ranges<base::TimeDelta>& r,
1057                            const std::string& expected) {
1058     std::stringstream ss;
1059     ss << "{ ";
1060     for (size_t i = 0; i < r.size(); ++i) {
1061       ss << "[" << r.start(i).InMilliseconds() << ","
1062          << r.end(i).InMilliseconds() << ") ";
1063     }
1064     ss << "}";
1065     EXPECT_EQ(expected, ss.str());
1066   }
1067
1068   MOCK_METHOD2(ReadDone,
1069                void(DemuxerStream::Status status,
1070                     scoped_refptr<DecoderBuffer>));
1071
1072   void StoreStatusAndBuffer(DemuxerStream::Status* status_out,
1073                             scoped_refptr<DecoderBuffer>* buffer_out,
1074                             DemuxerStream::Status status,
1075                             scoped_refptr<DecoderBuffer> buffer) {
1076     *status_out = status;
1077     *buffer_out = buffer;
1078   }
1079
1080   void ReadUntilNotOkOrEndOfStream(DemuxerStream::Type type,
1081                                    DemuxerStream::Status* status,
1082                                    base::TimeDelta* last_timestamp) {
1083     DemuxerStream* stream = GetStream(type);
1084     scoped_refptr<DecoderBuffer> buffer;
1085
1086     *last_timestamp = kNoTimestamp;
1087     do {
1088       stream->Read(base::BindOnce(&ChunkDemuxerTest::StoreStatusAndBuffer,
1089                                   base::Unretained(this), status, &buffer));
1090       base::RunLoop().RunUntilIdle();
1091       if (*status == DemuxerStream::kOk && !buffer->end_of_stream())
1092         *last_timestamp = buffer->timestamp();
1093     } while (*status == DemuxerStream::kOk && !buffer->end_of_stream());
1094   }
1095
1096   void ExpectEndOfStream(DemuxerStream::Type type) {
1097     EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, IsEndOfStream()));
1098     GetStream(type)->Read(
1099         base::BindOnce(&ChunkDemuxerTest::ReadDone, base::Unretained(this)));
1100     base::RunLoop().RunUntilIdle();
1101   }
1102
1103   void ExpectRead(DemuxerStream::Type type, int64_t timestamp_in_ms) {
1104     EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
1105                                 HasTimestamp(timestamp_in_ms)));
1106     GetStream(type)->Read(
1107         base::BindOnce(&ChunkDemuxerTest::ReadDone, base::Unretained(this)));
1108     base::RunLoop().RunUntilIdle();
1109   }
1110
1111   void ExpectConfigChanged(DemuxerStream::Type type) {
1112     EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
1113     GetStream(type)->Read(
1114         base::BindOnce(&ChunkDemuxerTest::ReadDone, base::Unretained(this)));
1115     base::RunLoop().RunUntilIdle();
1116   }
1117
1118   void CheckExpectedBuffers(DemuxerStream* stream,
1119                             const std::string& expected) {
1120     std::vector<std::string> timestamps = base::SplitString(
1121         expected, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
1122     std::stringstream ss;
1123     for (size_t i = 0; i < timestamps.size(); ++i) {
1124       // Initialize status to kAborted since it's possible for Read() to return
1125       // without calling StoreStatusAndBuffer() if it doesn't have any buffers
1126       // left to return.
1127       DemuxerStream::Status status = DemuxerStream::kAborted;
1128       scoped_refptr<DecoderBuffer> buffer;
1129       stream->Read(base::BindOnce(&ChunkDemuxerTest::StoreStatusAndBuffer,
1130                                   base::Unretained(this), &status, &buffer));
1131       base::RunLoop().RunUntilIdle();
1132       if (status != DemuxerStream::kOk || buffer->end_of_stream())
1133         break;
1134
1135       if (i > 0)
1136         ss << " ";
1137       ss << buffer->timestamp().InMilliseconds();
1138
1139       if (buffer->is_key_frame())
1140         ss << "K";
1141
1142       // Handle preroll buffers.
1143       if (base::EndsWith(timestamps[i], "P", base::CompareCase::SENSITIVE)) {
1144         ASSERT_EQ(kInfiniteDuration, buffer->discard_padding().first);
1145         ASSERT_EQ(base::TimeDelta(), buffer->discard_padding().second);
1146         ss << "P";
1147       }
1148     }
1149     EXPECT_EQ(expected, ss.str());
1150   }
1151
1152   MOCK_METHOD1(Checkpoint, void(int id));
1153
1154   struct BufferTimestamps {
1155     int video_time_ms;
1156     int audio_time_ms;
1157   };
1158   static const int kSkip = -1;
1159
1160   // Test parsing a WebM file.
1161   // |filename| - The name of the file in media/test/data to parse.
1162   // |timestamps| - The expected timestamps on the parsed buffers.
1163   //    a timestamp of kSkip indicates that a Read() call for that stream
1164   //    shouldn't be made on that iteration of the loop. If both streams have
1165   //    a kSkip then the loop will terminate.
1166   bool ParseWebMFile(const std::string& filename,
1167                      const BufferTimestamps* timestamps,
1168                      const base::TimeDelta& duration) {
1169     return ParseWebMFile(filename, timestamps, duration, HAS_AUDIO | HAS_VIDEO);
1170   }
1171
1172   bool ParseWebMFile(const std::string& filename,
1173                      const BufferTimestamps* timestamps,
1174                      const base::TimeDelta& duration,
1175                      int stream_flags) {
1176     EXPECT_CALL(*this, DemuxerOpened());
1177     demuxer_->Initialize(&host_, CreateInitDoneCallback(duration, PIPELINE_OK));
1178
1179     if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk)
1180       return false;
1181
1182     // Read a WebM file into memory and send the data to the demuxer.
1183     scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
1184     EXPECT_CALL(*this, InitSegmentReceivedMock(_));
1185
1186     EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
1187
1188     // Verify that the timestamps on the first few packets match what we
1189     // expect.
1190     for (size_t i = 0;
1191          (timestamps[i].audio_time_ms != kSkip ||
1192           timestamps[i].video_time_ms != kSkip);
1193          i++) {
1194       bool audio_read_done = false;
1195       bool video_read_done = false;
1196
1197       if (timestamps[i].audio_time_ms != kSkip) {
1198         ReadAudio(base::BindOnce(
1199             &OnReadDone, base::Milliseconds(timestamps[i].audio_time_ms),
1200             &audio_read_done));
1201         EXPECT_TRUE(audio_read_done);
1202       }
1203
1204       if (timestamps[i].video_time_ms != kSkip) {
1205         ReadVideo(base::BindOnce(
1206             &OnReadDone, base::Milliseconds(timestamps[i].video_time_ms),
1207             &video_read_done));
1208         EXPECT_TRUE(video_read_done);
1209       }
1210     }
1211
1212     return true;
1213   }
1214
1215   MOCK_METHOD0(DemuxerOpened, void());
1216   MOCK_METHOD2(OnEncryptedMediaInitData,
1217                void(EmeInitDataType init_data_type,
1218                     const std::vector<uint8_t>& init_data));
1219
1220   MOCK_METHOD1(InitSegmentReceivedMock, void(std::unique_ptr<MediaTracks>&));
1221   MOCK_METHOD1(OnParseWarningMock, void(const SourceBufferParseWarning));
1222
1223   void OnProgress() { did_progress_ = true; }
1224
1225   bool DidProgress() {
1226     bool result = did_progress_;
1227     did_progress_ = false;
1228     return result;
1229   }
1230
1231   void Seek(base::TimeDelta seek_time) {
1232     demuxer_->StartWaitingForSeek(seek_time);
1233     demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
1234     base::RunLoop().RunUntilIdle();
1235   }
1236
1237   void MarkEndOfStream(PipelineStatus status) {
1238     demuxer_->MarkEndOfStream(status);
1239     base::RunLoop().RunUntilIdle();
1240   }
1241
1242   bool SetTimestampOffset(const std::string& id,
1243                           base::TimeDelta timestamp_offset) {
1244     if (demuxer_->IsParsingMediaSegment(id))
1245       return false;
1246
1247     timestamp_offset_map_[id] = timestamp_offset;
1248     return true;
1249   }
1250
1251   base::test::TaskEnvironment task_environment_;
1252
1253   StrictMock<MockMediaLog> media_log_;
1254
1255   MockDemuxerHost host_;
1256
1257   std::unique_ptr<ChunkDemuxer> demuxer_;
1258   Demuxer::MediaTracksUpdatedCB init_segment_received_cb_;
1259
1260   bool did_progress_;
1261
1262   base::TimeDelta append_window_start_for_next_append_;
1263   base::TimeDelta append_window_end_for_next_append_;
1264
1265   // The size of coded frame data for a WebM SimpleBlock or BlockGroup muxed
1266   // into a test cluster. This defaults to |kBlockSize|, but can be changed to
1267   // test behavior.
1268   size_t block_size_ = kBlockSize;
1269
1270   // Map of source id to timestamp offset to use for the next AppendData()
1271   // operation for that source id.
1272   std::map<std::string, base::TimeDelta> timestamp_offset_map_;
1273
1274  public:
1275   void InitSegmentReceived(std::unique_ptr<MediaTracks> tracks) {
1276     DCHECK(tracks.get());
1277     DCHECK_GT(tracks->tracks().size(), 0u);
1278
1279     // Verify that track ids are unique.
1280     std::set<MediaTrack::Id> track_ids;
1281     for (const auto& track : tracks->tracks()) {
1282       EXPECT_EQ(track_ids.end(), track_ids.find(track->id()));
1283       track_ids.insert(track->id());
1284     }
1285
1286     InitSegmentReceivedMock(tracks);
1287   }
1288 };
1289
1290 TEST_F(ChunkDemuxerTest, Init) {
1291   InSequence s;
1292
1293   // Test no streams, audio-only, video-only, and audio & video scenarios.
1294   // Audio and video streams can be encrypted or not encrypted.
1295   for (int i = 0; i < 16; i++) {
1296     bool has_audio = (i & 0x1) != 0;
1297     bool has_video = (i & 0x2) != 0;
1298     bool is_audio_encrypted = (i & 0x4) != 0;
1299     bool is_video_encrypted = (i & 0x8) != 0;
1300
1301     // No test on invalid combination.
1302     if ((!has_audio && is_audio_encrypted) ||
1303         (!has_video && is_video_encrypted)) {
1304       continue;
1305     }
1306
1307     CreateNewDemuxer();
1308
1309     int stream_flags = 0;
1310     if (has_audio)
1311       stream_flags |= HAS_AUDIO;
1312
1313     if (has_video)
1314       stream_flags |= HAS_VIDEO;
1315
1316     if (has_audio || has_video) {
1317       ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
1318           stream_flags, is_audio_encrypted, is_video_encrypted));
1319     } else {
1320       ASSERT_FALSE(InitDemuxerWithEncryptionInfo(
1321           stream_flags, is_audio_encrypted, is_video_encrypted));
1322     }
1323
1324     DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
1325     if (has_audio) {
1326       ASSERT_TRUE(audio_stream);
1327
1328       const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
1329       EXPECT_EQ(AudioCodec::kVorbis, config.codec());
1330       EXPECT_EQ(32, config.bits_per_channel());
1331       EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout());
1332       EXPECT_EQ(44100, config.samples_per_second());
1333       EXPECT_GT(config.extra_data().size(), 0u);
1334       EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
1335       EXPECT_EQ(is_audio_encrypted,
1336                 audio_stream->audio_decoder_config().is_encrypted());
1337     } else {
1338       EXPECT_FALSE(audio_stream);
1339     }
1340
1341     DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
1342     if (has_video) {
1343       EXPECT_TRUE(video_stream);
1344       EXPECT_EQ(is_video_encrypted,
1345                 video_stream->video_decoder_config().is_encrypted());
1346     } else {
1347       EXPECT_FALSE(video_stream);
1348     }
1349
1350     for (auto* stream : demuxer_->GetAllStreams())
1351       EXPECT_TRUE(stream->SupportsConfigChanges());
1352
1353     ShutdownDemuxer();
1354     demuxer_.reset();
1355   }
1356 }
1357
1358 TEST_F(ChunkDemuxerTest, AddIdDuringOpenCallback) {
1359   // Tests that users may call |ChunkDemuxer::AddId| (or really any method that
1360   // acquires |ChunkDemuxer::lock_|) during the open callback.
1361   EXPECT_CALL(*this, DemuxerOpened()).WillOnce([this]() { this->AddId(); });
1362
1363   CreateNewDemuxer();
1364   demuxer_->Initialize(&host_, base::DoNothing());
1365   ShutdownDemuxer();
1366 }
1367
1368 TEST_F(ChunkDemuxerTest, AudioVideoTrackIdsChange) {
1369   // Test with 1 audio and 1 video stream. Send a second init segment in which
1370   // the audio and video track IDs change. Verify that appended buffers before
1371   // and after the second init segment map to the same underlying track buffers.
1372   CreateNewDemuxer();
1373   ASSERT_TRUE(
1374       InitDemuxerWithEncryptionInfo(HAS_AUDIO | HAS_VIDEO, false, false));
1375   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
1376   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
1377   ASSERT_TRUE(audio_stream);
1378   ASSERT_TRUE(video_stream);
1379
1380   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23),
1381                      MuxedStreamInfo(kVideoTrackNum, "0K 30", 30));
1382   CheckExpectedRanges("{ [0,46) }");
1383
1384   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
1385   ASSERT_TRUE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO |
1386                                 USE_ALTERNATE_AUDIO_TRACK_ID |
1387                                 USE_ALTERNATE_VIDEO_TRACK_ID));
1388   AppendMuxedCluster(MuxedStreamInfo(kAlternateAudioTrackNum, "46K 69K", 63),
1389                      MuxedStreamInfo(kAlternateVideoTrackNum, "60K", 23));
1390   CheckExpectedRanges("{ [0,92) }");
1391   CheckExpectedBuffers(audio_stream, "0K 23K 46K 69K");
1392   CheckExpectedBuffers(video_stream, "0K 30 60K");
1393
1394   ShutdownDemuxer();
1395 }
1396
1397 TEST_F(ChunkDemuxerTest, InitSegmentSetsNeedRandomAccessPointFlag) {
1398   // Tests that non-key-frames following an init segment are allowed
1399   // and dropped, as expected if the initialization segment received
1400   // algorithm correctly sets the needs random access point flag to true for all
1401   // track buffers. Note that the first initialization segment is insufficient
1402   // to fully test this since needs random access point flag initializes to
1403   // true.
1404   CreateNewDemuxer();
1405   ASSERT_TRUE(
1406       InitDemuxerWithEncryptionInfo(HAS_AUDIO | HAS_VIDEO, false, false));
1407   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
1408   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
1409   ASSERT_TRUE(audio_stream && video_stream);
1410
1411   AppendMuxedCluster(
1412       MuxedStreamInfo(kAudioTrackNum, "23K",
1413                       WebMClusterParser::kDefaultAudioBufferDurationInMs),
1414       MuxedStreamInfo(kVideoTrackNum, "0 30K", 30));
1415   CheckExpectedRanges("{ [23,46) }");
1416
1417   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
1418   ASSERT_TRUE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
1419   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23),
1420                      MuxedStreamInfo(kVideoTrackNum, "60 90K", 30));
1421   CheckExpectedRanges("{ [23,92) }");
1422
1423   CheckExpectedBuffers(audio_stream, "23K 46K 69K");
1424   CheckExpectedBuffers(video_stream, "30K 90K");
1425 }
1426
1427 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) {
1428   EXPECT_CALL(*this, DemuxerOpened());
1429   demuxer_->Initialize(&host_,
1430                        base::BindOnce(&ChunkDemuxerTest::DemuxerInitialized,
1431                                       base::Unretained(this)));
1432
1433   EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
1434   EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk);
1435
1436   ExpectInitMediaLogs(HAS_AUDIO);
1437   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
1438   ASSERT_TRUE(AppendInitSegmentWithSourceId("audio", HAS_AUDIO));
1439
1440   ShutdownDemuxer();
1441 }
1442
1443 // Verifies that all streams waiting for data receive an end of stream
1444 // buffer when Shutdown() is called.
1445 TEST_F(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) {
1446   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1447
1448   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
1449   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
1450
1451   bool audio_read_done = false;
1452   bool video_read_done = false;
1453   audio_stream->Read(base::BindOnce(&OnReadDone_EOSExpected, &audio_read_done));
1454   video_stream->Read(base::BindOnce(&OnReadDone_EOSExpected, &video_read_done));
1455   base::RunLoop().RunUntilIdle();
1456
1457   EXPECT_FALSE(audio_read_done);
1458   EXPECT_FALSE(video_read_done);
1459
1460   ShutdownDemuxer();
1461
1462   EXPECT_TRUE(audio_read_done);
1463   EXPECT_TRUE(video_read_done);
1464 }
1465
1466 // Test that Seek() completes successfully when the first cluster
1467 // arrives.
1468 TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) {
1469   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1470   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1471
1472   InSequence s;
1473
1474   EXPECT_CALL(*this, Checkpoint(1));
1475
1476   Seek(base::Milliseconds(46));
1477
1478   EXPECT_CALL(*this, Checkpoint(2));
1479
1480   Checkpoint(1);
1481
1482   ASSERT_TRUE(AppendCluster(kDefaultSecondCluster()));
1483
1484   base::RunLoop().RunUntilIdle();
1485
1486   Checkpoint(2);
1487 }
1488
1489 // Test that parsing errors are handled for clusters appended after init.
1490 TEST_F(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) {
1491   InSequence s;
1492   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1493
1494   EXPECT_MEDIA_LOG(StreamParsingFailed());
1495   EXPECT_CALL(host_,
1496               OnDemuxerError(HasStatusCode(CHUNK_DEMUXER_ERROR_APPEND_FAILED)));
1497   AppendGarbage();
1498 }
1499
1500 // Test the case where a Seek() is requested while the parser
1501 // is in the middle of cluster. This is to verify that the parser
1502 // does not reset itself on a seek.
1503 TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) {
1504   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1505
1506   InSequence s;
1507
1508   std::unique_ptr<Cluster> cluster_a(GenerateCluster(0, 6));
1509
1510   // Split the cluster into two appends at an arbitrary point near the end.
1511   int first_append_size = cluster_a->size() - 11;
1512   int second_append_size = cluster_a->size() - first_append_size;
1513
1514   // Append the first part of the cluster.
1515   ASSERT_TRUE(AppendData(cluster_a->data(), first_append_size));
1516
1517   ExpectRead(DemuxerStream::AUDIO, 0);
1518   ExpectRead(DemuxerStream::VIDEO, 0);
1519   ExpectRead(DemuxerStream::AUDIO, kAudioBlockDuration);
1520
1521   Seek(base::Seconds(5));
1522
1523   // Append the rest of the cluster.
1524   ASSERT_TRUE(
1525       AppendData(cluster_a->data() + first_append_size, second_append_size));
1526
1527   // Append the new cluster and verify that only the blocks
1528   // in the new cluster are returned.
1529   ASSERT_TRUE(AppendCluster(GenerateCluster(5000, 6)));
1530   GenerateExpectedReads(5000, 6);
1531 }
1532
1533 // Test the case where AppendData() is called before Init().
1534 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) {
1535   std::unique_ptr<uint8_t[]> info_tracks;
1536   int info_tracks_size = 0;
1537   CreateInitSegment(HAS_AUDIO | HAS_VIDEO,
1538                     false, false, &info_tracks, &info_tracks_size);
1539   ASSERT_FALSE(demuxer_->AppendData(
1540       kSourceId, info_tracks.get(), info_tracks_size,
1541       append_window_start_for_next_append_, append_window_end_for_next_append_,
1542       &timestamp_offset_map_[kSourceId]));
1543 }
1544
1545 // Make sure Read() callbacks are dispatched with the proper data.
1546 TEST_F(ChunkDemuxerTest, Read) {
1547   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1548
1549   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1550
1551   bool audio_read_done = false;
1552   bool video_read_done = false;
1553   ReadAudio(
1554       base::BindOnce(&OnReadDone, base::Milliseconds(0), &audio_read_done));
1555   ReadVideo(
1556       base::BindOnce(&OnReadDone, base::Milliseconds(0), &video_read_done));
1557
1558   EXPECT_TRUE(audio_read_done);
1559   EXPECT_TRUE(video_read_done);
1560 }
1561
1562 TEST_F(ChunkDemuxerTest, OutOfOrderClusters) {
1563   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1564   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
1565   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
1566
1567   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1568   CheckExpectedBuffers(audio_stream, "0K 23K");
1569   CheckExpectedBuffers(video_stream, "0K 33");
1570   // Note: splice trimming changes durations. These are verified in lower level
1571   // tests. See SourceBufferStreamTest.Audio_SpliceTrimmingForOverlap.
1572   EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(10000, 0, 13000));
1573   ASSERT_TRUE(AppendCluster(GenerateCluster(10, 4)));
1574   Seek(base::TimeDelta());
1575   CheckExpectedBuffers(audio_stream, "0K 10K 33K");
1576   CheckExpectedBuffers(video_stream, "0K 10K 43");
1577
1578   // Make sure that AppendCluster() does not fail with a cluster that has
1579   // overlaps with the previously appended cluster.
1580   EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(5000, 0, 5000));
1581   ASSERT_TRUE(AppendCluster(GenerateCluster(5, 4)));
1582   Seek(base::TimeDelta());
1583   CheckExpectedBuffers(audio_stream, "0K 5K 28K");
1584   CheckExpectedBuffers(video_stream, "0K 5K 38");
1585
1586   // Verify that AppendData() can still accept more data.
1587   std::unique_ptr<Cluster> cluster_c(GenerateCluster(45, 2));
1588   EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(45000, 28000, 6000));
1589   ASSERT_TRUE(demuxer_->AppendData(
1590       kSourceId, cluster_c->data(), cluster_c->size(),
1591       append_window_start_for_next_append_, append_window_end_for_next_append_,
1592       &timestamp_offset_map_[kSourceId]));
1593   Seek(base::Milliseconds(45));
1594   CheckExpectedBuffers(audio_stream, "45K");
1595   CheckExpectedBuffers(video_stream, "45K");
1596 }
1597
1598 TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) {
1599   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1600   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1601
1602   ClusterBuilder cb;
1603
1604   // Test the case where block timecodes are not monotonically
1605   // increasing but stay above the cluster timecode.
1606   cb.SetClusterTimecode(5);
1607   AddSimpleBlock(&cb, kAudioTrackNum, 5);
1608   AddSimpleBlock(&cb, kVideoTrackNum, 10);
1609   AddSimpleBlock(&cb, kAudioTrackNum, 7);
1610   AddSimpleBlock(&cb, kVideoTrackNum, 15);
1611
1612   EXPECT_MEDIA_LOG(WebMOutOfOrderTimecode());
1613   EXPECT_MEDIA_LOG(StreamParsingFailed());
1614   EXPECT_CALL(host_,
1615               OnDemuxerError(HasStatusCode(CHUNK_DEMUXER_ERROR_APPEND_FAILED)));
1616   ASSERT_FALSE(AppendCluster(cb.Finish()));
1617
1618   // Verify that AppendData() ignores data after the error.
1619   std::unique_ptr<Cluster> cluster_b(GenerateCluster(20, 2));
1620   ASSERT_FALSE(demuxer_->AppendData(
1621       kSourceId, cluster_b->data(), cluster_b->size(),
1622       append_window_start_for_next_append_, append_window_end_for_next_append_,
1623       &timestamp_offset_map_[kSourceId]));
1624 }
1625
1626 TEST_F(ChunkDemuxerTest, BeforeClusterTimecode) {
1627   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1628   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1629
1630   ClusterBuilder cb;
1631   uint8_t data[] = {0x00};
1632
1633   // Test timecodes before the cluster timecode are allowed now. This next
1634   // cluster mimics the blocks in kDefaultSecondCluster(), but with a cluster
1635   // timecode in the future. The blocks will have relative timestamps that
1636   // should make them appear as if they are precisely those in
1637   // kDefaultSecondCluster().
1638   cb.SetClusterTimecode(1000);  // In the future relative to the next blocks.
1639   cb.AddSimpleBlock(kAudioTrackNum, 46, kWebMFlagKeyframe, data, sizeof(data));
1640   cb.AddSimpleBlock(kVideoTrackNum, 66, kWebMFlagKeyframe, data, sizeof(data));
1641   cb.AddSimpleBlock(kAudioTrackNum, 69, kWebMFlagKeyframe, data, sizeof(data));
1642   cb.AddBlockGroup(kAudioTrackNum, 92, kAudioBlockDuration, kWebMFlagKeyframe,
1643                    true, data, sizeof(data));
1644   cb.AddBlockGroup(kVideoTrackNum, 99, kVideoBlockDuration, 0, false, data,
1645                    sizeof(data));
1646
1647   ASSERT_TRUE(AppendCluster(cb.Finish()));
1648   GenerateExpectedReads(0, 9);
1649 }
1650
1651 TEST_F(ChunkDemuxerTest, NonMonotonicButBeforeClusterTimecode) {
1652   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1653   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1654
1655   ClusterBuilder cb;
1656   uint8_t data[] = {0x00};
1657
1658   // Test timecodes going backwards and including values less than the cluster
1659   // timecode.
1660   cb.SetClusterTimecode(1000);
1661   cb.AddSimpleBlock(kAudioTrackNum, 69, kWebMFlagKeyframe, data, sizeof(data));
1662   cb.AddSimpleBlock(kVideoTrackNum, 99, kWebMFlagKeyframe, data, sizeof(data));
1663   cb.AddSimpleBlock(kAudioTrackNum, 46, kWebMFlagKeyframe, data, sizeof(data));
1664
1665   EXPECT_MEDIA_LOG(WebMOutOfOrderTimecode());
1666   EXPECT_MEDIA_LOG(StreamParsingFailed());
1667   EXPECT_CALL(host_,
1668               OnDemuxerError(HasStatusCode(CHUNK_DEMUXER_ERROR_APPEND_FAILED)));
1669   ASSERT_FALSE(AppendCluster(cb.Finish()));
1670
1671   // Verify that AppendData() ignores data after the error.
1672   std::unique_ptr<Cluster> cluster_b(GenerateCluster(6, 2));
1673   ASSERT_FALSE(demuxer_->AppendData(
1674       kSourceId, cluster_b->data(), cluster_b->size(),
1675       append_window_start_for_next_append_, append_window_end_for_next_append_,
1676       &timestamp_offset_map_[kSourceId]));
1677 }
1678
1679 TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) {
1680   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1681   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1682
1683   ClusterBuilder cb;
1684
1685   // Test monotonic increasing timestamps on a per stream
1686   // basis.
1687   cb.SetClusterTimecode(4);
1688   AddSimpleBlock(&cb, kAudioTrackNum, 5);
1689   AddSimpleBlock(&cb, kVideoTrackNum, 5);
1690   AddSimpleBlock(&cb, kAudioTrackNum, 4);
1691   AddSimpleBlock(&cb, kVideoTrackNum, 7);
1692
1693   EXPECT_MEDIA_LOG(WebMOutOfOrderTimecode());
1694   EXPECT_MEDIA_LOG(StreamParsingFailed());
1695   EXPECT_CALL(host_,
1696               OnDemuxerError(HasStatusCode(CHUNK_DEMUXER_ERROR_APPEND_FAILED)));
1697   ASSERT_FALSE(AppendCluster(cb.Finish()));
1698 }
1699
1700 // Test the case where a cluster is passed to AppendCluster() before
1701 // INFO & TRACKS data.
1702 TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) {
1703   EXPECT_CALL(*this, DemuxerOpened());
1704   demuxer_->Initialize(&host_,
1705                        NewExpectedStatusCB(CHUNK_DEMUXER_ERROR_APPEND_FAILED));
1706
1707   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
1708
1709   EXPECT_MEDIA_LOG(WebMClusterBeforeFirstInfo());
1710   EXPECT_MEDIA_LOG(StreamParsingFailed());
1711   ASSERT_FALSE(AppendCluster(GenerateCluster(0, 1)));
1712 }
1713
1714 // Test cases where we get an MarkEndOfStream() call during initialization.
1715 TEST_F(ChunkDemuxerTest, EOSDuringInit) {
1716   EXPECT_CALL(*this, DemuxerOpened());
1717   demuxer_->Initialize(&host_,
1718                        NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
1719   EXPECT_MEDIA_LOG(EosBeforeHaveMetadata());
1720   MarkEndOfStream(PIPELINE_OK);
1721 }
1722
1723 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) {
1724   EXPECT_CALL(*this, DemuxerOpened());
1725   demuxer_->Initialize(&host_,
1726                        NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
1727
1728   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
1729
1730   CheckExpectedRanges("{ }");
1731
1732   EXPECT_MEDIA_LOG(EosBeforeHaveMetadata());
1733   MarkEndOfStream(PIPELINE_OK);
1734
1735   ShutdownDemuxer();
1736   CheckExpectedRanges("{ }");
1737   demuxer_->RemoveId(kSourceId);
1738   demuxer_.reset();
1739 }
1740
1741 TEST_F(ChunkDemuxerTest, EndOfStreamWithNoMediaAppend) {
1742   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1743
1744   CheckExpectedRanges("{ }");
1745   MarkEndOfStream(PIPELINE_OK);
1746   CheckExpectedRanges("{ }");
1747 }
1748
1749 TEST_F(ChunkDemuxerTest, DecodeErrorEndOfStream) {
1750   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1751
1752   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1753   CheckExpectedRanges(kDefaultFirstClusterRange);
1754
1755   EXPECT_CALL(host_, OnDemuxerError(HasStatusCode(
1756                          CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR)));
1757   MarkEndOfStream(CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR);
1758   CheckExpectedRanges(kDefaultFirstClusterRange);
1759 }
1760
1761 TEST_F(ChunkDemuxerTest, NetworkErrorEndOfStream) {
1762   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1763
1764   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
1765   CheckExpectedRanges(kDefaultFirstClusterRange);
1766
1767   EXPECT_CALL(host_, OnDemuxerError(HasStatusCode(
1768                          CHUNK_DEMUXER_ERROR_EOS_STATUS_NETWORK_ERROR)));
1769   MarkEndOfStream(CHUNK_DEMUXER_ERROR_EOS_STATUS_NETWORK_ERROR);
1770 }
1771
1772 // Helper class to reduce duplicate code when testing end of stream
1773 // Read() behavior.
1774 class EndOfStreamHelper {
1775  public:
1776   explicit EndOfStreamHelper(DemuxerStream* audio, DemuxerStream* video)
1777       : audio_stream_(audio),
1778         video_stream_(video),
1779         audio_read_done_(false),
1780         video_read_done_(false) {}
1781
1782   EndOfStreamHelper(const EndOfStreamHelper&) = delete;
1783   EndOfStreamHelper& operator=(const EndOfStreamHelper&) = delete;
1784
1785   // Request a read on the audio and video streams.
1786   void RequestReads() {
1787     EXPECT_FALSE(audio_read_done_);
1788     EXPECT_FALSE(video_read_done_);
1789
1790     audio_stream_->Read(
1791         base::BindOnce(&OnEndOfStreamReadDone, &audio_read_done_));
1792     video_stream_->Read(
1793         base::BindOnce(&OnEndOfStreamReadDone, &video_read_done_));
1794     base::RunLoop().RunUntilIdle();
1795   }
1796
1797   // Check to see if |audio_read_done_| and |video_read_done_| variables
1798   // match |expected|.
1799   void CheckIfReadDonesWereCalled(bool expected) {
1800     base::RunLoop().RunUntilIdle();
1801     EXPECT_EQ(expected, audio_read_done_);
1802     EXPECT_EQ(expected, video_read_done_);
1803   }
1804
1805  private:
1806   static void OnEndOfStreamReadDone(bool* called,
1807                                     DemuxerStream::Status status,
1808                                     scoped_refptr<DecoderBuffer> buffer) {
1809     EXPECT_EQ(status, DemuxerStream::kOk);
1810     EXPECT_TRUE(buffer->end_of_stream());
1811     *called = true;
1812   }
1813
1814   raw_ptr<DemuxerStream> audio_stream_;
1815   raw_ptr<DemuxerStream> video_stream_;
1816   bool audio_read_done_;
1817   bool video_read_done_;
1818 };
1819
1820 // Make sure that all pending reads that we don't have media data for get an
1821 // "end of stream" buffer when MarkEndOfStream() is called.
1822 TEST_F(ChunkDemuxerTest, EndOfStreamWithPendingReads) {
1823   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1824
1825   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 2)));
1826
1827   bool audio_read_done_1 = false;
1828   bool video_read_done_1 = false;
1829   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
1830   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
1831   EndOfStreamHelper end_of_stream_helper_1(audio_stream, video_stream);
1832   EndOfStreamHelper end_of_stream_helper_2(audio_stream, video_stream);
1833
1834   ReadAudio(
1835       base::BindOnce(&OnReadDone, base::Milliseconds(0), &audio_read_done_1));
1836   ReadVideo(
1837       base::BindOnce(&OnReadDone, base::Milliseconds(0), &video_read_done_1));
1838   base::RunLoop().RunUntilIdle();
1839
1840   EXPECT_TRUE(audio_read_done_1);
1841   EXPECT_TRUE(video_read_done_1);
1842
1843   end_of_stream_helper_1.RequestReads();
1844
1845   EXPECT_CALL(host_, SetDuration(base::Milliseconds(kVideoBlockDuration)));
1846   MarkEndOfStream(PIPELINE_OK);
1847
1848   end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
1849
1850   end_of_stream_helper_2.RequestReads();
1851   end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
1852 }
1853
1854 // Make sure that all Read() calls after we get an MarkEndOfStream()
1855 // call return an "end of stream" buffer.
1856 TEST_F(ChunkDemuxerTest, ReadsAfterEndOfStream) {
1857   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1858
1859   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 2)));
1860
1861   bool audio_read_done_1 = false;
1862   bool video_read_done_1 = false;
1863   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
1864   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
1865   EndOfStreamHelper end_of_stream_helper_1(audio_stream, video_stream);
1866   EndOfStreamHelper end_of_stream_helper_2(audio_stream, video_stream);
1867   EndOfStreamHelper end_of_stream_helper_3(audio_stream, video_stream);
1868
1869   ReadAudio(
1870       base::BindOnce(&OnReadDone, base::Milliseconds(0), &audio_read_done_1));
1871   ReadVideo(
1872       base::BindOnce(&OnReadDone, base::Milliseconds(0), &video_read_done_1));
1873
1874   end_of_stream_helper_1.RequestReads();
1875
1876   EXPECT_TRUE(audio_read_done_1);
1877   EXPECT_TRUE(video_read_done_1);
1878   end_of_stream_helper_1.CheckIfReadDonesWereCalled(false);
1879
1880   EXPECT_CALL(host_, SetDuration(base::Milliseconds(kVideoBlockDuration)));
1881   MarkEndOfStream(PIPELINE_OK);
1882
1883   end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
1884
1885   // Request a few more reads and make sure we immediately get
1886   // end of stream buffers.
1887   end_of_stream_helper_2.RequestReads();
1888   end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
1889
1890   end_of_stream_helper_3.RequestReads();
1891   end_of_stream_helper_3.CheckIfReadDonesWereCalled(true);
1892 }
1893
1894 TEST_F(ChunkDemuxerTest, EndOfStreamDuringCanceledSeek) {
1895   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1896
1897   ASSERT_TRUE(AppendCluster(0, 10));
1898   EXPECT_CALL(host_, SetDuration(base::Milliseconds(138)));
1899   MarkEndOfStream(PIPELINE_OK);
1900
1901   // Start the first seek.
1902   Seek(base::Milliseconds(20));
1903
1904   // Simulate another seek being requested before the first
1905   // seek has finished prerolling.
1906   base::TimeDelta seek_time2 = base::Milliseconds(30);
1907   demuxer_->CancelPendingSeek(seek_time2);
1908
1909   // Finish second seek.
1910   Seek(seek_time2);
1911
1912   DemuxerStream::Status status;
1913   base::TimeDelta last_timestamp;
1914
1915   // Make sure audio can reach end of stream.
1916   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
1917   ASSERT_EQ(status, DemuxerStream::kOk);
1918
1919   // Make sure video can reach end of stream.
1920   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
1921   ASSERT_EQ(status, DemuxerStream::kOk);
1922 }
1923
1924 // Verify buffered range change behavior for audio/video/text tracks.
1925 TEST_F(ChunkDemuxerTest, EndOfStreamRangeChanges) {
1926   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1927
1928   AppendMuxedCluster(MuxedStreamInfo(kVideoTrackNum, "0K 33", 33),
1929                      MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23));
1930
1931   CheckExpectedRanges("{ [0,46) }");
1932
1933   EXPECT_CALL(host_, SetDuration(base::Milliseconds(66)));
1934   MarkEndOfStream(PIPELINE_OK);
1935
1936   CheckExpectedRanges("{ [0,66) }");
1937 }
1938
1939 // Make sure AppendData() will accept elements that span multiple calls.
1940 TEST_F(ChunkDemuxerTest, AppendingInPieces) {
1941   EXPECT_CALL(*this, DemuxerOpened());
1942   demuxer_->Initialize(&host_,
1943                        CreateInitDoneCallback(kDefaultDuration(), PIPELINE_OK));
1944
1945   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
1946
1947   std::unique_ptr<uint8_t[]> info_tracks;
1948   int info_tracks_size = 0;
1949   CreateInitSegment(HAS_AUDIO | HAS_VIDEO,
1950                     false, false, &info_tracks, &info_tracks_size);
1951
1952   std::unique_ptr<Cluster> cluster_a(kDefaultFirstCluster());
1953   std::unique_ptr<Cluster> cluster_b(kDefaultSecondCluster());
1954
1955   size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size();
1956   std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
1957   uint8_t* dst = buffer.get();
1958   memcpy(dst, info_tracks.get(), info_tracks_size);
1959   dst += info_tracks_size;
1960
1961   memcpy(dst, cluster_a->data(), cluster_a->size());
1962   dst += cluster_a->size();
1963
1964   memcpy(dst, cluster_b->data(), cluster_b->size());
1965   dst += cluster_b->size();
1966
1967   ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO);
1968   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
1969   EXPECT_FALSE(DidProgress());
1970   ASSERT_TRUE(AppendDataInPieces(buffer.get(), buffer_size));
1971   EXPECT_TRUE(DidProgress());
1972
1973   GenerateExpectedReads(0, 9);
1974 }
1975
1976 TEST_F(ChunkDemuxerTest, WebMFile_AudioAndVideo) {
1977   struct BufferTimestamps buffer_timestamps[] = {
1978     {0, 0},
1979     {33, 3},
1980     {67, 6},
1981     {100, 9},
1982     {133, 12},
1983     {kSkip, kSkip},
1984   };
1985
1986   ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO);
1987   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)).Times(7);
1988
1989   // Expect duration adjustment since actual duration differs slightly from
1990   // duration in the init segment.
1991   EXPECT_CALL(host_, SetDuration(base::Milliseconds(2768)));
1992
1993   ASSERT_TRUE(ParseWebMFile("bear-320x240.webm", buffer_timestamps,
1994                             base::Milliseconds(2744)));
1995   EXPECT_EQ(212949, demuxer_->GetMemoryUsage());
1996 }
1997
1998 TEST_F(ChunkDemuxerTest, WebMFile_LiveAudioAndVideo) {
1999   struct BufferTimestamps buffer_timestamps[] = {
2000     {0, 0},
2001     {33, 3},
2002     {67, 6},
2003     {100, 9},
2004     {133, 12},
2005     {kSkip, kSkip},
2006   };
2007
2008   ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO);
2009   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2)).Times(7);
2010   ASSERT_TRUE(ParseWebMFile("bear-320x240-live.webm", buffer_timestamps,
2011                             kInfiniteDuration));
2012
2013   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
2014   EXPECT_EQ(StreamLiveness::kLive, audio->liveness());
2015   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
2016   EXPECT_EQ(StreamLiveness::kLive, video->liveness());
2017   EXPECT_EQ(212949, demuxer_->GetMemoryUsage());
2018 }
2019
2020 TEST_F(ChunkDemuxerTest, WebMFile_AudioOnly) {
2021   struct BufferTimestamps buffer_timestamps[] = {
2022     {kSkip, 0},
2023     {kSkip, 3},
2024     {kSkip, 6},
2025     {kSkip, 9},
2026     {kSkip, 12},
2027     {kSkip, kSkip},
2028   };
2029
2030   ExpectInitMediaLogs(HAS_AUDIO);
2031   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2));
2032
2033   // Expect duration adjustment since actual duration differs slightly from
2034   // duration in the init segment.
2035   EXPECT_CALL(host_, SetDuration(base::Milliseconds(2768)));
2036
2037   ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps,
2038                             base::Milliseconds(2744), HAS_AUDIO));
2039   EXPECT_EQ(18624, demuxer_->GetMemoryUsage());
2040 }
2041
2042 TEST_F(ChunkDemuxerTest, WebMFile_VideoOnly) {
2043   struct BufferTimestamps buffer_timestamps[] = {
2044     {0, kSkip},
2045     {33, kSkip},
2046     {67, kSkip},
2047     {100, kSkip},
2048     {133, kSkip},
2049     {kSkip, kSkip},
2050   };
2051
2052   ExpectInitMediaLogs(HAS_VIDEO);
2053
2054   // Expect duration adjustment since actual duration differs slightly from
2055   // duration in the init segment.
2056   EXPECT_CALL(host_, SetDuration(base::Milliseconds(2736)));
2057
2058   ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps,
2059                             base::Milliseconds(2703), HAS_VIDEO));
2060   EXPECT_EQ(194325, demuxer_->GetMemoryUsage());
2061 }
2062
2063 TEST_F(ChunkDemuxerTest, WebMFile_AltRefFrames) {
2064   struct BufferTimestamps buffer_timestamps[] = {
2065     {0, 0},
2066     {33, 3},
2067     {33, 6},
2068     {67, 9},
2069     {100, 12},
2070     {kSkip, kSkip},
2071   };
2072
2073   // Expect duration adjustment since actual duration differs slightly from
2074   // duration in the init segment.
2075   EXPECT_CALL(host_, SetDuration(base::Milliseconds(2768)));
2076
2077   ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO);
2078   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2));
2079   ASSERT_TRUE(ParseWebMFile("bear-320x240-altref.webm", buffer_timestamps,
2080                             base::Milliseconds(2767)));
2081 }
2082
2083 // Verify that we output buffers before the entire cluster has been parsed.
2084 TEST_F(ChunkDemuxerTest, IncrementalClusterParsing) {
2085   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2086
2087   std::unique_ptr<Cluster> cluster(GenerateCluster(0, 6));
2088
2089   bool audio_read_done = false;
2090   bool video_read_done = false;
2091   ReadAudio(
2092       base::BindOnce(&OnReadDone, base::Milliseconds(0), &audio_read_done));
2093   ReadVideo(
2094       base::BindOnce(&OnReadDone, base::Milliseconds(0), &video_read_done));
2095
2096   // Make sure the reads haven't completed yet.
2097   EXPECT_FALSE(audio_read_done);
2098   EXPECT_FALSE(video_read_done);
2099
2100   // Append data one byte at a time until one or both reads complete.
2101   int i = 0;
2102   for (; i < cluster->size() && !(audio_read_done || video_read_done); ++i) {
2103     ASSERT_TRUE(AppendData(cluster->data() + i, 1));
2104     base::RunLoop().RunUntilIdle();
2105   }
2106
2107   EXPECT_TRUE(audio_read_done || video_read_done);
2108   EXPECT_GT(i, 0);
2109   EXPECT_LT(i, cluster->size());
2110
2111   audio_read_done = false;
2112   video_read_done = false;
2113   ReadAudio(
2114       base::BindOnce(&OnReadDone, base::Milliseconds(23), &audio_read_done));
2115   ReadVideo(
2116       base::BindOnce(&OnReadDone, base::Milliseconds(33), &video_read_done));
2117
2118   // Make sure the reads haven't completed yet.
2119   EXPECT_FALSE(audio_read_done);
2120   EXPECT_FALSE(video_read_done);
2121
2122   // Append the remaining data.
2123   ASSERT_LT(i, cluster->size());
2124   ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i));
2125
2126   base::RunLoop().RunUntilIdle();
2127
2128   EXPECT_TRUE(audio_read_done);
2129   EXPECT_TRUE(video_read_done);
2130 }
2131
2132 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) {
2133   EXPECT_CALL(*this, DemuxerOpened());
2134   demuxer_->Initialize(
2135       &host_,
2136       CreateInitDoneCallback(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED));
2137
2138   ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
2139
2140   EXPECT_MEDIA_LOG(StreamParsingFailed());
2141   uint8_t tmp = 0;
2142   ASSERT_FALSE(demuxer_->AppendData(
2143       kSourceId, &tmp, 1, append_window_start_for_next_append_,
2144       append_window_end_for_next_append_, &timestamp_offset_map_[kSourceId]));
2145 }
2146
2147 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) {
2148   EXPECT_CALL(*this, DemuxerOpened());
2149   demuxer_->Initialize(
2150       &host_,
2151       CreateInitDoneCallback(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED));
2152
2153   ASSERT_EQ(AddId(kSourceId, "audio/webm", "vorbis"), ChunkDemuxer::kOk);
2154
2155   // Video track is unexpected per mimetype.
2156   EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("Video", "vp8"));
2157   EXPECT_MEDIA_LOG(StreamParsingFailed());
2158   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
2159 }
2160
2161 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) {
2162   EXPECT_CALL(*this, DemuxerOpened());
2163   demuxer_->Initialize(
2164       &host_,
2165       CreateInitDoneCallback(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED));
2166
2167   ASSERT_EQ(AddId(kSourceId, "video/webm", "vp8"), ChunkDemuxer::kOk);
2168
2169   // Audio track is unexpected per mimetype.
2170   EXPECT_FOUND_CODEC_NAME(Video, "vp8");
2171   EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("Audio", "vorbis"));
2172   EXPECT_MEDIA_LOG(StreamParsingFailed());
2173   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
2174 }
2175
2176 TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) {
2177   EXPECT_CALL(*this, DemuxerOpened());
2178   demuxer_->Initialize(
2179       &host_,
2180       CreateInitDoneCallback(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED));
2181
2182   ASSERT_EQ(AddId(kSourceId, "video/webm", "vorbis,vp8"), ChunkDemuxer::kOk);
2183
2184   // Video track is also expected per mimetype.
2185   EXPECT_FOUND_CODEC_NAME(Audio, "vorbis");
2186   EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vp8"));
2187   EXPECT_MEDIA_LOG(StreamParsingFailed());
2188   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO));
2189 }
2190
2191 TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) {
2192   EXPECT_CALL(*this, DemuxerOpened());
2193   demuxer_->Initialize(
2194       &host_,
2195       CreateInitDoneCallback(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED));
2196
2197   ASSERT_EQ(AddId(kSourceId, "video/webm", "vorbis,vp8"), ChunkDemuxer::kOk);
2198
2199   // Audio track is also expected per mimetype.
2200   EXPECT_FOUND_CODEC_NAME(Video, "vp8");
2201   EXPECT_MEDIA_LOG(InitSegmentMissesExpectedTrack("vorbis"));
2202   EXPECT_MEDIA_LOG(StreamParsingFailed());
2203   ASSERT_FALSE(AppendInitSegment(HAS_VIDEO));
2204 }
2205
2206 TEST_F(ChunkDemuxerTest, MultipleHeaders) {
2207   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2208
2209   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
2210
2211   // Append another identical initialization segment.
2212   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
2213   ASSERT_TRUE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
2214
2215   ASSERT_TRUE(AppendCluster(kDefaultSecondCluster()));
2216
2217   GenerateExpectedReads(0, 9);
2218 }
2219
2220 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) {
2221   std::string audio_id = "audio1";
2222   std::string video_id = "video1";
2223   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2224
2225   // Append audio and video data into separate source ids.
2226   ASSERT_TRUE(AppendCluster(
2227       audio_id,
2228       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)));
2229   GenerateAudioStreamExpectedReads(0, 4);
2230   ASSERT_TRUE(AppendCluster(video_id,
2231                             GenerateSingleStreamCluster(0, 132, kVideoTrackNum,
2232                                                         kVideoBlockDuration)));
2233   GenerateVideoStreamExpectedReads(0, 4);
2234 }
2235
2236 TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) {
2237   std::string audio_id = "audio1";
2238   std::string video_id = "video1";
2239
2240   ASSERT_TRUE(InitDemuxerAudioAndVideoSourcesText(audio_id, video_id));
2241
2242   // Append audio and video data into separate source ids.
2243   ASSERT_TRUE(AppendCluster(
2244       audio_id,
2245       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)));
2246   GenerateAudioStreamExpectedReads(0, 4);
2247   ASSERT_TRUE(AppendCluster(video_id,
2248                             GenerateSingleStreamCluster(0, 132, kVideoTrackNum,
2249                                                         kVideoBlockDuration)));
2250   GenerateVideoStreamExpectedReads(0, 4);
2251 }
2252
2253 TEST_F(ChunkDemuxerTest, AddIdFailures) {
2254   EXPECT_CALL(*this, DemuxerOpened());
2255   demuxer_->Initialize(&host_,
2256                        CreateInitDoneCallback(kDefaultDuration(), PIPELINE_OK));
2257
2258   std::string audio_id = "audio1";
2259   std::string video_id = "video1";
2260
2261   ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk);
2262
2263   ExpectInitMediaLogs(HAS_AUDIO);
2264   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
2265   ASSERT_TRUE(AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO));
2266
2267   // Adding an id after append should fail.
2268   ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit);
2269 }
2270
2271 // Test that Read() calls after a RemoveId() return "end of stream" buffers.
2272 TEST_F(ChunkDemuxerTest, RemoveId) {
2273   std::string audio_id = "audio1";
2274   std::string video_id = "video1";
2275   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2276
2277   // Append audio and video data into separate source ids.
2278   ASSERT_TRUE(AppendCluster(
2279       audio_id,
2280       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)));
2281   ASSERT_TRUE(AppendCluster(video_id,
2282                             GenerateSingleStreamCluster(0, 132, kVideoTrackNum,
2283                                                         kVideoBlockDuration)));
2284
2285   // Read() from audio should return normal buffers.
2286   GenerateAudioStreamExpectedReads(0, 4);
2287
2288   // Audio stream will become inaccessible after |audio_id| is removed, so save
2289   // it here to read from it after RemoveId.
2290   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
2291
2292   // Remove the audio id.
2293   demuxer_->RemoveId(audio_id);
2294
2295   // Read() from audio should return "end of stream" buffers.
2296   bool audio_read_done = false;
2297   audio_stream->Read(base::BindOnce(&OnReadDone_EOSExpected, &audio_read_done));
2298   base::RunLoop().RunUntilIdle();
2299   EXPECT_TRUE(audio_read_done);
2300
2301   // Read() from video should still return normal buffers.
2302   GenerateVideoStreamExpectedReads(0, 4);
2303 }
2304
2305 // Test that removing an ID immediately after adding it does not interfere with
2306 // quota for new IDs in the future.
2307 TEST_F(ChunkDemuxerTest, RemoveAndAddId) {
2308   demuxer_->Initialize(&host_,
2309                        base::BindOnce(&ChunkDemuxerTest::DemuxerInitialized,
2310                                       base::Unretained(this)));
2311
2312   std::string audio_id_1 = "audio1";
2313   ASSERT_TRUE(AddId(audio_id_1, HAS_AUDIO) == ChunkDemuxer::kOk);
2314   demuxer_->RemoveId(audio_id_1);
2315
2316   std::string audio_id_2 = "audio2";
2317   ASSERT_TRUE(AddId(audio_id_2, HAS_AUDIO) == ChunkDemuxer::kOk);
2318 }
2319
2320 TEST_F(ChunkDemuxerTest, SeekCanceled) {
2321   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2322
2323   // Append cluster at the beginning of the stream.
2324   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 4)));
2325
2326   // Seek to an unbuffered region.
2327   Seek(base::Seconds(50));
2328
2329   // Attempt to read in unbuffered area; should not fulfill the read.
2330   bool audio_read_done = false;
2331   bool video_read_done = false;
2332   ReadAudio(base::BindOnce(&OnReadDone_AbortExpected, &audio_read_done));
2333   ReadVideo(base::BindOnce(&OnReadDone_AbortExpected, &video_read_done));
2334   EXPECT_FALSE(audio_read_done);
2335   EXPECT_FALSE(video_read_done);
2336
2337   // Now cancel the pending seek, which should flush the reads with empty
2338   // buffers.
2339   base::TimeDelta seek_time = base::Seconds(0);
2340   demuxer_->CancelPendingSeek(seek_time);
2341   base::RunLoop().RunUntilIdle();
2342   EXPECT_TRUE(audio_read_done);
2343   EXPECT_TRUE(video_read_done);
2344
2345   // A seek back to the buffered region should succeed.
2346   Seek(seek_time);
2347   GenerateExpectedReads(0, 4);
2348 }
2349
2350 TEST_F(ChunkDemuxerTest, SeekCanceledWhileWaitingForSeek) {
2351   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2352
2353   // Append cluster at the beginning of the stream.
2354   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 4)));
2355
2356   // Start waiting for a seek.
2357   base::TimeDelta seek_time1 = base::Seconds(50);
2358   base::TimeDelta seek_time2 = base::Seconds(0);
2359   demuxer_->StartWaitingForSeek(seek_time1);
2360
2361   // Now cancel the upcoming seek to an unbuffered region.
2362   demuxer_->CancelPendingSeek(seek_time2);
2363   demuxer_->Seek(seek_time1, NewExpectedStatusCB(PIPELINE_OK));
2364
2365   // Read requests should be fulfilled with empty buffers.
2366   bool audio_read_done = false;
2367   bool video_read_done = false;
2368   ReadAudio(base::BindOnce(&OnReadDone_AbortExpected, &audio_read_done));
2369   ReadVideo(base::BindOnce(&OnReadDone_AbortExpected, &video_read_done));
2370   EXPECT_TRUE(audio_read_done);
2371   EXPECT_TRUE(video_read_done);
2372
2373   // A seek back to the buffered region should succeed.
2374   Seek(seek_time2);
2375   GenerateExpectedReads(0, 4);
2376 }
2377
2378 // Test that Seek() successfully seeks to all source IDs.
2379 TEST_F(ChunkDemuxerTest, SeekAudioAndVideoSources) {
2380   std::string audio_id = "audio1";
2381   std::string video_id = "video1";
2382   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2383
2384   ASSERT_TRUE(AppendCluster(
2385       audio_id,
2386       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)));
2387   ASSERT_TRUE(AppendCluster(video_id,
2388                             GenerateSingleStreamCluster(0, 132, kVideoTrackNum,
2389                                                         kVideoBlockDuration)));
2390
2391   // Read() should return buffers at 0.
2392   bool audio_read_done = false;
2393   bool video_read_done = false;
2394   ReadAudio(
2395       base::BindOnce(&OnReadDone, base::Milliseconds(0), &audio_read_done));
2396   ReadVideo(
2397       base::BindOnce(&OnReadDone, base::Milliseconds(0), &video_read_done));
2398   EXPECT_TRUE(audio_read_done);
2399   EXPECT_TRUE(video_read_done);
2400
2401   // Seek to 3 (an unbuffered region).
2402   Seek(base::Seconds(3));
2403
2404   audio_read_done = false;
2405   video_read_done = false;
2406   ReadAudio(base::BindOnce(&OnReadDone, base::Seconds(3), &audio_read_done));
2407   ReadVideo(base::BindOnce(&OnReadDone, base::Seconds(3), &video_read_done));
2408   // Read()s should not return until after data is appended at the Seek point.
2409   EXPECT_FALSE(audio_read_done);
2410   EXPECT_FALSE(video_read_done);
2411
2412   ASSERT_TRUE(AppendCluster(
2413       audio_id, GenerateSingleStreamCluster(3000, 3092, kAudioTrackNum,
2414                                             kAudioBlockDuration)));
2415   ASSERT_TRUE(AppendCluster(
2416       video_id, GenerateSingleStreamCluster(3000, 3132, kVideoTrackNum,
2417                                             kVideoBlockDuration)));
2418
2419   base::RunLoop().RunUntilIdle();
2420
2421   // Read() should return buffers at 3.
2422   EXPECT_TRUE(audio_read_done);
2423   EXPECT_TRUE(video_read_done);
2424 }
2425
2426 // Test that Seek() completes successfully when EndOfStream
2427 // is called before data is available for that seek point.
2428 // This scenario might be useful if seeking past the end of stream
2429 // of either audio or video (or both).
2430 TEST_F(ChunkDemuxerTest, EndOfStreamAfterPastEosSeek) {
2431   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2432
2433   AppendMuxedCluster(
2434       MuxedStreamInfo(kAudioTrackNum,
2435                       "0K 10K 20K 30K 40K 50K 60K 70K 80K 90K 100K 110K", 10),
2436       MuxedStreamInfo(kVideoTrackNum, "0K 20K 40K 60K 80K", 20));
2437   CheckExpectedRanges("{ [0,100) }");
2438
2439   // Seeking past the end of video.
2440   // Note: audio data is available for that seek point.
2441   bool seek_cb_was_called = false;
2442   base::TimeDelta seek_time = base::Milliseconds(110);
2443   demuxer_->StartWaitingForSeek(seek_time);
2444   demuxer_->Seek(seek_time,
2445                  base::BindOnce(OnSeekDone_OKExpected, &seek_cb_was_called));
2446   base::RunLoop().RunUntilIdle();
2447
2448   EXPECT_FALSE(seek_cb_was_called);
2449
2450   EXPECT_CALL(host_, SetDuration(base::Milliseconds(120)));
2451   MarkEndOfStream(PIPELINE_OK);
2452   CheckExpectedRanges("{ [0,120) }");
2453   base::RunLoop().RunUntilIdle();
2454
2455   EXPECT_TRUE(seek_cb_was_called);
2456
2457   ShutdownDemuxer();
2458 }
2459
2460 // Test that EndOfStream is ignored if coming during a pending seek
2461 // whose seek time is before some existing ranges.
2462 TEST_F(ChunkDemuxerTest, EndOfStreamDuringPendingSeek) {
2463   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2464
2465   AppendMuxedCluster(
2466       MuxedStreamInfo(kAudioTrackNum,
2467                       "0K 10K 20K 30K 40K 50K 60K 70K 80K 90K 100K 110K", 10),
2468       MuxedStreamInfo(kVideoTrackNum, "0K 20K 40K 60K 80K", 20));
2469   AppendMuxedCluster(
2470       MuxedStreamInfo(kAudioTrackNum,
2471                       "200K 210K 220K 230K 240K 250K 260K 270K 280K 290K", 10),
2472       MuxedStreamInfo(kVideoTrackNum, "200K 220K 240K 260K 280K", 20));
2473
2474   bool seek_cb_was_called = false;
2475   base::TimeDelta seek_time = base::Milliseconds(160);
2476   demuxer_->StartWaitingForSeek(seek_time);
2477   demuxer_->Seek(seek_time,
2478                  base::BindOnce(OnSeekDone_OKExpected, &seek_cb_was_called));
2479   base::RunLoop().RunUntilIdle();
2480
2481   EXPECT_FALSE(seek_cb_was_called);
2482
2483   EXPECT_CALL(host_, SetDuration(base::Milliseconds(300)));
2484   MarkEndOfStream(PIPELINE_OK);
2485   base::RunLoop().RunUntilIdle();
2486
2487   EXPECT_FALSE(seek_cb_was_called);
2488
2489   demuxer_->UnmarkEndOfStream();
2490
2491   AppendMuxedCluster(
2492       MuxedStreamInfo(kAudioTrackNum, "140K 150K 160K 170K", 10),
2493       MuxedStreamInfo(kVideoTrackNum, "140K 145K 150K 155K 160K 165K 170K 175K",
2494                       20));
2495
2496   base::RunLoop().RunUntilIdle();
2497
2498   EXPECT_TRUE(seek_cb_was_called);
2499
2500   ShutdownDemuxer();
2501 }
2502
2503 // Test ranges in an audio-only stream.
2504 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) {
2505   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
2506
2507   // Test a simple cluster.
2508   ASSERT_TRUE(AppendCluster(
2509       GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)));
2510
2511   CheckExpectedRanges("{ [0,92) }");
2512
2513   // Append a disjoint cluster to check for two separate ranges.
2514   ASSERT_TRUE(AppendCluster(GenerateSingleStreamCluster(
2515       150, 219, kAudioTrackNum, kAudioBlockDuration)));
2516
2517   CheckExpectedRanges("{ [0,92) [150,219) }");
2518 }
2519
2520 // Test ranges in a video-only stream.
2521 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) {
2522   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
2523
2524   // Test a simple cluster.
2525   ASSERT_TRUE(AppendCluster(GenerateSingleStreamCluster(0, 132, kVideoTrackNum,
2526                                                         kVideoBlockDuration)));
2527
2528   CheckExpectedRanges("{ [0,132) }");
2529
2530   // Append a disjoint cluster to check for two separate ranges.
2531   ASSERT_TRUE(AppendCluster(GenerateSingleStreamCluster(
2532       200, 299, kVideoTrackNum, kVideoBlockDuration)));
2533
2534   CheckExpectedRanges("{ [0,132) [200,299) }");
2535 }
2536
2537 TEST_F(ChunkDemuxerTest, GetBufferedRanges_SeparateStreams) {
2538   std::string audio_id = "audio1";
2539   std::string video_id = "video1";
2540   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2541
2542   // Append audio and video data into separate source ids.
2543
2544   // Audio block: 0 -> 23
2545   // Video block: 0 -> 33
2546   // Buffered Range: 0 -> 23
2547   // Audio block duration is smaller than video block duration,
2548   // so the buffered ranges should correspond to the audio blocks.
2549   ASSERT_TRUE(AppendCluster(
2550       audio_id, GenerateSingleStreamCluster(0, 23, kAudioTrackNum, 23)));
2551   ASSERT_TRUE(AppendCluster(
2552       video_id, GenerateSingleStreamCluster(0, 33, kVideoTrackNum, 33)));
2553   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,23) }");
2554   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,33) }");
2555   CheckExpectedRangesForMediaSource("{ [0,23) }");
2556
2557   // Audio blocks: 300 -> 400
2558   // Video blocks: 320 -> 420
2559   // Buffered Range: 320 -> 400  (jagged start and end across SourceBuffers)
2560   ASSERT_TRUE(AppendCluster(
2561       audio_id, GenerateSingleStreamCluster(300, 400, kAudioTrackNum, 50)));
2562   ASSERT_TRUE(AppendCluster(
2563       video_id, GenerateSingleStreamCluster(320, 420, kVideoTrackNum, 50)));
2564   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,23) [300,400) }");
2565   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,33) [320,420) }");
2566   CheckExpectedRangesForMediaSource("{ [0,23) [320,400) }");
2567
2568   // Audio block: 620 -> 690
2569   // Video block: 600 -> 670
2570   // Buffered Range: 620 -> 670  (jagged start and end across SourceBuffers)
2571   ASSERT_TRUE(AppendCluster(
2572       audio_id, GenerateSingleStreamCluster(620, 690, kAudioTrackNum, 70)));
2573   ASSERT_TRUE(AppendCluster(
2574       video_id, GenerateSingleStreamCluster(600, 670, kVideoTrackNum, 70)));
2575   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,23) [300,400) [620,690) }");
2576   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,33) [320,420) [600,670) }");
2577   CheckExpectedRangesForMediaSource("{ [0,23) [320,400) [620,670) }");
2578
2579   // Audio block: 920 -> 950
2580   // Video block: 900 -> 970
2581   // Buffered Range: 920 -> 950  (complete overlap of audio)
2582   ASSERT_TRUE(AppendCluster(
2583       audio_id, GenerateSingleStreamCluster(920, 950, kAudioTrackNum, 30)));
2584   ASSERT_TRUE(AppendCluster(
2585       video_id, GenerateSingleStreamCluster(900, 970, kVideoTrackNum, 70)));
2586   CheckExpectedRanges(DemuxerStream::AUDIO,
2587                       "{ [0,23) [300,400) [620,690) [920,950) }");
2588   CheckExpectedRanges(DemuxerStream::VIDEO,
2589                       "{ [0,33) [320,420) [600,670) [900,970) }");
2590   CheckExpectedRangesForMediaSource("{ [0,23) [320,400) [620,670) [920,950) }");
2591
2592   // Audio block: 1200 -> 1270
2593   // Video block: 1220 -> 1250
2594   // Buffered Range: 1220 -> 1250  (complete overlap of video)
2595   ASSERT_TRUE(AppendCluster(
2596       audio_id, GenerateSingleStreamCluster(1200, 1270, kAudioTrackNum, 70)));
2597   ASSERT_TRUE(AppendCluster(
2598       video_id, GenerateSingleStreamCluster(1220, 1250, kVideoTrackNum, 30)));
2599   CheckExpectedRanges(DemuxerStream::AUDIO,
2600                       "{ [0,23) [300,400) [620,690) [920,950) [1200,1270) }");
2601   CheckExpectedRanges(DemuxerStream::VIDEO,
2602                       "{ [0,33) [320,420) [600,670) [900,970) [1220,1250) }");
2603   CheckExpectedRangesForMediaSource(
2604       "{ [0,23) [320,400) [620,670) [920,950) [1220,1250) }");
2605
2606   // Audio buffered ranges are trimmed from 1270 to 1250 due to splicing the
2607   // previously buffered audio frame
2608   // - existing frame trimmed from [1200, 1270) to [1200,1230),
2609   // - newly appended audio from [1230, 1250).
2610   EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(1230000, 1200000, 40000));
2611   ASSERT_TRUE(AppendCluster(
2612       audio_id, GenerateSingleStreamCluster(1230, 1250, kAudioTrackNum, 20)));
2613   CheckExpectedRanges(DemuxerStream::AUDIO,
2614                       "{ [0,23) [300,400) [620,690) [920,950) [1200,1250) }");
2615
2616   // Video buffer range is unchanged by next append. The time and duration of
2617   // the new key frame line up with previous range boundaries.
2618   ASSERT_TRUE(AppendCluster(
2619       video_id, GenerateSingleStreamCluster(1230, 1250, kVideoTrackNum, 20)));
2620   CheckExpectedRanges(DemuxerStream::VIDEO,
2621                       "{ [0,33) [320,420) [600,670) [900,970) [1220,1250) }");
2622
2623   CheckExpectedRangesForMediaSource(
2624       "{ [0,23) [320,400) [620,670) [920,950) [1220,1250) }");
2625 }
2626
2627 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
2628   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2629
2630   // Audio block: 0 -> 23
2631   // Video block: 0 -> 33
2632   // Buffered Range: 0 -> 23
2633   // Audio block duration is smaller than video block duration,
2634   // so the buffered ranges should correspond to the audio blocks.
2635   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0D23K"),
2636                      MuxedStreamInfo(kVideoTrackNum, "0D33K"));
2637
2638   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,23) }");
2639   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,33) }");
2640   CheckExpectedRanges("{ [0,23) }");
2641
2642   // Audio blocks: 300 -> 400
2643   // Video blocks: 320 -> 420
2644   // Naive Buffered Range: 320 -> 400  (end overlap) **
2645   // **Except these are in the same cluster, with same segment start time of
2646   // 300, so the added buffered range is 300 -> 400  (still with end overlap)
2647   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "300K 350D50K"),
2648                      MuxedStreamInfo(kVideoTrackNum, "320K 370D50K"));
2649
2650   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,23) [300,400) }");
2651   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,33) [300,420) }");
2652   CheckExpectedRanges("{ [0,23) [300,400) }");
2653
2654   // Audio block: 620 -> 690
2655   // Video block: 600 -> 670
2656   // Naive Buffered Range: 620 -> 670  (front overlap) **
2657   // **Except these are in the same cluster, with same segment start time of
2658   // 500, so the added buffered range is 600 -> 670
2659   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "620D70K"),
2660                      MuxedStreamInfo(kVideoTrackNum, "600D70K"));
2661
2662   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,23) [300,400) [600,690) }");
2663   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,33) [300,420) [600,670) }");
2664   CheckExpectedRanges("{ [0,23) [300,400) [600,670) }");
2665
2666   // Audio block: 920 -> 950
2667   // Video block: 900 -> 970
2668   // Naive Buffered Range: 920 -> 950  (complete overlap, audio) **
2669   // **Except these are in the same cluster, with same segment start time of
2670   // 900, so the added buffered range is 900 -> 950
2671   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "920D30K"),
2672                      MuxedStreamInfo(kVideoTrackNum, "900D70K"));
2673
2674   CheckExpectedRanges(DemuxerStream::AUDIO,
2675                       "{ [0,23) [300,400) [600,690) [900,950) }");
2676   CheckExpectedRanges(DemuxerStream::VIDEO,
2677                       "{ [0,33) [300,420) [600,670) [900,970) }");
2678   CheckExpectedRanges("{ [0,23) [300,400) [600,670) [900,950) }");
2679
2680   // Audio block: 1200 -> 1270
2681   // Video block: 1220 -> 1250
2682   // Naive Buffered Range: 1220 -> 1250  (complete overlap, video) **
2683   // **Except these are in the same cluster, with same segment start time of
2684   // 1200, so the added buffered range is 1200 -> 1250
2685   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "1200D70K"),
2686                      MuxedStreamInfo(kVideoTrackNum, "1220D30K"));
2687
2688   CheckExpectedRanges(DemuxerStream::AUDIO,
2689                       "{ [0,23) [300,400) [600,690) [900,950) [1200,1270) }");
2690   CheckExpectedRanges(DemuxerStream::VIDEO,
2691                       "{ [0,33) [300,420) [600,670) [900,970) [1200,1250) }");
2692   CheckExpectedRanges("{ [0,23) [300,400) [600,670) [900,950) [1200,1250) }");
2693
2694   // Appending within existing buffered range.
2695   EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(1230000, 1200000, 40000));
2696   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "1230D20K"),
2697                      MuxedStreamInfo(kVideoTrackNum, "1230D20K"));
2698   // Video buffer range is unchanged. The time and duration of the new key frame
2699   // line up with previous range boundaries.
2700   CheckExpectedRanges(DemuxerStream::VIDEO,
2701                       "{ [0,33) [300,420) [600,670) [900,970) [1200,1250) }");
2702
2703   // Audio buffered ranges are trimmed from 1270 to 1250 due to splicing the
2704   // previously buffered audio frame.
2705   // - existing frame trimmed from [1200, 1270) to [1200, 1230),
2706   // - newly appended audio from [1230, 1250).
2707   CheckExpectedRanges(DemuxerStream::AUDIO,
2708                       "{ [0,23) [300,400) [600,690) [900,950) [1200,1250) }");
2709
2710   CheckExpectedRanges("{ [0,23) [300,400) [600,670) [900,950) [1200,1250) }");
2711 }
2712
2713 // Once MarkEndOfStream() is called, GetBufferedRanges should not cut off any
2714 // over-hanging tails at the end of the ranges as this is likely due to block
2715 // duration differences.
2716 TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) {
2717   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2718
2719   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 23K", 23),
2720                      MuxedStreamInfo(kVideoTrackNum, "0K 33", 33));
2721
2722   CheckExpectedRanges("{ [0,46) }");
2723
2724   EXPECT_CALL(host_, SetDuration(base::Milliseconds(66)));
2725   MarkEndOfStream(PIPELINE_OK);
2726
2727   // Verify that the range extends to the end of the video data.
2728   CheckExpectedRanges("{ [0,66) }");
2729
2730   // Verify that the range reverts to the intersection when end of stream
2731   // has been cancelled.
2732   demuxer_->UnmarkEndOfStream();
2733   CheckExpectedRanges("{ [0,46) }");
2734
2735   // Append and remove data so that the 2 streams' end ranges do not overlap.
2736   EXPECT_CALL(host_, SetDuration(base::Milliseconds(398)));
2737   AppendMuxedCluster(
2738       MuxedStreamInfo(kAudioTrackNum, "200K 223K", 23),
2739       MuxedStreamInfo(kVideoTrackNum, "200K 233 266 299 332K 365", 33));
2740
2741   // At this point, the per-stream ranges are as follows:
2742   // Audio: [0,46) [200,246)
2743   // Video: [0,66) [200,398)
2744   CheckExpectedRanges("{ [0,46) [200,246) }");
2745
2746   demuxer_->Remove(kSourceId, base::Milliseconds(200), base::Milliseconds(300));
2747
2748   // At this point, the per-stream ranges are as follows:
2749   // Audio: [0,46)
2750   // Video: [0,66) [332,398)
2751   CheckExpectedRanges("{ [0,46) }");
2752
2753   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "200K 223K", 23),
2754                      MuxedStreamInfo(kVideoTrackNum, "200K 233", 33));
2755
2756   // At this point, the per-stream ranges are as follows:
2757   // Audio: [0,46) [200,246)
2758   // Video: [0,66) [200,266) [332,398)
2759   // NOTE: The last range on each stream do not overlap in time.
2760   CheckExpectedRanges("{ [0,46) [200,246) }");
2761
2762   MarkEndOfStream(PIPELINE_OK);
2763
2764   // NOTE: The last range on each stream gets extended to the highest
2765   // end timestamp according to the spec. The last audio range gets extended
2766   // from [200,246) to [200,398) which is why the intersection results in the
2767   // middle range getting larger AND the new range appearing.
2768   CheckExpectedRanges("{ [0,46) [200,266) [332,398) }");
2769 }
2770
2771 TEST_F(ChunkDemuxerTest, DifferentStreamTimecodes) {
2772   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2773
2774   // Create a cluster where the video timecode begins 25ms after the audio.
2775   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 25, 8)));
2776
2777   Seek(base::Seconds(0));
2778   GenerateExpectedReads(0, 25, 8);
2779
2780   // Seek to 5 seconds.
2781   Seek(base::Seconds(5));
2782
2783   // Generate a cluster to fulfill this seek, where audio timecode begins 25ms
2784   // after the video.
2785   ASSERT_TRUE(AppendCluster(GenerateCluster(5025, 5000, 8)));
2786   GenerateExpectedReads(5025, 5000, 8);
2787 }
2788
2789 TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesSeparateSources) {
2790   std::string audio_id = "audio1";
2791   std::string video_id = "video1";
2792   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2793
2794   // Generate two streams where the video stream starts 5ms after the audio
2795   // stream and append them.
2796   ASSERT_TRUE(AppendCluster(
2797       audio_id,
2798       GenerateSingleStreamCluster(25, 4 * kAudioBlockDuration + 25,
2799                                   kAudioTrackNum, kAudioBlockDuration)));
2800   ASSERT_TRUE(AppendCluster(
2801       video_id,
2802       GenerateSingleStreamCluster(30, 4 * kVideoBlockDuration + 30,
2803                                   kVideoTrackNum, kVideoBlockDuration)));
2804
2805   // Both streams should be able to fulfill a seek to 25.
2806   Seek(base::Milliseconds(25));
2807   GenerateAudioStreamExpectedReads(25, 4);
2808   GenerateVideoStreamExpectedReads(30, 4);
2809 }
2810
2811 TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesOutOfRange) {
2812   std::string audio_id = "audio1";
2813   std::string video_id = "video1";
2814   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
2815
2816   // Generate two streams where the video stream starts 10s after the audio
2817   // stream and append them.
2818   ASSERT_TRUE(AppendCluster(
2819       audio_id,
2820       GenerateSingleStreamCluster(0, 4 * kAudioBlockDuration + 0,
2821                                   kAudioTrackNum, kAudioBlockDuration)));
2822   ASSERT_TRUE(AppendCluster(
2823       video_id,
2824       GenerateSingleStreamCluster(10000, 4 * kVideoBlockDuration + 10000,
2825                                   kVideoTrackNum, kVideoBlockDuration)));
2826
2827   // Should not be able to fulfill a seek to 0.
2828   base::TimeDelta seek_time = base::Milliseconds(0);
2829   demuxer_->StartWaitingForSeek(seek_time);
2830   demuxer_->Seek(seek_time,
2831                  NewExpectedStatusCB(PIPELINE_ERROR_ABORT));
2832   ExpectRead(DemuxerStream::AUDIO, 0);
2833   ExpectEndOfStream(DemuxerStream::VIDEO);
2834 }
2835
2836 TEST_F(ChunkDemuxerTest, CodecPrefixMatching) {
2837   demuxer_->Initialize(&host_,
2838                        base::BindOnce(&ChunkDemuxerTest::DemuxerInitialized,
2839                                       base::Unretained(this)));
2840   ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
2841
2842 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
2843   expected = ChunkDemuxer::kOk;
2844 #else
2845   EXPECT_MEDIA_LOG(CodecUnsupportedInContainer("avc1.4D4041", "video/mp4"));
2846 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
2847
2848   EXPECT_EQ(AddId("source_id", "video/mp4", "avc1.4D4041"), expected);
2849 }
2850
2851 // Test codec ID's that are not compliant with RFC6381, but have been
2852 // seen in the wild.
2853 TEST_F(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) {
2854   ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
2855
2856   const char* codec_ids[] = {
2857     // GPAC places leading zeros on the audio object type.
2858     "mp4a.40.02",
2859     "mp4a.40.05"
2860   };
2861
2862   demuxer_->Initialize(&host_,
2863                        base::BindOnce(&ChunkDemuxerTest::DemuxerInitialized,
2864                                       base::Unretained(this)));
2865
2866   for (size_t i = 0; i < std::size(codec_ids); ++i) {
2867 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
2868     expected = ChunkDemuxer::kOk;
2869 #else
2870     EXPECT_MEDIA_LOG(CodecUnsupportedInContainer(codec_ids[i], "audio/mp4"));
2871 #endif
2872
2873     ChunkDemuxer::Status result = AddId("source_id", "audio/mp4", codec_ids[i]);
2874
2875     EXPECT_EQ(result, expected)
2876         << "Fail to add codec_id '" << codec_ids[i] << "'";
2877
2878     if (result == ChunkDemuxer::kOk)
2879       demuxer_->RemoveId("source_id");
2880   }
2881 }
2882
2883 TEST_F(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) {
2884   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2885
2886   EXPECT_CALL(host_, SetDuration(_))
2887       .Times(AnyNumber());
2888
2889   base::TimeDelta kLastAudioTimestamp = base::Milliseconds(92);
2890   base::TimeDelta kLastVideoTimestamp = base::Milliseconds(99);
2891
2892   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
2893   ASSERT_TRUE(AppendCluster(kDefaultSecondCluster()));
2894   MarkEndOfStream(PIPELINE_OK);
2895
2896   DemuxerStream::Status status;
2897   base::TimeDelta last_timestamp;
2898
2899   // Verify that we can read audio & video to the end w/o problems.
2900   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
2901   EXPECT_EQ(DemuxerStream::kOk, status);
2902   EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
2903
2904   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2905   EXPECT_EQ(DemuxerStream::kOk, status);
2906   EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
2907
2908   // Seek back to 0 and verify that we can read to the end again..
2909   Seek(base::Milliseconds(0));
2910
2911   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
2912   EXPECT_EQ(DemuxerStream::kOk, status);
2913   EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
2914
2915   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2916   EXPECT_EQ(DemuxerStream::kOk, status);
2917   EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
2918 }
2919
2920 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) {
2921   EXPECT_CALL(*this, DemuxerOpened());
2922   demuxer_->Initialize(&host_,
2923                        base::BindOnce(&ChunkDemuxerTest::DemuxerInitialized,
2924                                       base::Unretained(this)));
2925   ASSERT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
2926   ASSERT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk);
2927
2928   CheckExpectedRanges("audio", "{ }");
2929   CheckExpectedRanges("video", "{ }");
2930 }
2931
2932 // Test that Seek() completes successfully when the first cluster
2933 // arrives.
2934 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) {
2935   InSequence s;
2936
2937   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2938
2939   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
2940
2941   base::TimeDelta seek_time = base::Seconds(0);
2942   demuxer_->StartWaitingForSeek(seek_time);
2943
2944   ASSERT_TRUE(AppendCluster(kDefaultSecondCluster()));
2945   EXPECT_CALL(
2946       host_,
2947       SetDuration(base::Milliseconds(kDefaultSecondClusterEndTimestamp)));
2948   MarkEndOfStream(PIPELINE_OK);
2949
2950   demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
2951
2952   GenerateExpectedReads(0, 4);
2953   GenerateExpectedReads(46, 66, 5);
2954
2955   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
2956   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
2957   EndOfStreamHelper end_of_stream_helper(audio_stream, video_stream);
2958   end_of_stream_helper.RequestReads();
2959   end_of_stream_helper.CheckIfReadDonesWereCalled(true);
2960 }
2961
2962 TEST_F(ChunkDemuxerTest, ConfigChange_Video) {
2963   InSequence s;
2964
2965   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
2966
2967   DemuxerStream::Status status;
2968   base::TimeDelta last_timestamp;
2969
2970   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
2971
2972   // Fetch initial video config and verify it matches what we expect.
2973   const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
2974   ASSERT_TRUE(video_config_1.IsValidConfig());
2975   EXPECT_EQ(video_config_1.natural_size().width(), 320);
2976   EXPECT_EQ(video_config_1.natural_size().height(), 240);
2977
2978   ExpectRead(DemuxerStream::VIDEO, 0);
2979
2980   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2981
2982   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
2983   EXPECT_EQ(last_timestamp.InMilliseconds(), 501);
2984
2985   // Fetch the new decoder config.
2986   const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
2987   ASSERT_TRUE(video_config_2.IsValidConfig());
2988   EXPECT_EQ(video_config_2.natural_size().width(), 640);
2989   EXPECT_EQ(video_config_2.natural_size().height(), 360);
2990
2991   ExpectRead(DemuxerStream::VIDEO, 527);
2992
2993   // Read until the next config change.
2994   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
2995   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
2996   EXPECT_EQ(last_timestamp.InMilliseconds(), 760);
2997
2998   // Get the new config and verify that it matches the first one.
2999   ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
3000
3001   ExpectRead(DemuxerStream::VIDEO, 801);
3002
3003   // Read until the end of the stream just to make sure there aren't any other
3004   // config changes.
3005   ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
3006   ASSERT_EQ(status, DemuxerStream::kOk);
3007 }
3008
3009 TEST_F(ChunkDemuxerTest, ConfigChange_Audio) {
3010   InSequence s;
3011
3012   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
3013
3014   DemuxerStream::Status status;
3015   base::TimeDelta last_timestamp;
3016
3017   DemuxerStream* audio = GetStream(DemuxerStream::AUDIO);
3018
3019   // Fetch initial audio config and verify it matches what we expect.
3020   const AudioDecoderConfig& audio_config_1 = audio->audio_decoder_config();
3021   ASSERT_TRUE(audio_config_1.IsValidConfig());
3022   EXPECT_EQ(audio_config_1.samples_per_second(), 44100);
3023   EXPECT_EQ(audio_config_1.extra_data().size(), 3863u);
3024
3025   ExpectRead(DemuxerStream::AUDIO, 0);
3026
3027   // Read until we encounter config 2.
3028   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
3029   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
3030   EXPECT_EQ(last_timestamp.InMilliseconds(), 524);
3031
3032   // Fetch the new decoder config.
3033   const AudioDecoderConfig& audio_config_2 = audio->audio_decoder_config();
3034   ASSERT_TRUE(audio_config_2.IsValidConfig());
3035   EXPECT_EQ(audio_config_2.samples_per_second(), 44100);
3036   EXPECT_EQ(audio_config_2.extra_data().size(), 3935u);
3037
3038   // Read until we encounter config 1 again.
3039   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
3040   ASSERT_EQ(status, DemuxerStream::kConfigChanged);
3041   EXPECT_EQ(last_timestamp.InMilliseconds(), 759);
3042   ASSERT_TRUE(audio_config_1.Matches(audio->audio_decoder_config()));
3043
3044   // Read until the end of the stream just to make sure there aren't any other
3045   // config changes.
3046   ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
3047   ASSERT_EQ(status, DemuxerStream::kOk);
3048   EXPECT_EQ(last_timestamp.InMilliseconds(), 2744);
3049 }
3050
3051 TEST_F(ChunkDemuxerTest, ConfigChange_Seek) {
3052   InSequence s;
3053
3054   ASSERT_TRUE(InitDemuxerWithConfigChangeData());
3055
3056   DemuxerStream* video = GetStream(DemuxerStream::VIDEO);
3057
3058   // Fetch initial video config and verify it matches what we expect.
3059   const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
3060   ASSERT_TRUE(video_config_1.IsValidConfig());
3061   EXPECT_EQ(video_config_1.natural_size().width(), 320);
3062   EXPECT_EQ(video_config_1.natural_size().height(), 240);
3063
3064   ExpectRead(DemuxerStream::VIDEO, 0);
3065
3066   // Seek to a location with a different config.
3067   Seek(base::Milliseconds(527));
3068
3069   // Verify that the config change is signalled.
3070   ExpectConfigChanged(DemuxerStream::VIDEO);
3071
3072   // Fetch the new decoder config and verify it is what we expect.
3073   const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
3074   ASSERT_TRUE(video_config_2.IsValidConfig());
3075   EXPECT_EQ(video_config_2.natural_size().width(), 640);
3076   EXPECT_EQ(video_config_2.natural_size().height(), 360);
3077
3078   // Verify that Read() will return a buffer now.
3079   ExpectRead(DemuxerStream::VIDEO, 527);
3080
3081   // Seek back to the beginning and verify we get another config change.
3082   Seek(base::Milliseconds(0));
3083   ExpectConfigChanged(DemuxerStream::VIDEO);
3084   ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
3085   ExpectRead(DemuxerStream::VIDEO, 0);
3086
3087   // Seek to a location that requires a config change and then
3088   // seek to a new location that has the same configuration as
3089   // the start of the file without a Read() in the middle.
3090   Seek(base::Milliseconds(527));
3091   Seek(base::Milliseconds(801));
3092
3093   // Verify that no config change is signalled.
3094   ExpectRead(DemuxerStream::VIDEO, 801);
3095   ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
3096 }
3097
3098 TEST_F(ChunkDemuxerTest, TimestampPositiveOffset) {
3099   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3100
3101   ASSERT_TRUE(SetTimestampOffset(kSourceId, base::Seconds(30)));
3102   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 2)));
3103
3104   Seek(base::Milliseconds(30000));
3105
3106   GenerateExpectedReads(30000, 2);
3107 }
3108
3109 TEST_F(ChunkDemuxerTest, TimestampNegativeOffset) {
3110   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3111
3112   ASSERT_TRUE(SetTimestampOffset(kSourceId, base::Seconds(-1)));
3113   ASSERT_TRUE(AppendCluster(GenerateCluster(1000, 2)));
3114
3115   GenerateExpectedReads(0, 2);
3116 }
3117
3118 TEST_F(ChunkDemuxerTest, TimestampOffsetSeparateStreams) {
3119   std::string audio_id = "audio1";
3120   std::string video_id = "video1";
3121   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
3122
3123   ASSERT_TRUE(SetTimestampOffset(audio_id, base::Milliseconds(-2500)));
3124   ASSERT_TRUE(SetTimestampOffset(video_id, base::Milliseconds(-2500)));
3125   ASSERT_TRUE(AppendCluster(
3126       audio_id,
3127       GenerateSingleStreamCluster(2500, 2500 + kAudioBlockDuration * 4,
3128                                   kAudioTrackNum, kAudioBlockDuration)));
3129   ASSERT_TRUE(AppendCluster(
3130       video_id,
3131       GenerateSingleStreamCluster(2500, 2500 + kVideoBlockDuration * 4,
3132                                   kVideoTrackNum, kVideoBlockDuration)));
3133   GenerateAudioStreamExpectedReads(0, 4);
3134   GenerateVideoStreamExpectedReads(0, 4);
3135
3136   Seek(base::Milliseconds(27300));
3137
3138   ASSERT_TRUE(SetTimestampOffset(audio_id, base::Milliseconds(27300)));
3139   ASSERT_TRUE(SetTimestampOffset(video_id, base::Milliseconds(27300)));
3140   ASSERT_TRUE(AppendCluster(
3141       audio_id,
3142       GenerateSingleStreamCluster(0, kAudioBlockDuration * 4, kAudioTrackNum,
3143                                   kAudioBlockDuration)));
3144   ASSERT_TRUE(AppendCluster(
3145       video_id,
3146       GenerateSingleStreamCluster(0, kVideoBlockDuration * 4, kVideoTrackNum,
3147                                   kVideoBlockDuration)));
3148   GenerateVideoStreamExpectedReads(27300, 4);
3149   GenerateAudioStreamExpectedReads(27300, 4);
3150 }
3151
3152 TEST_F(ChunkDemuxerTest, IsParsingMediaSegmentMidMediaSegment) {
3153   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3154
3155   std::unique_ptr<Cluster> cluster = GenerateCluster(0, 2);
3156   // Append only part of the cluster data.
3157   ASSERT_TRUE(AppendData(cluster->data(), cluster->size() - 13));
3158
3159   // Confirm we're in the middle of parsing a media segment.
3160   ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId));
3161
3162   demuxer_->ResetParserState(kSourceId,
3163                              append_window_start_for_next_append_,
3164                              append_window_end_for_next_append_,
3165                              &timestamp_offset_map_[kSourceId]);
3166
3167   // After ResetParserState(), parsing should no longer be in the middle of a
3168   // media segment.
3169   ASSERT_FALSE(demuxer_->IsParsingMediaSegment(kSourceId));
3170 }
3171
3172 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
3173 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
3174 namespace {
3175 const char* kMp2tMimeType = "video/mp2t";
3176 const char* kMp2tCodecs = "mp4a.40.2,avc1.640028";
3177 }
3178
3179 TEST_F(ChunkDemuxerTest, EmitBuffersDuringAbort) {
3180   EXPECT_CALL(*this, DemuxerOpened());
3181   EXPECT_FOUND_CODEC_NAME(Audio, "aac");
3182   EXPECT_FOUND_CODEC_NAME(Video, "h264");
3183   demuxer_->Initialize(&host_,
3184                        CreateInitDoneCallback(kInfiniteDuration, PIPELINE_OK));
3185   EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, kMp2tMimeType, kMp2tCodecs));
3186
3187   // For info:
3188   // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode
3189   // Video: first PES:
3190   //        PTS: 126912 (0x0001efc0)  [= 90 kHz-Timestamp: 0:00:01.4101]
3191   //        DTS: 123909 (0x0001e405)  [= 90 kHz-Timestamp: 0:00:01.3767]
3192   // Audio: first PES:
3193   //        PTS: 126000 (0x0001ec30)  [= 90 kHz-Timestamp: 0:00:01.4000]
3194   //        DTS: 123910 (0x0001e406)  [= 90 kHz-Timestamp: 0:00:01.3767]
3195   // Video: last PES:
3196   //        PTS: 370155 (0x0005a5eb)  [= 90 kHz-Timestamp: 0:00:04.1128]
3197   //        DTS: 367152 (0x00059a30)  [= 90 kHz-Timestamp: 0:00:04.0794]
3198   // Audio: last PES:
3199   //        PTS: 353788 (0x000565fc)  [= 90 kHz-Timestamp: 0:00:03.9309]
3200
3201   scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts");
3202   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
3203
3204   // This mp2ts file contains buffers which can trigger media logs related to
3205   // splicing, especially when appending in small chunks.
3206   EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(1655422, 1655419, 23217));
3207   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(1957277, 4));
3208   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(2514555, 6));
3209   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(3071833, 6));
3210   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(3652333, 6));
3211
3212   // Append the media in small chunks.
3213   size_t appended_bytes = 0;
3214   const size_t chunk_size = 1024;
3215   while (appended_bytes < buffer->data_size()) {
3216     size_t cur_chunk_size =
3217         std::min(chunk_size, buffer->data_size() - appended_bytes);
3218     ASSERT_TRUE(
3219         AppendData(kSourceId, buffer->data() + appended_bytes, cur_chunk_size));
3220     appended_bytes += cur_chunk_size;
3221   }
3222
3223   // Confirm we're in the middle of parsing a media segment.
3224   ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId));
3225
3226   // ResetParserState on the Mpeg2 TS parser triggers the emission of the last
3227   // video buffer which is pending in the stream parser.
3228   Ranges<base::TimeDelta> range_before_abort =
3229       demuxer_->GetBufferedRanges(kSourceId);
3230   demuxer_->ResetParserState(kSourceId,
3231                              append_window_start_for_next_append_,
3232                              append_window_end_for_next_append_,
3233                              &timestamp_offset_map_[kSourceId]);
3234   Ranges<base::TimeDelta> range_after_abort =
3235       demuxer_->GetBufferedRanges(kSourceId);
3236
3237   ASSERT_EQ(range_before_abort.size(), 1u);
3238   ASSERT_EQ(range_after_abort.size(), 1u);
3239   EXPECT_EQ(range_after_abort.start(0), range_before_abort.start(0));
3240   EXPECT_GT(range_after_abort.end(0), range_before_abort.end(0));
3241 }
3242
3243 TEST_F(ChunkDemuxerTest, SeekCompleteDuringAbort) {
3244   EXPECT_CALL(*this, DemuxerOpened());
3245   EXPECT_FOUND_CODEC_NAME(Video, "h264");
3246   EXPECT_FOUND_CODEC_NAME(Audio, "aac");
3247   demuxer_->Initialize(&host_,
3248                        CreateInitDoneCallback(kInfiniteDuration, PIPELINE_OK));
3249   EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, kMp2tMimeType, kMp2tCodecs));
3250
3251   // For info:
3252   // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode
3253   // Video: first PES:
3254   //        PTS: 126912 (0x0001efc0)  [= 90 kHz-Timestamp: 0:00:01.4101]
3255   //        DTS: 123909 (0x0001e405)  [= 90 kHz-Timestamp: 0:00:01.3767]
3256   // Audio: first PES:
3257   //        PTS: 126000 (0x0001ec30)  [= 90 kHz-Timestamp: 0:00:01.4000]
3258   //        DTS: 123910 (0x0001e406)  [= 90 kHz-Timestamp: 0:00:01.3767]
3259   // Video: last PES:
3260   //        PTS: 370155 (0x0005a5eb)  [= 90 kHz-Timestamp: 0:00:04.1128]
3261   //        DTS: 367152 (0x00059a30)  [= 90 kHz-Timestamp: 0:00:04.0794]
3262   // Audio: last PES:
3263   //        PTS: 353788 (0x000565fc)  [= 90 kHz-Timestamp: 0:00:03.9309]
3264
3265   scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts");
3266   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
3267
3268   // This mp2ts file contains buffers which can trigger media logs related to
3269   // splicing, especially when appending in small chunks.
3270   EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(1655422, 1655419, 23217));
3271   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(1957277, 4));
3272   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(2514555, 6));
3273   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(3071833, 6));
3274   EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(3652333, 6));
3275
3276   // Append the media in small chunks.
3277   size_t appended_bytes = 0;
3278   const size_t chunk_size = 1024;
3279   while (appended_bytes < buffer->data_size()) {
3280     size_t cur_chunk_size =
3281         std::min(chunk_size, buffer->data_size() - appended_bytes);
3282     ASSERT_TRUE(
3283         AppendData(kSourceId, buffer->data() + appended_bytes, cur_chunk_size));
3284     appended_bytes += cur_chunk_size;
3285   }
3286
3287   // Confirm we're in the middle of parsing a media segment.
3288   ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId));
3289
3290   // Seek to a time corresponding to buffers that will be emitted during the
3291   // abort.
3292   Seek(base::Milliseconds(4110));
3293
3294   // ResetParserState on the Mpeg2 TS parser triggers the emission of the last
3295   // video buffer which is pending in the stream parser.
3296   demuxer_->ResetParserState(kSourceId,
3297                              append_window_start_for_next_append_,
3298                              append_window_end_for_next_append_,
3299                              &timestamp_offset_map_[kSourceId]);
3300 }
3301
3302 #endif
3303 #endif
3304
3305 TEST_F(ChunkDemuxerTest, WebMIsParsingMediaSegmentDetection) {
3306   const uint8_t kBuffer[] = {
3307       // CLUSTER (size = 10)
3308       0x1F, 0x43, 0xB6, 0x75, 0x8A,
3309
3310       // Cluster TIMECODE (value = 1)
3311       0xE7, 0x81, 0x01,
3312
3313       // SIMPLEBLOCK (size = 5)
3314       0xA3, 0x85,
3315
3316       // Audio Track Number
3317       0x80 | (kAudioTrackNum & 0x7F),
3318
3319       // Timecode (relative to cluster) (value = 0)
3320       0x00, 0x00,
3321
3322       // Keyframe flag
3323       0x80,
3324
3325       // Fake block data
3326       0x00,
3327
3328       // CLUSTER (size = unknown; really 10)
3329       0x1F, 0x43, 0xB6, 0x75, 0xFF,
3330
3331       // Cluster TIMECODE (value = 2)
3332       0xE7, 0x81, 0x02,
3333
3334       // SIMPLEBLOCK (size = 5)
3335       0xA3, 0x85,
3336
3337       // Audio Track Number
3338       0x80 | (kAudioTrackNum & 0x7F),
3339
3340       // Timecode (relative to cluster) (value = 0)
3341       0x00, 0x00,
3342
3343       // Keyframe flag
3344       0x80,
3345
3346       // Fake block data
3347       0x00,
3348
3349       // EBMLHEADER (size = 10, not fully appended)
3350       0x1A, 0x45, 0xDF, 0xA3, 0x8A,
3351   };
3352
3353   // This array indicates expected return value of IsParsingMediaSegment()
3354   // following each incrementally appended byte in |kBuffer|.
3355   const bool kExpectedReturnValues[] = {
3356       // First Cluster, explicit size
3357       false, false, false, false, true, true, true, true, true, true, true,
3358       true, true, true, false,
3359
3360       // Second Cluster, unknown size
3361       false, false, false, false, true, true, true, true, true, true, true,
3362       true, true, true, true,
3363
3364       // EBMLHEADER
3365       true, true, true, true, false,
3366   };
3367
3368   static_assert(std::size(kBuffer) == std::size(kExpectedReturnValues),
3369                 "test arrays out of sync");
3370   static_assert(std::size(kBuffer) == sizeof(kBuffer),
3371                 "there should be one byte per index");
3372
3373   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3374   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23)).Times(2);
3375   for (size_t i = 0; i < sizeof(kBuffer); i++) {
3376     DVLOG(3) << "Appending and testing index " << i;
3377     ASSERT_TRUE(AppendData(kBuffer + i, 1));
3378     bool expected_return_value = kExpectedReturnValues[i];
3379     EXPECT_EQ(expected_return_value,
3380               demuxer_->IsParsingMediaSegment(kSourceId));
3381   }
3382 }
3383
3384 TEST_F(ChunkDemuxerTest, DurationChange) {
3385   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3386   const int kStreamDuration = kDefaultDuration().InMilliseconds();
3387
3388   // Add data leading up to the currently set duration.
3389   ASSERT_TRUE(
3390       AppendCluster(GenerateCluster(kStreamDuration - kAudioBlockDuration,
3391                                     kStreamDuration - kVideoBlockDuration, 2)));
3392
3393   CheckExpectedRanges("{ [201191,201224) }");
3394
3395   // Add data beginning at the currently set duration and expect a new duration
3396   // to be signaled. Note that the last video block will have a higher end
3397   // timestamp than the last audio block.
3398   const int kNewStreamDurationVideo = kStreamDuration + kVideoBlockDuration;
3399   EXPECT_CALL(host_, SetDuration(base::Milliseconds(kNewStreamDurationVideo)));
3400   ASSERT_TRUE(
3401       AppendCluster(GenerateCluster(kDefaultDuration().InMilliseconds(), 2)));
3402
3403   CheckExpectedRanges("{ [201191,201247) }");
3404
3405   // Add more data to the end of each media type. Note that the last audio block
3406   // will have a higher end timestamp than the last video block.
3407   const int kFinalStreamDuration = kStreamDuration + kAudioBlockDuration * 3;
3408   EXPECT_CALL(host_, SetDuration(base::Milliseconds(kFinalStreamDuration)));
3409   ASSERT_TRUE(
3410       AppendCluster(GenerateCluster(kStreamDuration + kAudioBlockDuration,
3411                                     kStreamDuration + kVideoBlockDuration, 3)));
3412
3413   // See that the range has increased appropriately (but not to the full
3414   // duration of 201293, since there is not enough video appended for that).
3415   CheckExpectedRanges("{ [201191,201290) }");
3416 }
3417
3418 TEST_F(ChunkDemuxerTest, DurationChangeTimestampOffset) {
3419   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3420   ASSERT_TRUE(SetTimestampOffset(kSourceId, kDefaultDuration()));
3421   EXPECT_CALL(host_, SetDuration(kDefaultDuration() +
3422                                  base::Milliseconds(kVideoBlockDuration * 2)));
3423   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 4)));
3424 }
3425
3426 TEST_F(ChunkDemuxerTest, EndOfStreamTruncateDuration) {
3427   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3428
3429   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
3430
3431   EXPECT_CALL(
3432       host_, SetDuration(base::Milliseconds(kDefaultFirstClusterEndTimestamp)));
3433   MarkEndOfStream(PIPELINE_OK);
3434 }
3435
3436 TEST_F(ChunkDemuxerTest, ZeroLengthAppend) {
3437   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3438   ASSERT_TRUE(AppendData(NULL, 0));
3439 }
3440
3441 TEST_F(ChunkDemuxerTest, AppendAfterEndOfStream) {
3442   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3443
3444   EXPECT_CALL(host_, SetDuration(_))
3445       .Times(AnyNumber());
3446
3447   ASSERT_TRUE(AppendCluster(kDefaultFirstCluster()));
3448   MarkEndOfStream(PIPELINE_OK);
3449
3450   demuxer_->UnmarkEndOfStream();
3451
3452   ASSERT_TRUE(AppendCluster(kDefaultSecondCluster()));
3453   MarkEndOfStream(PIPELINE_OK);
3454 }
3455
3456 // Test receiving a Shutdown() call before we get an Initialize()
3457 // call. This can happen if video element gets destroyed before
3458 // the pipeline has a chance to initialize the demuxer.
3459 TEST_F(ChunkDemuxerTest, Shutdown_BeforeInitialize) {
3460   demuxer_->Shutdown();
3461   demuxer_->Initialize(&host_,
3462                        CreateInitDoneCallback(DEMUXER_ERROR_COULD_NOT_OPEN));
3463   base::RunLoop().RunUntilIdle();
3464 }
3465
3466 // Verifies that signaling end of stream while stalled at a gap
3467 // boundary does not trigger end of stream buffers to be returned.
3468 TEST_F(ChunkDemuxerTest, EndOfStreamWhileWaitingForGapToBeFilled) {
3469   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3470
3471   ASSERT_TRUE(AppendCluster(0, 10));
3472   ASSERT_TRUE(AppendCluster(300, 10));
3473   CheckExpectedRanges("{ [0,132) [300,432) }");
3474
3475   GenerateExpectedReads(0, 10);
3476
3477   bool audio_read_done = false;
3478   bool video_read_done = false;
3479   ReadAudio(
3480       base::BindOnce(&OnReadDone, base::Milliseconds(138), &audio_read_done));
3481   ReadVideo(
3482       base::BindOnce(&OnReadDone, base::Milliseconds(138), &video_read_done));
3483
3484   // Verify that the reads didn't complete
3485   EXPECT_FALSE(audio_read_done);
3486   EXPECT_FALSE(video_read_done);
3487
3488   EXPECT_CALL(host_, SetDuration(base::Milliseconds(438)));
3489   MarkEndOfStream(PIPELINE_OK);
3490
3491   // Verify that the reads still haven't completed.
3492   EXPECT_FALSE(audio_read_done);
3493   EXPECT_FALSE(video_read_done);
3494
3495   demuxer_->UnmarkEndOfStream();
3496
3497   ASSERT_TRUE(AppendCluster(138, 22));
3498
3499   base::RunLoop().RunUntilIdle();
3500
3501   CheckExpectedRanges("{ [0,435) }");
3502
3503   // Verify that the reads have completed.
3504   EXPECT_TRUE(audio_read_done);
3505   EXPECT_TRUE(video_read_done);
3506
3507   // Read the rest of the buffers.
3508   GenerateExpectedReads(161, 171, 20);
3509
3510   // Verify that reads block because the append cleared the end of stream state.
3511   audio_read_done = false;
3512   video_read_done = false;
3513   ReadAudio(base::BindOnce(&OnReadDone_EOSExpected, &audio_read_done));
3514   ReadVideo(base::BindOnce(&OnReadDone_EOSExpected, &video_read_done));
3515
3516   // Verify that the reads don't complete.
3517   EXPECT_FALSE(audio_read_done);
3518   EXPECT_FALSE(video_read_done);
3519
3520   EXPECT_CALL(host_, SetDuration(base::Milliseconds(437)));
3521   MarkEndOfStream(PIPELINE_OK);
3522
3523   EXPECT_TRUE(audio_read_done);
3524   EXPECT_TRUE(video_read_done);
3525 }
3526
3527 TEST_F(ChunkDemuxerTest, CanceledSeekDuringInitialPreroll) {
3528   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3529
3530   // Cancel preroll.
3531   base::TimeDelta seek_time = base::Milliseconds(200);
3532   demuxer_->CancelPendingSeek(seek_time);
3533
3534   // Initiate the seek to the new location.
3535   Seek(seek_time);
3536
3537   // Append data to satisfy the seek.
3538   ASSERT_TRUE(AppendCluster(seek_time.InMilliseconds(), 10));
3539 }
3540
3541 TEST_F(ChunkDemuxerTest, SetMemoryLimitType) {
3542   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3543
3544   // Set different memory limits for audio and video.
3545   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
3546   demuxer_->SetMemoryLimitsForTest(DemuxerStream::VIDEO, 5 * block_size_ + 1);
3547
3548   base::TimeDelta seek_time = base::Milliseconds(1000);
3549
3550   // Append data at the start that can be garbage collected:
3551   AppendMuxedCluster(
3552       MuxedStreamInfo(kAudioTrackNum,
3553                       "0K 23K 46K 69K 92K 115K 138K 161K 184K 207K", 23),
3554       MuxedStreamInfo(kVideoTrackNum, "0K 33K 66K 99K 132K", 33));
3555
3556   // We should be right at buffer limit, should pass
3557   EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, base::Milliseconds(0), 0));
3558
3559   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,230) }");
3560   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,165) }");
3561
3562   // Seek so we can garbage collect the data appended above.
3563   Seek(seek_time);
3564
3565   // Append data at seek_time.
3566   AppendMuxedCluster(
3567       MuxedStreamInfo(
3568           kAudioTrackNum,
3569           "1000K 1023K 1046K 1069K 1092K 1115K 1138K 1161K 1184K 1207K", 23),
3570       MuxedStreamInfo(kVideoTrackNum, "1000K 1033K 1066K 1099K 1132K", 33));
3571
3572   // We should delete first append, and be exactly at buffer limit
3573   EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 0));
3574
3575   // Verify that the old data, and nothing more, has been garbage collected.
3576   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [1000,1230) }");
3577   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [1000,1165) }");
3578 }
3579
3580 TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekForward) {
3581   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3582   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
3583   // Append some data at position 1000ms
3584   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 10);
3585   CheckExpectedRanges("{ [1000,1230) }");
3586
3587   // GC should be able to evict frames in the currently buffered range, since
3588   // those frames are earlier than the seek target position.
3589   base::TimeDelta seek_time = base::Milliseconds(2000);
3590   Seek(seek_time);
3591   EXPECT_TRUE(
3592       demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * block_size_));
3593
3594   // Append data to complete seek operation
3595   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3596   CheckExpectedRanges("{ [1115,1230) [2000,2115) }");
3597 }
3598
3599 TEST_F(ChunkDemuxerTest, GCDuringSeek_SingleRange_SeekBack) {
3600   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3601   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
3602   // Append some data at position 1000ms
3603   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 10);
3604   CheckExpectedRanges("{ [1000,1230) }");
3605
3606   // GC should be able to evict frames in the currently buffered range, since
3607   // seek target position has no data and so we should allow some frames to be
3608   // evicted to make space for the upcoming append at seek target position.
3609   base::TimeDelta seek_time = base::TimeDelta();
3610   Seek(seek_time);
3611   EXPECT_TRUE(
3612       demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * block_size_));
3613
3614   // Append data to complete seek operation
3615   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 5);
3616   CheckExpectedRanges("{ [0,115) [1115,1230) }");
3617 }
3618
3619 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekForward) {
3620   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3621   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
3622   // Append some data at position 1000ms then at 2000ms
3623   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3624   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3625   CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3626
3627   // GC should be able to evict frames in the currently buffered ranges, since
3628   // those frames are earlier than the seek target position.
3629   base::TimeDelta seek_time = base::Milliseconds(3000);
3630   Seek(seek_time);
3631   EXPECT_TRUE(
3632       demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * block_size_));
3633
3634   // Append data to complete seek operation
3635   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 3000, 5);
3636   CheckExpectedRanges("{ [2069,2115) [3000,3115) }");
3637 }
3638
3639 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween1) {
3640   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3641   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
3642   // Append some data at position 1000ms then at 2000ms
3643   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3644   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3645   CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3646
3647   // GC should be able to evict all frames from the first buffered range, since
3648   // those frames are earlier than the seek target position. But there's only 5
3649   // blocks worth of data in the first range and seek target position has no
3650   // data, so GC proceeds with trying to delete some frames from the back of
3651   // buffered ranges, that doesn't yield anything, since that's the most
3652   // recently appended data, so then GC starts removing data from the front of
3653   // the remaining buffered range (2000ms) to ensure we free up enough space for
3654   // the upcoming append and allow seek to proceed.
3655   base::TimeDelta seek_time = base::Milliseconds(1500);
3656   Seek(seek_time);
3657   EXPECT_TRUE(
3658       demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * block_size_));
3659
3660   // Append data to complete seek operation
3661   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1500, 5);
3662   CheckExpectedRanges("{ [1500,1615) [2069,2115) }");
3663 }
3664
3665 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekInbetween2) {
3666   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3667   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
3668
3669   // Append some data at position 2000ms first, then at 1000ms, so that the last
3670   // appended data position is in the first buffered range (that matters to the
3671   // GC algorithm since it tries to preserve more recently appended data).
3672   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3673   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3674   CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3675
3676   // Now try performing garbage collection without announcing seek first, i.e.
3677   // without calling Seek(), the GC algorithm should try to preserve data in the
3678   // first range, since that is most recently appended data.
3679   base::TimeDelta seek_time = base::Milliseconds(2030);
3680   EXPECT_TRUE(
3681       demuxer_->EvictCodedFrames(kSourceId, seek_time, 5 * block_size_));
3682
3683   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1500, 5);
3684   CheckExpectedRanges("{ [1000,1115) [1500,1615) }");
3685 }
3686
3687 TEST_F(ChunkDemuxerTest, GCDuringSeek_MultipleRanges_SeekBack) {
3688   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3689   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
3690   // Append some data at position 1000ms then at 2000ms
3691   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 1000, 5);
3692   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 2000, 5);
3693   CheckExpectedRanges("{ [1000,1115) [2000,2115) }");
3694
3695   // GC should be able to evict frames in the currently buffered ranges, since
3696   // those frames are earlier than the seek target position.
3697   base::TimeDelta seek_time = base::TimeDelta();
3698   Seek(seek_time);
3699   EXPECT_TRUE(
3700       demuxer_->EvictCodedFrames(kSourceId, seek_time, 8 * block_size_));
3701
3702   // Append data to complete seek operation
3703   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 5);
3704   CheckExpectedRanges("{ [0,115) [2069,2115) }");
3705 }
3706
3707 TEST_F(ChunkDemuxerTest, GCDuringSeek) {
3708   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3709
3710   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 5 * block_size_);
3711
3712   base::TimeDelta seek_time1 = base::Milliseconds(1000);
3713   base::TimeDelta seek_time2 = base::Milliseconds(500);
3714
3715   // Initiate a seek to |seek_time1|.
3716   Seek(seek_time1);
3717
3718   // Append data to satisfy the first seek request.
3719   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3720                             seek_time1.InMilliseconds(), 5);
3721   CheckExpectedRanges("{ [1000,1115) }");
3722
3723   // We are under memory limit, so Evict should be a no-op.
3724   EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time1, 0));
3725   CheckExpectedRanges("{ [1000,1115) }");
3726
3727   // Signal that the second seek is starting.
3728   demuxer_->StartWaitingForSeek(seek_time2);
3729
3730   // Append data to satisfy the second seek.
3731   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3732                             seek_time2.InMilliseconds(), 5);
3733   CheckExpectedRanges("{ [500,615) [1000,1115) }");
3734
3735   // We are now over our memory usage limit. We have just seeked to |seek_time2|
3736   // so data around 500ms position should be preserved, while the previous
3737   // append at 1000ms should be removed.
3738   EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0));
3739   CheckExpectedRanges("{ [500,615) }");
3740
3741   // Complete the seek.
3742   demuxer_->Seek(seek_time2, NewExpectedStatusCB(PIPELINE_OK));
3743
3744   // Append more data and make sure that we preserve both the buffered range
3745   // around |seek_time2|, because that's the current playback position,
3746   // and the newly appended range, since this is the most recent append.
3747   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5);
3748   EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0));
3749   CheckExpectedRanges("{ [500,615) [700,815) }");
3750 }
3751
3752 TEST_F(ChunkDemuxerTest, GCKeepPlayhead) {
3753   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3754
3755   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 5 * block_size_);
3756
3757   // Append data at the start that can be garbage collected:
3758   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
3759   CheckExpectedRanges("{ [0,230) }");
3760
3761   // We expect garbage collection to fail, as we don't want to spontaneously
3762   // create gaps in source buffer stream. Gaps could break playback for many
3763   // clients, who don't bother to check ranges after append.
3764   EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, base::Milliseconds(0), 0));
3765   CheckExpectedRanges("{ [0,230) }");
3766
3767   // Increase media_time a bit, this will allow some data to be collected, but
3768   // we are still over memory usage limit.
3769   base::TimeDelta seek_time1 = base::Milliseconds(23 * 2);
3770   Seek(seek_time1);
3771   EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time1, 0));
3772   CheckExpectedRanges("{ [46,230) }");
3773
3774   base::TimeDelta seek_time2 = base::Milliseconds(23 * 4);
3775   Seek(seek_time2);
3776   EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0));
3777   CheckExpectedRanges("{ [92,230) }");
3778
3779   // media_time has progressed to a point where we can collect enough data to
3780   // be under memory limit, so Evict should return true.
3781   base::TimeDelta seek_time3 = base::Milliseconds(23 * 6);
3782   Seek(seek_time3);
3783   EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time3, 0));
3784   // Strictly speaking the current playback time is 23*6==138ms, so we could
3785   // release data up to 138ms, but we only release as much data as necessary
3786   // to bring memory usage under the limit, so we release only up to 115ms.
3787   CheckExpectedRanges("{ [115,230) }");
3788 }
3789
3790 TEST_F(ChunkDemuxerTest, AppendWindow_Video) {
3791   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
3792   DemuxerStream* stream = GetStream(DemuxerStream::VIDEO);
3793
3794   // Set the append window to [50,280).
3795   append_window_start_for_next_append_ = base::Milliseconds(50);
3796   append_window_end_for_next_append_ = base::Milliseconds(280);
3797
3798   // Append a cluster that starts before and ends after the append window.
3799   EXPECT_MEDIA_LOG(DroppedFrame("video", 0));
3800   EXPECT_MEDIA_LOG(DroppedFrame("video", 30000));
3801   EXPECT_MEDIA_LOG(DroppedFrame("video", 270000));
3802   EXPECT_MEDIA_LOG(DroppedFrame("video", 300000));
3803   EXPECT_MEDIA_LOG(DroppedFrame("video", 330000));
3804   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(30));
3805   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3806                             "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
3807
3808   // Verify that GOPs that start outside the window are not included
3809   // in the buffer. Also verify that buffers that start inside the
3810   // window and extend beyond the end of the window are not included.
3811   CheckExpectedRanges("{ [120,270) }");
3812   CheckExpectedBuffers(stream, "120K 150 180 210 240K");
3813
3814   // Extend the append window to [50,650).
3815   append_window_end_for_next_append_ = base::Milliseconds(650);
3816
3817   // Append more data and verify that adding buffers start at the next
3818   // key frame.
3819   EXPECT_MEDIA_LOG(DroppedFrame("video", 630000));
3820   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(30));
3821   AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3822                             "360 390 420K 450 480 510 540K 570 600 630K");
3823   CheckExpectedRanges("{ [120,270) [420,630) }");
3824 }
3825
3826 TEST_F(ChunkDemuxerTest, AppendWindow_Audio) {
3827   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3828   DemuxerStream* stream = GetStream(DemuxerStream::AUDIO);
3829
3830   // Set the append window to [50,280).
3831   append_window_start_for_next_append_ = base::Milliseconds(50);
3832   append_window_end_for_next_append_ = base::Milliseconds(280);
3833
3834   // Append a cluster that starts before and ends after the append window.
3835   EXPECT_MEDIA_LOG(DroppedFrame("audio", 0));
3836   EXPECT_MEDIA_LOG(TruncatedFrame(30000, 60000, "start", 50000));
3837   EXPECT_MEDIA_LOG(TruncatedFrame(270000, 300000, "end", 280000));
3838   EXPECT_MEDIA_LOG(DroppedFrame("audio", 300000));
3839   EXPECT_MEDIA_LOG(DroppedFrame("audio", 330000));
3840   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(30));
3841   AppendSingleStreamCluster(
3842       kSourceId, kAudioTrackNum,
3843       "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K");
3844
3845   // Verify that frames that end outside the window are not included
3846   // in the buffer. Also verify that buffers that start inside the
3847   // window and extend beyond the end of the window are not included.
3848   //
3849   // The first 50ms of the range should be truncated since it overlaps
3850   // the start of the append window.
3851   CheckExpectedRanges("{ [50,280) }");
3852
3853   // The "50P" buffer is the "0" buffer marked for complete discard.  The next
3854   // "50" buffer is the "30" buffer marked with 20ms of start discard.
3855   CheckExpectedBuffers(stream, "50KP 50K 60K 90K 120K 150K 180K 210K 240K");
3856
3857   // Extend the append window to [50,650).
3858   append_window_end_for_next_append_ = base::Milliseconds(650);
3859
3860   // Append more data and verify that a new range is created.
3861   EXPECT_MEDIA_LOG(TruncatedFrame(630000, 660000, "end", 650000));
3862   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(30));
3863   AppendSingleStreamCluster(
3864       kSourceId, kAudioTrackNum,
3865       "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K");
3866   CheckExpectedRanges("{ [50,280) [360,650) }");
3867 }
3868
3869 TEST_F(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) {
3870   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3871
3872   // Set the append window to [10,20).
3873   append_window_start_for_next_append_ = base::Milliseconds(10);
3874   append_window_end_for_next_append_ = base::Milliseconds(20);
3875
3876   EXPECT_MEDIA_LOG(
3877       TruncatedFrame(0, kAudioBlockDuration * 1000, "start", 10000));
3878   EXPECT_MEDIA_LOG(
3879       TruncatedFrame(10000, kAudioBlockDuration * 1000, "end", 20000));
3880
3881   // Append a cluster that starts before and ends after the append window.
3882   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(
3883       WebMClusterParser::kDefaultAudioBufferDurationInMs));
3884   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K");
3885
3886   // Verify the append is clipped to the append window.
3887   CheckExpectedRanges("{ [10,20) }");
3888 }
3889
3890 TEST_F(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) {
3891   EXPECT_CALL(*this, DemuxerOpened());
3892   demuxer_->Initialize(
3893       &host_, CreateInitDoneCallback(base::Milliseconds(2744), PIPELINE_OK));
3894   ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO));
3895
3896   // Set the append window to [50,150).
3897   append_window_start_for_next_append_ = base::Milliseconds(50);
3898   append_window_end_for_next_append_ = base::Milliseconds(150);
3899
3900   EXPECT_MEDIA_LOG(DroppedFrameCheckAppendWindow(
3901                        "audio",
3902                        append_window_start_for_next_append_.InMicroseconds(),
3903                        append_window_end_for_next_append_.InMicroseconds()))
3904       .Times(AtLeast(1));
3905   EXPECT_MEDIA_LOG(TruncatedFrame(39000, 62000, "start", 50000));
3906   EXPECT_MEDIA_LOG(TruncatedFrame(141000, 164000, "end", 150000));
3907
3908   // Read a WebM file into memory and send the data to the demuxer.  The chunk
3909   // size has been chosen carefully to ensure the preroll buffer used by the
3910   // partial append window trim must come from a previous Append() call.
3911   scoped_refptr<DecoderBuffer> buffer =
3912       ReadTestDataFile("bear-320x240-audio-only.webm");
3913   ExpectInitMediaLogs(HAS_AUDIO);
3914   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
3915   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2));
3916   ASSERT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 128));
3917
3918   DemuxerStream* stream = GetStream(DemuxerStream::AUDIO);
3919   CheckExpectedBuffers(stream, "50KP 50K 62K 86K 109K 122K 125K 128K");
3920 }
3921
3922 TEST_F(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) {
3923   EXPECT_CALL(*this, DemuxerOpened());
3924   demuxer_->Initialize(
3925       &host_, CreateInitDoneCallback(base::Milliseconds(2744), PIPELINE_OK));
3926   ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO));
3927
3928   // Set the append window such that the first file is completely before the
3929   // append window.
3930   // Expect duration adjustment since actual duration differs slightly from
3931   // duration in the init segment.
3932   const base::TimeDelta duration_1 = base::Milliseconds(2768);
3933   append_window_start_for_next_append_ = duration_1;
3934
3935   EXPECT_MEDIA_LOG(DroppedFrameCheckAppendWindow(
3936                        "audio",
3937                        append_window_start_for_next_append_.InMicroseconds(),
3938                        append_window_end_for_next_append_.InMicroseconds()))
3939       .Times(AtLeast(1));
3940
3941   // Read a WebM file into memory and append the data.
3942   scoped_refptr<DecoderBuffer> buffer =
3943       ReadTestDataFile("bear-320x240-audio-only.webm");
3944   ExpectInitMediaLogs(HAS_AUDIO);
3945   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
3946   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(2));
3947   ASSERT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
3948   CheckExpectedRanges("{ }");
3949
3950   DemuxerStream* stream = GetStream(DemuxerStream::AUDIO);
3951   AudioDecoderConfig config_1 = stream->audio_decoder_config();
3952
3953   // Read a second WebM with a different config in and append the data.
3954   scoped_refptr<DecoderBuffer> buffer2 =
3955       ReadTestDataFile("bear-320x240-audio-only-48khz.webm");
3956   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
3957   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(22));
3958   EXPECT_CALL(host_, SetDuration(_)).Times(AnyNumber());
3959   ASSERT_TRUE(SetTimestampOffset(kSourceId, duration_1));
3960   ASSERT_TRUE(AppendDataInPieces(buffer2->data(), buffer2->data_size(), 512));
3961   CheckExpectedRanges("{ [2768,5542) }");
3962
3963   Seek(duration_1);
3964   ExpectConfigChanged(DemuxerStream::AUDIO);
3965   ASSERT_FALSE(config_1.Matches(stream->audio_decoder_config()));
3966   CheckExpectedBuffers(stream, "2768K 2789K 2811K 2832K");
3967 }
3968
3969 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) {
3970   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3971   EXPECT_MEDIA_LOG(StreamParsingFailed());
3972   EXPECT_CALL(host_,
3973               OnDemuxerError(HasStatusCode(CHUNK_DEMUXER_ERROR_APPEND_FAILED)));
3974   AppendGarbage();
3975   base::TimeDelta seek_time = base::Seconds(50);
3976   demuxer_->StartWaitingForSeek(seek_time);
3977 }
3978
3979 TEST_F(ChunkDemuxerTest, Remove_AudioVideoText) {
3980   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3981
3982   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
3983   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
3984
3985   AppendMuxedCluster(
3986       MuxedStreamInfo(kAudioTrackNum, "0K 20K 40K 60K 80K 100K 120K 140K", 20),
3987       MuxedStreamInfo(kVideoTrackNum, "0K 30 60 90 120K 150 180", 30));
3988
3989   CheckExpectedBuffers(audio_stream, "0K 20K 40K 60K 80K 100K 120K 140K");
3990   CheckExpectedBuffers(video_stream, "0K 30 60 90 120K 150 180");
3991
3992   // Remove the buffers that were added.
3993   demuxer_->Remove(kSourceId, base::TimeDelta(), base::Milliseconds(300));
3994
3995   // Verify that all the appended data has been removed.
3996   CheckExpectedRanges("{ }");
3997
3998   // Append new buffers that are clearly different than the original
3999   // ones and verify that only the new buffers are returned.
4000   AppendMuxedCluster(
4001       MuxedStreamInfo(kAudioTrackNum, "1K 21K 41K 61K 81K 101K 121K 141K", 20),
4002       MuxedStreamInfo(kVideoTrackNum, "1K 31 61 91 121K 151 181", 30));
4003
4004   Seek(base::TimeDelta());
4005   CheckExpectedBuffers(audio_stream, "1K 21K 41K 61K 81K 101K 121K 141K");
4006   CheckExpectedBuffers(video_stream, "1K 31 61 91 121K 151 181");
4007 }
4008
4009 TEST_F(ChunkDemuxerTest, Remove_StartAtDuration) {
4010   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
4011   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
4012
4013   // Set the duration to something small so that the append that
4014   // follows updates the duration to reflect the end of the appended data.
4015   EXPECT_CALL(host_, SetDuration(base::Milliseconds(1)));
4016   demuxer_->SetDuration(0.001);
4017
4018   EXPECT_CALL(host_, SetDuration(base::Milliseconds(160)));
4019   AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
4020                             "0K 20K 40K 60K 80K 100K 120K 140D20K");
4021
4022   CheckExpectedRanges("{ [0,160) }");
4023   CheckExpectedBuffers(audio_stream, "0K 20K 40K 60K 80K 100K 120K 140K");
4024
4025   demuxer_->Remove(kSourceId, base::Seconds(demuxer_->GetDuration()),
4026                    kInfiniteDuration);
4027
4028   Seek(base::TimeDelta());
4029   CheckExpectedRanges("{ [0,160) }");
4030   CheckExpectedBuffers(audio_stream, "0K 20K 40K 60K 80K 100K 120K 140K");
4031 }
4032
4033 // Verifies that a Seek() will complete without text cues for
4034 // the seek point and will return cues after the seek position
4035 // when they are eventually appended.
4036 TEST_F(ChunkDemuxerTest, SeekCompletesWithoutTextCues) {
4037   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4038
4039   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
4040   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4041
4042   base::TimeDelta seek_time = base::Milliseconds(120);
4043   bool seek_cb_was_called = false;
4044   demuxer_->StartWaitingForSeek(seek_time);
4045   demuxer_->Seek(seek_time,
4046                  base::BindOnce(OnSeekDone_OKExpected, &seek_cb_was_called));
4047   base::RunLoop().RunUntilIdle();
4048
4049   EXPECT_FALSE(seek_cb_was_called);
4050
4051   // Append audio & video data so the seek completes.
4052   AppendMuxedCluster(
4053       MuxedStreamInfo(kAudioTrackNum,
4054                       "0K 20K 40K 60K 80K 100K 120K 140K 160K 180K 200K", 20),
4055       MuxedStreamInfo(kVideoTrackNum, "0K 30 60 90 120K 150 180 210", 30));
4056
4057   base::RunLoop().RunUntilIdle();
4058   EXPECT_TRUE(seek_cb_was_called);
4059
4060   // Read some audio & video buffers to further verify seek completion.
4061   CheckExpectedBuffers(audio_stream, "120K 140K");
4062   CheckExpectedBuffers(video_stream, "120K 150");
4063
4064   // Append text cues that start after the seek point and verify that
4065   // they are returned by Read() calls.
4066   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "220K 240K 260K 280K", 20),
4067                      MuxedStreamInfo(kVideoTrackNum, "240K 270 300 330", 30));
4068
4069   base::RunLoop().RunUntilIdle();
4070
4071   // Verify that audio & video streams continue to return expected values.
4072   CheckExpectedBuffers(audio_stream, "160K 180K");
4073   CheckExpectedBuffers(video_stream, "180 210");
4074 }
4075
4076 TEST_F(ChunkDemuxerTest, ClusterWithUnknownSize) {
4077   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4078
4079   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 0, 4, true)));
4080   CheckExpectedRanges("{ [0,46) }");
4081
4082   // A new cluster indicates end of the previous cluster with unknown size.
4083   ASSERT_TRUE(AppendCluster(GenerateCluster(46, 66, 5, true)));
4084   CheckExpectedRanges("{ [0,115) }");
4085 }
4086
4087 TEST_F(ChunkDemuxerTest, CuesBetweenClustersWithUnknownSize) {
4088   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4089
4090   // Add two clusters separated by Cues in a single Append() call.
4091   std::unique_ptr<Cluster> cluster = GenerateCluster(0, 0, 4, true);
4092   std::vector<uint8_t> data(cluster->data(), cluster->data() + cluster->size());
4093   data.insert(data.end(), kCuesHeader, kCuesHeader + sizeof(kCuesHeader));
4094   cluster = GenerateCluster(46, 66, 5, true);
4095   data.insert(data.end(), cluster->data(), cluster->data() + cluster->size());
4096   ASSERT_TRUE(AppendData(&*data.begin(), data.size()));
4097
4098   CheckExpectedRanges("{ [0,115) }");
4099 }
4100
4101 TEST_F(ChunkDemuxerTest, CuesBetweenClusters) {
4102   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4103
4104   ASSERT_TRUE(AppendCluster(GenerateCluster(0, 0, 4)));
4105   ASSERT_TRUE(AppendData(kCuesHeader, sizeof(kCuesHeader)));
4106   ASSERT_TRUE(AppendCluster(GenerateCluster(46, 66, 5)));
4107   CheckExpectedRanges("{ [0,115) }");
4108 }
4109
4110 TEST_F(ChunkDemuxerTest, EvictCodedFramesTest) {
4111   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4112   demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, 10 * block_size_);
4113   demuxer_->SetMemoryLimitsForTest(DemuxerStream::VIDEO, 15 * block_size_);
4114   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
4115   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4116
4117   const char* kAudioStreamInfo = "0K 40K 80K 120K 160K 200K 240K 280K";
4118   const char* kVideoStreamInfo = "0K 10 20K 30 40K 50 60K 70 80K 90 100K "
4119       "110 120K 130 140K";
4120   // Append 8 blocks (80 bytes) of data to audio stream and 15 blocks (150
4121   // bytes) to video stream.
4122   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, kAudioStreamInfo, 40),
4123                      MuxedStreamInfo(kVideoTrackNum, kVideoStreamInfo, 10));
4124   CheckExpectedBuffers(audio_stream, kAudioStreamInfo);
4125   CheckExpectedBuffers(video_stream, kVideoStreamInfo);
4126
4127   // If we want to append 80 more blocks of muxed a+v data and the current
4128   // position is 0, that will fail, because EvictCodedFrames won't remove the
4129   // data after the current playback position.
4130   ASSERT_FALSE(
4131       demuxer_->EvictCodedFrames(kSourceId, base::Milliseconds(0), 80));
4132   // EvictCodedFrames has failed, so data should be unchanged.
4133   Seek(base::Milliseconds(0));
4134   CheckExpectedBuffers(audio_stream, kAudioStreamInfo);
4135   CheckExpectedBuffers(video_stream, kVideoStreamInfo);
4136
4137   // But if we pretend that playback position has moved to 120ms, that allows
4138   // EvictCodedFrames to garbage-collect enough data to succeed.
4139   ASSERT_TRUE(
4140       demuxer_->EvictCodedFrames(kSourceId, base::Milliseconds(120), 80));
4141
4142   Seek(base::Milliseconds(0));
4143   // Audio stream had 8 buffers, video stream had 15. We told EvictCodedFrames
4144   // that the new data size is 8 blocks muxed, i.e. 80 bytes. Given the current
4145   // ratio of video to the total data size (15 : (8+15) ~= 0.65) the estimated
4146   // sizes of video and audio data in the new 80 byte chunk are 52 bytes for
4147   // video (80*0.65 = 52) and 28 bytes for audio (80 - 52).
4148   // Given these numbers MSE GC will remove just one audio block (since current
4149   // audio size is 80 bytes, new data is 28 bytes, we need to remove just one 10
4150   // byte block to stay under 100 bytes memory limit after append
4151   // 80 - 10 + 28 = 98).
4152   // For video stream 150 + 52 = 202. Video limit is 150 bytes. We need to
4153   // remove at least 6 blocks to stay under limit.
4154   CheckExpectedBuffers(audio_stream, "40K 80K 120K 160K 200K 240K 280K");
4155   CheckExpectedBuffers(video_stream, "60K 70 80K 90 100K 110 120K 130 140K");
4156 }
4157
4158 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioOnly) {
4159   ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
4160   EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4161   ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4162 }
4163
4164 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_VideoOnly) {
4165   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4166   EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4167   ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4168 }
4169
4170 TEST_F(ChunkDemuxerTest, SegmentMissingAudioFrame_AudioVideo) {
4171   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4172   EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4173   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 0, 10);
4174 }
4175
4176 TEST_F(ChunkDemuxerTest, SegmentMissingVideoFrame_AudioVideo) {
4177   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4178   EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4179   AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
4180 }
4181
4182 TEST_F(ChunkDemuxerTest, SegmentMissingAudioVideoFrames) {
4183   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4184   EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4185   EXPECT_MEDIA_LOG(SegmentMissingFrames("2"));
4186   ASSERT_TRUE(AppendCluster(GenerateEmptyCluster(0)));
4187 }
4188
4189 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_FirstSegmentMissingKeyframe) {
4190   // Append V:[n n n][n n K]
4191   // Expect V:           [K]
4192   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4193   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4194
4195   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(2);
4196   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0 10 20");
4197   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "30 40 50K");
4198   CheckExpectedRanges("{ [50,60) }");
4199   CheckExpectedBuffers(video_stream, "50K");
4200 }
4201
4202 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_SecondSegmentMissingKeyframe) {
4203   // Append V:[K n n][n n n]
4204   // Expect V:[K n n][n n n]
4205   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4206   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4207
4208   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(2);
4209   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 10 20");
4210   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "30 40 50");
4211   CheckExpectedRanges("{ [0,60) }");
4212   CheckExpectedBuffers(video_stream, "0K 10 20 30 40 50");
4213 }
4214
4215 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_1) {
4216   // Append V:[K n n]
4217   // Remove    *****
4218   // Append V:       [n n n][n K n]
4219   // Expect:                  [K n]
4220   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4221   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4222
4223   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(3);
4224   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 10 20");
4225   demuxer_->Remove(kSourceId, base::TimeDelta(), base::Milliseconds(30));
4226   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "30 40 50");
4227   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "60 70K 80");
4228   CheckExpectedRanges("{ [70,90) }");
4229   CheckExpectedBuffers(video_stream, "70K 80");
4230 }
4231
4232 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_2) {
4233   // Append V:[K n n][n n n][n K n]
4234   // Remove    *
4235   // Expect:                  [K n]
4236   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4237   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4238
4239   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(3);
4240   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 10 20");
4241   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "30 40 50");
4242   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "60 70K 80");
4243   demuxer_->Remove(kSourceId, base::TimeDelta(), base::Milliseconds(10));
4244   CheckExpectedRanges("{ [70,90) }");
4245   CheckExpectedBuffers(video_stream, "70K 80");
4246 }
4247
4248 TEST_F(ChunkDemuxerTest, RelaxedKeyframe_RemoveInterruptsCodedFrameGroup_3) {
4249   // Append V:[K n n][n n n][n K n]
4250   // Remove               *
4251   // Expect:  [K n n..n n]    [K n]
4252   ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
4253   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4254
4255   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(10)).Times(3);
4256   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 10 20");
4257   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "30 40 50");
4258   AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "60 70K 80");
4259   demuxer_->Remove(kSourceId, base::Milliseconds(50), base::Milliseconds(60));
4260   CheckExpectedRanges("{ [0,50) [70,90) }");
4261   CheckExpectedBuffers(video_stream, "0K 10 20 30 40");
4262   Seek(base::Milliseconds(70));
4263   CheckExpectedBuffers(video_stream, "70K 80");
4264 }
4265
4266 TEST_F(ChunkDemuxerTest,
4267        RelaxedKeyframe_RemoveInterruptsMuxedCodedFrameGroup_1) {
4268   // Append muxed:
4269   //        A:[K K K]
4270   //        V:[K n n]
4271   // Remove    *****
4272   // Append muxed:
4273   //        A:       [K K K][K K K]
4274   //        V:       [n n n][n K n]
4275   // Expect:
4276   //        A:       [K K K][K K K]
4277   //        V                 [K n]
4278   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4279   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
4280   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4281
4282   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 10K 20D10K"),
4283                      MuxedStreamInfo(kVideoTrackNum, "0K 10 20", 10));
4284   demuxer_->Remove(kSourceId, base::TimeDelta(), base::Milliseconds(30));
4285   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "30K 40K 50D10K"),
4286                      MuxedStreamInfo(kVideoTrackNum, "30 40 50", 10));
4287   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "60K 70K 80D10K"),
4288                      MuxedStreamInfo(kVideoTrackNum, "60 70K 80", 10));
4289   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }");
4290   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [70,90) }");
4291   CheckExpectedRanges("{ [70,90) }");
4292   CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K");
4293   CheckExpectedBuffers(video_stream, "70K 80");
4294 }
4295
4296 TEST_F(ChunkDemuxerTest,
4297        RelaxedKeyframe_RemoveInterruptsMuxedCodedFrameGroup_2) {
4298   // Append muxed:
4299   //        A:[K K K]
4300   //        V:(Nothing, simulating jagged cluster start or a long previous
4301   //          video frame)
4302   // Remove    *****
4303   // Append muxed:
4304   //        A:       [K K K][K K K]
4305   //        V:       [n n n][n K n]
4306   // Expect:
4307   //        A:       [K K K][K K K]
4308   //        V [................K n] (As would occur if there really were a
4309   //        jagged cluster start and not badly muxed clusters as used to
4310   //        simulate a jagged start in this test.)
4311   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4312   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
4313   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4314
4315   EXPECT_MEDIA_LOG(SegmentMissingFrames("1"));
4316   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0K 10K 20D10K"),
4317                      MuxedStreamInfo(kVideoTrackNum, ""));
4318   demuxer_->Remove(kSourceId, base::TimeDelta(), base::Milliseconds(30));
4319   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "30K 40K 50D10K"),
4320                      MuxedStreamInfo(kVideoTrackNum, "30 40 50", 10));
4321   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "60K 70K 80D10K"),
4322                      MuxedStreamInfo(kVideoTrackNum, "60 70K 80", 10));
4323   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }");
4324   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,90) }");
4325   CheckExpectedRanges("{ [30,90) }");
4326   CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K");
4327   CheckExpectedBuffers(video_stream, "70K 80");
4328 }
4329
4330 TEST_F(ChunkDemuxerTest,
4331        RelaxedKeyframe_RemoveInterruptsMuxedCodedFrameGroup_3) {
4332   // Append muxed:
4333   //        A:[K K K
4334   //        V:(Nothing yet. This is a jagged start, not simulated.)
4335   // Remove    *****
4336   // Append muxed:
4337   //        A:       K K K K K K]
4338   //        V:       n n n n K n]
4339   // Expect:
4340   //        A:      [K K K K K K]
4341   //        V [..............K n]
4342   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4343   DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
4344   DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
4345
4346   std::vector<MuxedStreamInfo> msi(2);
4347   msi[0] =
4348       MuxedStreamInfo(kAudioTrackNum, "0K 10K 20K 30K 40K 50K 60K 70K 80D10K");
4349   msi[1] = MuxedStreamInfo(kVideoTrackNum, "31 41 51 61 71K 81", 10);
4350   std::unique_ptr<Cluster> cluster = GenerateMuxedCluster(msi);
4351
4352   // Append the first part of the cluster, up to the beginning of the first
4353   // video simpleblock. The result should be just 4 audio blocks and no video
4354   // blocks are appended. Since the stream parser does not yet have a duration
4355   // for the 4th audio block in this partial cluster append, it is not yet
4356   // emitted from the parser, and only the first 3 audio blocks are expected to
4357   // be buffered by and available from the demuxer.
4358   ASSERT_EQ(kVideoTrackNum, 1);
4359   int video_start = 0;
4360   bool found = false;
4361   while (video_start < cluster->size() - 10) {
4362     if (cluster->data()[video_start] == 0xA3 &&
4363         cluster->data()[video_start + 9] == 0x81) {
4364       found = true;
4365       break;
4366     }
4367     video_start++;
4368   }
4369
4370   ASSERT_TRUE(found);
4371   ASSERT_GT(video_start, 0);
4372   ASSERT_LT(video_start, cluster->size() - 3);
4373
4374   ASSERT_TRUE(AppendData(kSourceId, cluster->data(), video_start));
4375   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,30) }");
4376   CheckExpectedRanges(DemuxerStream::VIDEO, "{ }");
4377
4378   demuxer_->Remove(kSourceId, base::TimeDelta(), base::Milliseconds(30));
4379
4380   // Append the remainder of the cluster
4381   ASSERT_TRUE(AppendData(kSourceId, cluster->data() + video_start,
4382                          cluster->size() - video_start));
4383
4384   CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }");
4385   CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,91) }");
4386   CheckExpectedRanges("{ [30,90) }");
4387   CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K");
4388   CheckExpectedBuffers(video_stream, "71K 81");
4389 }
4390
4391 namespace {
4392 void QuitLoop(base::OnceClosure quit_closure,
4393               DemuxerStream::Type type,
4394               const std::vector<DemuxerStream*>& streams) {
4395   std::move(quit_closure).Run();
4396 }
4397
4398 void DisableAndEnableDemuxerTracks(
4399     ChunkDemuxer* demuxer,
4400     base::test::TaskEnvironment* task_environment) {
4401   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
4402                             base::WaitableEvent::InitialState::NOT_SIGNALED);
4403   std::vector<MediaTrack::Id> audio_tracks;
4404   std::vector<MediaTrack::Id> video_tracks;
4405
4406   base::RunLoop disable_video;
4407   demuxer->OnSelectedVideoTrackChanged(
4408       video_tracks, base::TimeDelta(),
4409       base::BindOnce(QuitLoop, disable_video.QuitClosure()));
4410   disable_video.Run();
4411
4412   base::RunLoop disable_audio;
4413   demuxer->OnEnabledAudioTracksChanged(
4414       audio_tracks, base::TimeDelta(),
4415       base::BindOnce(QuitLoop, disable_audio.QuitClosure()));
4416   disable_audio.Run();
4417
4418   base::RunLoop enable_video;
4419   video_tracks.push_back(MediaTrack::Id("1"));
4420   demuxer->OnSelectedVideoTrackChanged(
4421       video_tracks, base::TimeDelta(),
4422       base::BindOnce(QuitLoop, enable_video.QuitClosure()));
4423   enable_video.Run();
4424
4425   base::RunLoop enable_audio;
4426   audio_tracks.push_back(MediaTrack::Id("2"));
4427   demuxer->OnEnabledAudioTracksChanged(
4428       audio_tracks, base::TimeDelta(),
4429       base::BindOnce(QuitLoop, enable_audio.QuitClosure()));
4430   enable_audio.Run();
4431
4432   task_environment->RunUntilIdle();
4433 }
4434 }  // namespace
4435
4436 TEST_F(ChunkDemuxerTest, StreamStatusNotifications) {
4437   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4438   ChunkDemuxerStream* audio_stream =
4439       static_cast<ChunkDemuxerStream*>(GetStream(DemuxerStream::AUDIO));
4440   EXPECT_NE(nullptr, audio_stream);
4441   ChunkDemuxerStream* video_stream =
4442       static_cast<ChunkDemuxerStream*>(GetStream(DemuxerStream::VIDEO));
4443   EXPECT_NE(nullptr, video_stream);
4444
4445   // Verify stream status changes without pending read.
4446   DisableAndEnableDemuxerTracks(demuxer_.get(), &task_environment_);
4447
4448   // Verify stream status changes with pending read.
4449   bool read_done = false;
4450   audio_stream->Read(base::BindOnce(&OnReadDone_EOSExpected, &read_done));
4451   DisableAndEnableDemuxerTracks(demuxer_.get(), &task_environment_);
4452   EXPECT_TRUE(read_done);
4453   read_done = false;
4454   video_stream->Read(base::BindOnce(&OnReadDone_EOSExpected, &read_done));
4455   DisableAndEnableDemuxerTracks(demuxer_.get(), &task_environment_);
4456   EXPECT_TRUE(read_done);
4457 }
4458
4459 TEST_F(ChunkDemuxerTest, MultipleIds) {
4460   CreateNewDemuxer();
4461   EXPECT_CALL(*this, DemuxerOpened());
4462   EXPECT_CALL(host_, SetDuration(_)).Times(2);
4463   demuxer_->Initialize(&host_,
4464                        CreateInitDoneCallback(kNoTimestamp, PIPELINE_OK));
4465
4466   const char* kId1 = "id1";
4467   const char* kId2 = "id2";
4468   EXPECT_EQ(AddId(kId1, "video/webm", "opus,vp9"), ChunkDemuxer::kOk);
4469   EXPECT_EQ(AddId(kId2, "video/webm", "opus,vp9"), ChunkDemuxer::kOk);
4470   scoped_refptr<DecoderBuffer> data1 = ReadTestDataFile("green-a300hz.webm");
4471   scoped_refptr<DecoderBuffer> data2 = ReadTestDataFile("red-a500hz.webm");
4472
4473   EXPECT_FOUND_CODEC_NAME(Video, "vp9").Times(2);
4474   EXPECT_FOUND_CODEC_NAME(Audio, "opus").Times(2);
4475   EXPECT_CALL(*this, InitSegmentReceivedMock(_)).Times(2);
4476   EXPECT_MEDIA_LOG(SegmentMissingFrames("1")).Times(1);
4477
4478   EXPECT_TRUE(AppendData(kId1, data1->data(), data1->data_size()));
4479   EXPECT_TRUE(AppendData(kId2, data2->data(), data2->data_size()));
4480   CheckExpectedRanges(kId1, "{ [0,12007) }");
4481   CheckExpectedRanges(kId2, "{ [0,10007) }");
4482 }
4483
4484 TEST_F(ChunkDemuxerTest, CompleteInitAfterIdRemoved) {
4485   CreateNewDemuxer();
4486   EXPECT_CALL(*this, DemuxerOpened());
4487   demuxer_->Initialize(&host_,
4488                        CreateInitDoneCallback(kDefaultDuration(), PIPELINE_OK));
4489
4490   // Add two ids, then remove one of the ids and verify that adding init segment
4491   // only for the remaining id still triggers the InitDoneCB.
4492   const char* kId1 = "id1";
4493   const char* kId2 = "id2";
4494   EXPECT_EQ(AddId(kId1, "video/webm", "vp8"), ChunkDemuxer::kOk);
4495   EXPECT_EQ(AddId(kId2, "video/webm", "vp9"), ChunkDemuxer::kOk);
4496   demuxer_->RemoveId(kId2);
4497
4498   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
4499   EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(30));
4500   EXPECT_FOUND_CODEC_NAME(Video, "vp8");
4501
4502   ASSERT_TRUE(AppendInitSegmentWithSourceId(kId1, HAS_VIDEO));
4503   AppendSingleStreamCluster(kId1, kVideoTrackNum, "0K 30 60 90");
4504 }
4505
4506 TEST_F(ChunkDemuxerTest, RemovingIdMustRemoveStreams) {
4507   CreateNewDemuxer();
4508   EXPECT_CALL(*this, DemuxerOpened());
4509   demuxer_->Initialize(&host_,
4510                        CreateInitDoneCallback(kDefaultDuration(), PIPELINE_OK));
4511
4512   const char* kId1 = "id1";
4513   EXPECT_EQ(AddId(kId1, "video/webm", "vorbis,vp8"), ChunkDemuxer::kOk);
4514
4515   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
4516   EXPECT_FOUND_CODEC_NAME(Video, "vp8");
4517   EXPECT_FOUND_CODEC_NAME(Audio, "vorbis");
4518
4519   // Append init segment to ensure demuxer streams get created.
4520   ASSERT_TRUE(AppendInitSegmentWithSourceId(kId1, HAS_AUDIO | HAS_VIDEO));
4521   EXPECT_NE(nullptr, GetStream(DemuxerStream::AUDIO));
4522   EXPECT_NE(nullptr, GetStream(DemuxerStream::VIDEO));
4523
4524   // Removing the id should remove also the DemuxerStreams.
4525   demuxer_->RemoveId(kId1);
4526   EXPECT_EQ(nullptr, GetStream(DemuxerStream::AUDIO));
4527   EXPECT_EQ(nullptr, GetStream(DemuxerStream::VIDEO));
4528 }
4529
4530 TEST_F(ChunkDemuxerTest, SequenceModeMuxedAppendShouldWarn) {
4531   ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
4532
4533   demuxer_->SetSequenceMode(kSourceId, true);
4534   EXPECT_CALL(*this,
4535               OnParseWarningMock(SourceBufferParseWarning::kMuxedSequenceMode));
4536   EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
4537
4538   AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "0D10K"),
4539                      MuxedStreamInfo(kVideoTrackNum, "0D10K"));
4540 }
4541
4542 TEST_F(ChunkDemuxerTest, SequenceModeSingleTrackNoWarning) {
4543   std::string audio_id = "audio1";
4544   std::string video_id = "video1";
4545
4546   EXPECT_CALL(*this,
4547               OnParseWarningMock(SourceBufferParseWarning::kMuxedSequenceMode))
4548       .Times(0);
4549   EXPECT_MEDIA_LOG(MuxedSequenceModeWarning()).Times(0);
4550
4551   ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
4552
4553   demuxer_->SetSequenceMode(audio_id, true);
4554   demuxer_->SetSequenceMode(video_id, true);
4555
4556   // Append audio and video data into separate source ids.
4557   ASSERT_TRUE(AppendCluster(
4558       audio_id, GenerateSingleStreamCluster(0, 23, kAudioTrackNum, 23)));
4559   ASSERT_TRUE(AppendCluster(
4560       video_id, GenerateSingleStreamCluster(0, 33, kVideoTrackNum, 33)));
4561 }
4562
4563 TEST_F(ChunkDemuxerTest, Mp4Vp9CodecSupport) {
4564   demuxer_->Initialize(&host_,
4565                        base::BindOnce(&ChunkDemuxerTest::DemuxerInitialized,
4566                                       base::Unretained(this)));
4567   ChunkDemuxer::Status expected = ChunkDemuxer::kOk;
4568   EXPECT_EQ(AddId("source_id", "video/mp4", "vp09.00.10.08"), expected);
4569 }
4570
4571 TEST_F(ChunkDemuxerTest, UnmarkEOSRetainsParseErrorState_BeforeInit) {
4572   InSequence s;
4573   // Trigger a (fatal) parse error prior to successfully reaching source init.
4574   EXPECT_CALL(*this, DemuxerOpened());
4575   EXPECT_MEDIA_LOG(StreamParsingFailed());
4576   demuxer_->Initialize(
4577       &host_,
4578       CreateInitDoneCallback(kNoTimestamp, CHUNK_DEMUXER_ERROR_APPEND_FAILED));
4579
4580   ASSERT_EQ(AddId(kSourceId, HAS_AUDIO | HAS_VIDEO), ChunkDemuxer::kOk);
4581   AppendGarbage();
4582
4583   // Simulate SourceBuffer Append Error algorithm.
4584   demuxer_->ResetParserState(kSourceId, append_window_start_for_next_append_,
4585                              append_window_end_for_next_append_,
4586                              &timestamp_offset_map_[kSourceId]);
4587   demuxer_->MarkEndOfStream(CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR);
4588
4589   // UnmarkEndOfStream and verify that attempted append of an initialization
4590   // segment still fails.
4591   demuxer_->UnmarkEndOfStream();
4592   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
4593 }
4594
4595 TEST_F(ChunkDemuxerTest, UnmarkEOSRetainsParseErrorState_AfterInit) {
4596   InSequence s;
4597   // Trigger a (fatal) parse error after successfully reaching source init.
4598   InitDemuxer(HAS_AUDIO | HAS_VIDEO);
4599   EXPECT_MEDIA_LOG(StreamParsingFailed());
4600   EXPECT_CALL(host_,
4601               OnDemuxerError(HasStatusCode(CHUNK_DEMUXER_ERROR_APPEND_FAILED)));
4602   AppendGarbage();
4603
4604   // Simulate SourceBuffer Append Error algorithm.
4605   demuxer_->ResetParserState(kSourceId, append_window_start_for_next_append_,
4606                              append_window_end_for_next_append_,
4607                              &timestamp_offset_map_[kSourceId]);
4608   demuxer_->MarkEndOfStream(CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR);
4609
4610   // UnmarkEndOfStream and verify that attempted append of another
4611   // initialization segment still fails.
4612   demuxer_->UnmarkEndOfStream();
4613   ASSERT_FALSE(AppendInitSegment(HAS_AUDIO | HAS_VIDEO));
4614 }
4615
4616 struct ZeroLengthFrameCase {
4617   DemuxerStream::Type stream_type;
4618   int flags;
4619   int track_number;
4620 };
4621
4622 // Test that 0-length audio and video coded frames are dropped gracefully.
4623 TEST_F(ChunkDemuxerTest, ZeroLengthFramesDropped) {
4624   struct ZeroLengthFrameCase cases[] = {
4625       {DemuxerStream::AUDIO, HAS_AUDIO, kAudioTrackNum},
4626       {DemuxerStream::VIDEO, HAS_VIDEO, kVideoTrackNum}};
4627
4628   for (const auto& c : cases) {
4629     InSequence s;
4630
4631     CreateNewDemuxer();
4632     ASSERT_TRUE(InitDemuxer(c.flags));
4633     DemuxerStream* stream = GetStream(c.stream_type);
4634
4635     // Append a cluster containing nonzero-sized frames. Use end of stream to
4636     // ensure we read back precisely the expected buffers.
4637     ASSERT_GT(block_size_, 0U);
4638     AppendSingleStreamCluster(kSourceId, c.track_number, "0K 10K 20K 30D10K");
4639     EXPECT_CALL(host_, SetDuration(base::Milliseconds(40)));
4640     MarkEndOfStream(PIPELINE_OK);
4641     CheckExpectedRanges("{ [0,40) }");
4642     CheckExpectedBuffers(stream, "0K 10K 20K 30K");
4643     ExpectEndOfStream(c.stream_type);
4644
4645     // Append a cluster containing a 0-sized frame. Verify there is nothing new
4646     // buffered.
4647     demuxer_->UnmarkEndOfStream();
4648     EXPECT_MEDIA_LOG(DiscardingEmptyFrame(40000, 40000));
4649     block_size_ = 0;
4650     AppendSingleStreamCluster(kSourceId, c.track_number, "40D10K");
4651     MarkEndOfStream(PIPELINE_OK);
4652     Seek(base::Milliseconds(0));
4653     CheckExpectedRanges("{ [0,40) }");
4654     CheckExpectedBuffers(stream, "0K 10K 20K 30K");
4655     ExpectEndOfStream(c.stream_type);
4656
4657     // Append a cluster containing a nonzero-sized frame. Verify it is buffered.
4658     demuxer_->UnmarkEndOfStream();
4659     EXPECT_CALL(host_, SetDuration(base::Milliseconds(50)));
4660     block_size_ = kBlockSize;
4661     AppendSingleStreamCluster(kSourceId, c.track_number, "40D10K");
4662     MarkEndOfStream(PIPELINE_OK);
4663     Seek(base::Milliseconds(0));
4664     CheckExpectedRanges("{ [0,50) }");
4665     CheckExpectedBuffers(stream, "0K 10K 20K 30K 40K");
4666     ExpectEndOfStream(c.stream_type);
4667   }
4668 }
4669
4670 // TODO(servolk): Add a unit test with multiple audio/video tracks using the
4671 // same codec type in a single SourceBufferState, when WebM parser supports
4672 // multiple tracks. crbug.com/646900
4673
4674 }  // namespace media