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