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