15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <algorithm>
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/string_number_conversions.h"
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/string_split.h"
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/string_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_decoder_config.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/decoder_buffer.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/decrypt_config.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/mock_demuxer_host.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/test_data_util.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/test_helpers.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/chunk_demuxer.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/webm/cluster_builder.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/webm/webm_constants.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/webm/webm_crypto_helpers.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AnyNumber;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Exactly;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::InSequence;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::NotNull;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SaveArg;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SetArgumentPointee;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const uint8 kTracksHeader[] = {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x16, 0x54, 0xAE, 0x6B,  // Tracks ID
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // tracks(size = 0)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebM Block bytes that represent a VP8 keyframe.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const uint8 kVP8Keyframe[] = {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  0x010, 0x00, 0x00, 0x9d, 0x01, 0x2a, 0x00, 0x10, 0x00, 0x10, 0x00
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebM Block bytes that represent a VP8 interframe.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const uint8 kVP8Interframe[] = { 0x11, 0x00, 0x00 };
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kTracksHeaderSize = sizeof(kTracksHeader);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kTracksSizeOffset = 4;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The size of TrackEntry element in test file "webm_vorbis_track_entry" starts
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at index 1 and spans 8 bytes.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAudioTrackSizeOffset = 1;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAudioTrackSizeWidth = 8;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAudioTrackEntryHeaderSize = kAudioTrackSizeOffset +
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              kAudioTrackSizeWidth;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The size of TrackEntry element in test file "webm_vp8_track_entry" starts at
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// index 1 and spans 8 bytes.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kVideoTrackSizeOffset = 1;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kVideoTrackSizeWidth = 8;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset +
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              kVideoTrackSizeWidth;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kVideoTrackNum = 1;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAudioTrackNum = 2;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAudioBlockDuration = 23;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kVideoBlockDuration = 33;
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kBlockSize = 10;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kSourceId[] = "SourceId";
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kDefaultFirstClusterRange[] = "{ [0,46) }";
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultFirstClusterEndTimestamp = 66;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultSecondClusterEndTimestamp = 132;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta kDefaultDuration() {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::TimeDelta::FromMilliseconds(201224);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Write an integer into buffer in the form of vint that spans 8 bytes.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The data pointed by |buffer| should be at least 8 bytes long.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void WriteInt64(uint8* buffer, int64 number) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(number >= 0 && number < GG_LONGLONG(0x00FFFFFFFFFFFFFF));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer[0] = 0x01;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 tmp = number;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 7; i > 0; i--) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer[i] = tmp & 0xff;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tmp >>= 8;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MATCHER_P(HasTimestamp, timestamp_in_ms, "") {
95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return arg.get() && !arg->end_of_stream() &&
96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch         arg->timestamp().InMilliseconds() == timestamp_in_ms;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochMATCHER(IsEndOfStream, "") { return arg.get() && arg->end_of_stream(); }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnReadDone(const base::TimeDelta& expected_time,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bool* called,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       DemuxerStream::Status status,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const scoped_refptr<DecoderBuffer>& buffer) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kOk);
106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(expected_time, buffer->timestamp());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *called = true;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnReadDone_AbortExpected(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* called, DemuxerStream::Status status,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<DecoderBuffer>& buffer) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kAborted);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, buffer.get());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *called = true;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnReadDone_EOSExpected(bool* called,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   DemuxerStream::Status status,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const scoped_refptr<DecoderBuffer>& buffer) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kOk);
122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(buffer->end_of_stream());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *called = true;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static void OnSeekDone_OKExpected(bool* called, PipelineStatus status) {
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(status, PIPELINE_OK);
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  *called = true;
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChunkDemuxerTest : public testing::Test {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum CodecsIndex {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUDIO,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VIDEO,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MAX_CODECS_INDEX
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default cluster to append first for simple tests.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> kDefaultFirstCluster() {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GenerateCluster(0, 4);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default cluster to append after kDefaultFirstCluster()
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has been appended. This cluster starts with blocks that
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have timestamps consistent with the end times of the blocks
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in kDefaultFirstCluster() so that these two clusters represent
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a continuous region.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> kDefaultSecondCluster() {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GenerateCluster(46, 66, 5);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChunkDemuxerTest() {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateNewDemuxer();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateNewDemuxer() {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Closure open_cb =
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this));
160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    Demuxer::NeedKeyCB need_key_cb =
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this));
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    demuxer_.reset(new ChunkDemuxer(open_cb, need_key_cb, LogCB()));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ChunkDemuxerTest() {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShutdownDemuxer();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void CreateInitSegment(bool has_audio, bool has_video, bool has_text,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool is_audio_encrypted, bool is_video_encrypted,
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         scoped_ptr<uint8[]>* buffer,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int* size) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> ebml_header;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> info;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> audio_track_entry;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> video_track_entry;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> audio_content_encodings;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> video_content_encodings;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<DecoderBuffer> text_track_entry;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ebml_header = ReadTestDataFile("webm_ebml_element");
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info = ReadTestDataFile("webm_info_element");
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tracks_element_size = 0;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry");
189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      tracks_element_size += audio_track_entry->data_size();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_audio_encrypted) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_content_encodings = ReadTestDataFile("webm_content_encodings");
192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        tracks_element_size += audio_content_encodings->data_size();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_track_entry = ReadTestDataFile("webm_vp8_track_entry");
198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      tracks_element_size += video_track_entry->data_size();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_video_encrypted) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        video_content_encodings = ReadTestDataFile("webm_content_encodings");
201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        tracks_element_size += video_content_encodings->data_size();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_text) {
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // TODO(matthewjheaney): create an abstraction to do
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // this (http://crbug/321454).
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // We need it to also handle the creation of multiple text tracks.
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // This is the track entry for a text track,
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // TrackEntry [AE], size=30
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //   TrackNum [D7], size=1, val=3
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //   TrackUID [73] [C5], size=1, value=3
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //   TrackType [83], size=1, val=0x11
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //   CodecId [86], size=18, val="D_WEBVTT/SUBTITLES"
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const char str[] = "\xAE\x9E\xD7\x81\x03\x73\xC5\x81\x03"
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         "\x83\x81\x11\x86\x92"
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         "D_WEBVTT/SUBTITLES";
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const int len = strlen(str);
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK_EQ(len, 32);
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const uint8* const buf = reinterpret_cast<const uint8*>(str);
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      text_track_entry = DecoderBuffer::CopyFrom(buf, len);
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      tracks_element_size += text_track_entry->data_size();
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *size = ebml_header->data_size() + info->data_size() +
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kTracksHeaderSize + tracks_element_size;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer->reset(new uint8[*size]);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* buf = buffer->get();
232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    memcpy(buf, ebml_header->data(), ebml_header->data_size());
233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    buf += ebml_header->data_size();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    memcpy(buf, info->data(), info->data_size());
236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    buf += info->data_size();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(buf, kTracksHeader, kTracksHeaderSize);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteInt64(buf + kTracksSizeOffset, tracks_element_size);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf += kTracksHeaderSize;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(xhwang): Simplify this! Probably have test data files that contain
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ContentEncodings directly instead of trying to create one at run-time.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      memcpy(buf, audio_track_entry->data(),
246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch             audio_track_entry->data_size());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_audio_encrypted) {
248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        memcpy(buf + audio_track_entry->data_size(),
249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               audio_content_encodings->data(),
250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               audio_content_encodings->data_size());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WriteInt64(buf + kAudioTrackSizeOffset,
252ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   audio_track_entry->data_size() +
253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   audio_content_encodings->data_size() -
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   kAudioTrackEntryHeaderSize);
255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        buf += audio_content_encodings->data_size();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      buf += audio_track_entry->data_size();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      memcpy(buf, video_track_entry->data(),
262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch             video_track_entry->data_size());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_video_encrypted) {
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        memcpy(buf + video_track_entry->data_size(),
265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               video_content_encodings->data(),
266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               video_content_encodings->data_size());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WriteInt64(buf + kVideoTrackSizeOffset,
268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   video_track_entry->data_size() +
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   video_content_encodings->data_size() -
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   kVideoTrackEntryHeaderSize);
271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        buf += video_content_encodings->data_size();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      buf += video_track_entry->data_size();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_text) {
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      memcpy(buf, text_track_entry->data(),
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             text_track_entry->data_size());
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      buf += text_track_entry->data_size();
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChunkDemuxer::Status AddId() {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return AddId(kSourceId, true, true);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChunkDemuxer::Status AddId(const std::string& source_id,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool has_audio, bool has_video) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> codecs;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string type;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      codecs.push_back("vorbis");
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = "audio/webm";
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      codecs.push_back("vp8");
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = "video/webm";
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!has_audio && !has_video) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return AddId(kSourceId, true, true);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return demuxer_->AddId(source_id, type, codecs);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendData(const uint8* data, size_t length) {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(kSourceId, data, length);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void AppendCluster(const std::string& source_id,
314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                     scoped_ptr<Cluster> cluster) {
315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendData(source_id, cluster->data(), cluster->size());
316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void AppendCluster(scoped_ptr<Cluster> cluster) {
319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(kSourceId, cluster.Pass());
320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendCluster(int timecode, int block_count) {
323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(GenerateCluster(timecode, block_count));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void AppendSingleStreamCluster(const std::string& source_id, int track_number,
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 int timecode, int block_count) {
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int block_duration = 0;
329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    switch(track_number) {
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      case kVideoTrackNum:
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        block_duration = kVideoBlockDuration;
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        break;
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      case kAudioTrackNum:
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        block_duration = kAudioBlockDuration;
335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        break;
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_NE(block_duration, 0);
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int end_timecode = timecode + block_count * block_duration;
339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(source_id,
340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                  GenerateSingleStreamCluster(
341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      timecode, end_timecode, track_number, block_duration));
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
344558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void AppendSingleStreamCluster(const std::string& source_id, int track_number,
345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                 const std::string& cluster_description) {
346558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::vector<std::string> timestamps;
347558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    base::SplitString(cluster_description, ' ', &timestamps);
348558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
349558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ClusterBuilder cb;
350558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::vector<uint8> data(10);
351558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (size_t i = 0; i < timestamps.size(); ++i) {
352558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      std::string timestamp_str = timestamps[i];
353558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      int block_flags = 0;
354558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (EndsWith(timestamp_str, "K", true)) {
355558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        block_flags = kWebMFlagKeyframe;
356558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        // Remove the "K" off of the token.
357558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1);
358558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
359558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      int timestamp_in_ms;
360558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      CHECK(base::StringToInt(timestamp_str, &timestamp_in_ms));
361558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
362558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (i == 0)
363558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        cb.SetClusterTimecode(timestamp_in_ms);
364558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
365558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags,
366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                        &data[0], data.size());
367558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(source_id, cb.Finish());
369558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendData(const std::string& source_id,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const uint8* data, size_t length) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber());
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    demuxer_->AppendData(source_id, data, length);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendDataInPieces(const uint8* data, size_t length) {
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendDataInPieces(data, length, 7);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* start = data;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* end = data + length;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (start < end) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t append_size = std::min(piece_size,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    static_cast<size_t>(end - start));
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AppendData(start, append_size);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      start += append_size;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendInitSegment(bool has_audio, bool has_video) {
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AppendInitSegmentWithSourceId(kSourceId, has_audio, has_video, false);
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void AppendInitSegmentText(bool has_audio, bool has_video) {
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AppendInitSegmentWithSourceId(kSourceId, has_audio, has_video, true);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendInitSegmentWithSourceId(const std::string& source_id,
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     bool has_audio, bool has_video,
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     bool has_text) {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendInitSegmentWithEncryptedInfo(
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        source_id, has_audio, has_video, has_text, false, false);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendInitSegmentWithEncryptedInfo(const std::string& source_id,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bool has_audio, bool has_video,
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          bool has_text,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bool is_audio_encrypted,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bool is_video_encrypted) {
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> info_tracks;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int info_tracks_size = 0;
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CreateInitSegment(has_audio, has_video, has_text,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      is_audio_encrypted, is_video_encrypted,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &info_tracks, &info_tracks_size);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(source_id, info_tracks.get(), info_tracks_size);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendGarbage() {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fill up an array with gibberish.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int garbage_cluster_size = 10;
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> garbage_cluster(new uint8[garbage_cluster_size]);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < garbage_cluster_size; ++i)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      garbage_cluster[i] = i;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(garbage_cluster.get(), garbage_cluster_size);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitDoneCalled(PipelineStatus expected_status,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      PipelineStatus status) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(status, expected_status);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendEmptyCluster(int timecode) {
435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(GenerateEmptyCluster(timecode));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    PipelineStatus expected_status) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected_duration != kNoTimestamp())
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_CALL(host_, SetDuration(expected_duration));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CreateInitDoneCB(expected_status);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::Bind(&ChunkDemuxerTest::InitDoneCalled,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(this),
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      expected_status);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitDemuxer(bool has_audio, bool has_video) {
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return InitDemuxerWithEncryptionInfo(has_audio, has_video, false,
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                         false, false);
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool InitDemuxerText(bool has_audio, bool has_video) {
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return InitDemuxerWithEncryptionInfo(has_audio, has_video, true,
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                         false, false);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitDemuxerWithEncryptionInfo(
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool has_audio, bool has_video, bool has_text,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool is_audio_encrypted, bool is_video_encrypted) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PipelineStatus expected_status =
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta expected_duration = kNoTimestamp();
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected_status == PIPELINE_OK)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_duration = kDefaultDuration();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &host_, CreateInitDoneCB(expected_duration, expected_status), true);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendInitSegmentWithEncryptedInfo(
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        kSourceId, has_audio, has_video, has_text,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_audio_encrypted, is_video_encrypted);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool InitDemuxerAudioAndVideoSourcesText(const std::string& audio_id,
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                           const std::string& video_id,
486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                           bool has_text) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (AddId(audio_id, true, false) != ChunkDemuxer::kOk)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (AddId(video_id, false, true) != ChunkDemuxer::kOk)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AppendInitSegmentWithSourceId(audio_id, true, false, has_text);
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AppendInitSegmentWithSourceId(video_id, false, true, has_text);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool InitDemuxerAudioAndVideoSources(const std::string& audio_id,
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       const std::string& video_id) {
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false);
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the demuxer with data from 2 files with different
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // decoder configurations. This is used to test the decoder config change
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // logic.
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-320x240.webm VideoDecoderConfig returns 320x240 for its natural_size()
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm VideoDecoderConfig returns 640x360 for its natural_size()
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The resulting video stream returns data from each file for the following
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time ranges.
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-320x240.webm : [0-501)       [801-2737)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm :       [527-793)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size()
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size()
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The resulting audio stream returns data from each file for the following
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time ranges.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-320x240.webm : [0-524)       [779-2737)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm :       [527-759)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitDemuxerWithConfigChangeData() {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm");
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm");
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744),
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 PIPELINE_OK), true);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (AddId(kSourceId, true, true) != ChunkDemuxer::kOk)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append the whole bear1 file.
536ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear1->data(), bear1->data_size());
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckExpectedRanges(kSourceId, "{ [0,2737) }");
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append initialization segment for bear2.
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: Offsets here and below are derived from
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // media/test/data/bear-640x360-manifest.js and
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // media/test/data/bear-320x240-manifest.js which were
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // generated from media/test/data/bear-640x360.webm and
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // media/test/data/bear-320x240.webm respectively.
545ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear2->data(), 4340);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append a media segment that goes from [0.527000, 1.014000).
548ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear2->data() + 55290, 18785);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckExpectedRanges(kSourceId, "{ [0,1028) [1201,2737) }");
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append initialization segment for bear1 & fill gap with [779-1197)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // segment.
553ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear1->data(), 4370);
554ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear1->data() + 72737, 28183);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckExpectedRanges(kSourceId, "{ [0,2737) }");
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
557ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    MarkEndOfStream(PIPELINE_OK);
5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return true;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShutdownDemuxer() {
562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (demuxer_) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      demuxer_->Shutdown();
564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      message_loop_.RunUntilIdle();
565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 data[] = { 0x00 };
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GenerateCluster(timecode, timecode, block_count);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddVideoBlockGroup(ClusterBuilder* cb, int track_num, int64 timecode,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          int duration, int flags) {
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const uint8* data =
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (flags & kWebMFlagKeyframe) != 0 ? kVP8Keyframe : kVP8Interframe;
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int size = (flags & kWebMFlagKeyframe) != 0 ? sizeof(kVP8Keyframe) :
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        sizeof(kVP8Interframe);
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cb->AddBlockGroup(track_num, timecode, duration, flags, data, size);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode,
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int first_video_timecode,
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int block_count) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(block_count, 0);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size = 10;
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> data(new uint8[size]);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClusterBuilder cb;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb.SetClusterTimecode(std::min(first_audio_timecode, first_video_timecode));
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (block_count == 1) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddBlockGroup(kAudioTrackNum, first_audio_timecode,
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kAudioBlockDuration, kWebMFlagKeyframe,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       data.get(), size);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return cb.Finish();
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int audio_timecode = first_audio_timecode;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int video_timecode = first_video_timecode;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create simple blocks for everything except the last 2 blocks.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first video frame must be a keyframe.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 video_flag = kWebMFlagKeyframe;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < block_count - 2; i++) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (audio_timecode <= video_timecode) {
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cb.AddSimpleBlock(kAudioTrackNum, audio_timecode, kWebMFlagKeyframe,
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          data.get(), size);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_timecode += kAudioBlockDuration;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddSimpleBlock(kVideoTrackNum, video_timecode, video_flag, data.get(),
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        size);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_timecode += kVideoBlockDuration;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_flag = 0;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make the last 2 blocks BlockGroups so that they don't get delayed by the
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // block duration calculation logic.
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (audio_timecode <= video_timecode) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kWebMFlagKeyframe, data.get(), size);
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode,
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         kVideoBlockDuration, video_flag);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode,
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         kVideoBlockDuration, video_flag);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration,
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kWebMFlagKeyframe, data.get(), size);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cb.Finish();
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode,
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int end_timecode,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int track_number,
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int block_duration) {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(end_timecode, timecode);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<uint8> data(kBlockSize);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClusterBuilder cb;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb.SetClusterTimecode(timecode);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create simple blocks for everything except the last block.
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; timecode < (end_timecode - block_duration); i++) {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe,
655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        &data[0], data.size());
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      timecode += block_duration;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make the last block a BlockGroup so that it doesn't get delayed by the
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // block duration calculation logic.
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (track_number == kVideoTrackNum) {
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddVideoBlockGroup(&cb, track_number, timecode, block_duration,
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         kWebMFlagKeyframe);
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cb.AddBlockGroup(track_number, timecode, block_duration,
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       kWebMFlagKeyframe, &data[0], data.size());
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cb.Finish();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Read(DemuxerStream::Type type, const DemuxerStream::ReadCB& read_cb) {
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(read_cb);
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReadAudio(const DemuxerStream::ReadCB& read_cb) {
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Read(DemuxerStream::AUDIO, read_cb);
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReadVideo(const DemuxerStream::ReadCB& read_cb) {
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Read(DemuxerStream::VIDEO, read_cb);
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateExpectedReads(int timecode, int block_count) {
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GenerateExpectedReads(timecode, timecode, block_count);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GenerateExpectedReads(int start_audio_timecode,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int start_video_timecode,
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             int block_count) {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(block_count, 0);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (block_count == 1) {
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExpectRead(DemuxerStream::AUDIO, start_audio_timecode);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int audio_timecode = start_audio_timecode;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int video_timecode = start_video_timecode;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < block_count; i++) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (audio_timecode <= video_timecode) {
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ExpectRead(DemuxerStream::AUDIO, audio_timecode);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_timecode += kAudioBlockDuration;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExpectRead(DemuxerStream::VIDEO, video_timecode);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_timecode += kVideoBlockDuration;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateSingleStreamExpectedReads(int timecode,
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         int block_count,
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         DemuxerStream::Type type,
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         int block_duration) {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(block_count, 0);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int stream_timecode = timecode;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < block_count; i++) {
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExpectRead(type, stream_timecode);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stream_timecode += block_duration;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateAudioStreamExpectedReads(int timecode, int block_count) {
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GenerateSingleStreamExpectedReads(
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timecode, block_count, DemuxerStream::AUDIO, kAudioBlockDuration);
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateVideoStreamExpectedReads(int timecode, int block_count) {
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GenerateSingleStreamExpectedReads(
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timecode, block_count, DemuxerStream::VIDEO, kVideoBlockDuration);
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateEmptyCluster(int timecode) {
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClusterBuilder cb;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb.SetClusterTimecode(timecode);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cb.Finish();
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckExpectedRanges(const std::string& expected) {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckExpectedRanges(kSourceId, expected);
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckExpectedRanges(const std::string&  id,
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& expected) {
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Ranges<base::TimeDelta> r = demuxer_->GetBufferedRanges(id);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::stringstream ss;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << "{ ";
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < r.size(); ++i) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ss << "[" << r.start(i).InMilliseconds() << ","
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         << r.end(i).InMilliseconds() << ") ";
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << "}";
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ss.str(), expected);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(ReadDone, void(DemuxerStream::Status status,
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const scoped_refptr<DecoderBuffer>&));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StoreStatusAndBuffer(DemuxerStream::Status* status_out,
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            scoped_refptr<DecoderBuffer>* buffer_out,
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            DemuxerStream::Status status,
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const scoped_refptr<DecoderBuffer>& buffer) {
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *status_out = status;
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *buffer_out = buffer;
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReadUntilNotOkOrEndOfStream(DemuxerStream::Type type,
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   DemuxerStream::Status* status,
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   base::TimeDelta* last_timestamp) {
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* stream = demuxer_->GetStream(type);
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<DecoderBuffer> buffer;
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *last_timestamp = kNoTimestamp();
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    do {
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              base::Unretained(this), status, &buffer));
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop::current()->RunUntilIdle();
782ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (*status == DemuxerStream::kOk && !buffer->end_of_stream())
783ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *last_timestamp = buffer->timestamp();
784ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    } while (*status == DemuxerStream::kOk && !buffer->end_of_stream());
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ExpectEndOfStream(DemuxerStream::Type type) {
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, IsEndOfStream()));
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(base::Bind(
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ExpectRead(DemuxerStream::Type type, int64 timestamp_in_ms) {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                HasTimestamp(timestamp_in_ms)));
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(base::Bind(
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ExpectConfigChanged(DemuxerStream::Type type) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(base::Bind(
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
809558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void CheckExpectedBuffers(DemuxerStream* stream,
810558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                            const std::string& expected) {
811558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::vector<std::string> timestamps;
812558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    base::SplitString(expected, ' ', &timestamps);
813558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::stringstream ss;
814558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (size_t i = 0; i < timestamps.size(); ++i) {
815558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      DemuxerStream::Status status;
816558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      scoped_refptr<DecoderBuffer> buffer;
817558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
818558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                              base::Unretained(this), &status, &buffer));
819558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::MessageLoop::current()->RunUntilIdle();
820558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (status != DemuxerStream::kOk || buffer->end_of_stream())
821558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        break;
822558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
823558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (i > 0)
824558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        ss << " ";
825558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      ss << buffer->timestamp().InMilliseconds();
826558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
827558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_EQ(expected, ss.str());
828558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
829558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(Checkpoint, void(int id));
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int video_time_ms;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int audio_time_ms;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kSkip = -1;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test parsing a WebM file.
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |filename| - The name of the file in media/test/data to parse.
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |timestamps| - The expected timestamps on the parsed buffers.
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    a timestamp of kSkip indicates that a Read() call for that stream
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    shouldn't be made on that iteration of the loop. If both streams have
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    a kSkip then the loop will terminate.
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ParseWebMFile(const std::string& filename,
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const BufferTimestamps* timestamps,
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const base::TimeDelta& duration) {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ParseWebMFile(filename, timestamps, duration, true, true);
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ParseWebMFile(const std::string& filename,
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const BufferTimestamps* timestamps,
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const base::TimeDelta& duration,
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     bool has_audio, bool has_video) {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
856f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &host_, CreateInitDoneCB(duration, PIPELINE_OK), true);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (AddId(kSourceId, has_audio, has_video) != ChunkDemuxer::kOk)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read a WebM file into memory and send the data to the demuxer.
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
863ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendDataInPieces(buffer->data(), buffer->data_size(), 512);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that the timestamps on the first few packets match what we
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // expect.
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (timestamps[i].audio_time_ms != kSkip ||
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          timestamps[i].video_time_ms != kSkip);
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i++) {
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool audio_read_done = false;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool video_read_done = false;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (timestamps[i].audio_time_ms != kSkip) {
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ReadAudio(base::Bind(&OnReadDone,
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::TimeDelta::FromMilliseconds(
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 timestamps[i].audio_time_ms),
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &audio_read_done));
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(audio_read_done);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (timestamps[i].video_time_ms != kSkip) {
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ReadVideo(base::Bind(&OnReadDone,
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::TimeDelta::FromMilliseconds(
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 timestamps[i].video_time_ms),
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &video_read_done));
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(video_read_done);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD0(DemuxerOpened, void());
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(xhwang): This is a workaround of the issue that move-only parameters
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are not supported in mocked methods. Remove this when the issue is fixed
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689).
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD3(NeedKeyMock, void(const std::string& type,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const uint8* init_data, int init_data_size));
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DemuxerNeedKey(const std::string& type,
902424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                      const std::vector<uint8>& init_data) {
903424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
904424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    NeedKeyMock(type, init_data_ptr, init_data.size());
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Seek(base::TimeDelta seek_time) {
908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    demuxer_->StartWaitingForSeek(seek_time);
909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_loop_.RunUntilIdle();
911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
913ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void MarkEndOfStream(PipelineStatus status) {
914ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    demuxer_->MarkEndOfStream(status);
915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_loop_.RunUntilIdle();
916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockDemuxerHost host_;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ChunkDemuxer> demuxer_;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
927a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Init) {
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test no streams, audio-only, video-only, and audio & video scenarios.
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio and video streams can be encrypted or not encrypted.
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 16; i++) {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_audio = (i & 0x1) != 0;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_video = (i & 0x2) != 0;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_audio_encrypted = (i & 0x4) != 0;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_video_encrypted = (i & 0x8) != 0;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No test on invalid combination.
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((!has_audio && is_audio_encrypted) ||
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (!has_video && is_video_encrypted)) {
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateNewDemuxer();
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_audio_encrypted || is_video_encrypted) {
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int need_key_count = (is_audio_encrypted ? 1 : 0) +
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           (is_video_encrypted ? 1 : 0);
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(*this, NeedKeyMock(kWebMEncryptInitDataType, NotNull(),
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     DecryptConfig::kDecryptionKeySize))
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Times(Exactly(need_key_count));
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
953f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        has_audio, has_video, false, is_audio_encrypted, is_video_encrypted));
954f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
956f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_audio) {
957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ASSERT_TRUE(audio_stream);
958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(kCodecVorbis, config.codec());
961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(32, config.bits_per_channel());
962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout());
963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(44100, config.samples_per_second());
964f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_TRUE(config.extra_data());
965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_GT(config.extra_data_size(), 0u);
966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(is_audio_encrypted,
968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                audio_stream->audio_decoder_config().is_encrypted());
969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_FALSE(audio_stream);
971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_video) {
975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_TRUE(video_stream);
976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(is_video_encrypted,
977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                video_stream->video_decoder_config().is_encrypted());
978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_FALSE(video_stream);
980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ShutdownDemuxer();
983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    demuxer_.reset();
984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ChunkDemuxerTest, InitText) {
988f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Test with 1 video stream and 1 text streams, and 0 or 1 audio streams.
989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // No encryption cases handled here.
990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool has_video = true;
991f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_audio_encrypted = false;
992f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_video_encrypted = false;
993f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
994f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool has_audio = (i & 0x1) != 0;
995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CreateNewDemuxer();
997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DemuxerStream* text_stream = NULL;
999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TextTrackConfig text_config;
1000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(host_, AddTextStream(_,_))
1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        .WillOnce(DoAll(SaveArg<0>(&text_stream),
1002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SaveArg<1>(&text_config)));
1003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
1005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        has_audio, has_video, true, is_audio_encrypted, is_video_encrypted));
1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(text_stream);
1007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(kTextSubtitles, text_config.kind());
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(audio_stream);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(kCodecVorbis, config.codec());
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(32, config.bits_per_channel());
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout());
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(44100, config.samples_per_second());
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(config.extra_data());
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_GT(config.extra_data_size(), 0u);
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(is_audio_encrypted,
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                audio_stream->audio_decoder_config().is_encrypted());
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(audio_stream);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(video_stream);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(is_video_encrypted,
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                video_stream->video_decoder_config().is_encrypted());
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(video_stream);
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShutdownDemuxer();
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_.reset();
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that the demuxer reports an error if Shutdown()
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is called before all the initialization segments are appended.
1044a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppended) {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(
1048f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendInitSegmentWithSourceId("audio", true, false, false);
1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1055f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ChunkDemuxerTest, ShutdownBeforeAllInitSegmentsAppendedText) {
1057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
1058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Initialize(
1059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(
1060f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
1061f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1062f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk);
1063f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(AddId("video", false, true), ChunkDemuxer::kOk);
1064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1065f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_,_))
1066f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .Times(Exactly(1));
1067f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1068f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendInitSegmentWithSourceId("video", false, true, true);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Seek() completes successfully when the first cluster
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arrives.
1073a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) {
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
1075a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, Checkpoint(1));
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(46));
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, Checkpoint(2));
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Checkpoint(1);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1087a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Checkpoint(2);
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that parsing errors are handled for clusters appended after init.
1095a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) {
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
1097a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendGarbage();
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case where a Seek() is requested while the parser
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is in the middle of cluster. This is to verify that the parser
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// does not reset itself on a seek.
1106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) {
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 6));
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Split the cluster into two appends at an arbitrary point near the end.
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int first_append_size = cluster_a->size() - 11;
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int second_append_size = cluster_a->size() - first_append_size;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the first part of the cluster.
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(cluster_a->data(), first_append_size);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, kAudioBlockDuration);
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: We skip trying to read a video buffer here because computing
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the duration for this block relies on successfully parsing the last block
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the cluster the cluster.
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 2 * kAudioBlockDuration);
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(5));
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the rest of the cluster.
1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendData(cluster_a->data() + first_append_size, second_append_size);
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the new cluster and verify that only the blocks
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the new cluster are returned.
1135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(5000, 6));
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(5000, 6);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case where AppendData() is called before Init().
1140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) {
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> info_tracks;
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int info_tracks_size = 0;
1143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateInitSegment(true, true, false,
1144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    false, false, &info_tracks, &info_tracks_size);
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure Read() callbacks are dispatched with the proper data.
1150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Read) {
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, OutOfOrderClusters) {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
1170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
1171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(10, 4));
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Make sure that AppendCluster() does not fail with a cluster that has
1174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // overlaps with the previously appended cluster.
1175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(5, 4));
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that AppendData() can still accept more data.
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2));
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->AppendData(kSourceId, cluster_c->data(), cluster_c->size());
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) {
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
1184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClusterBuilder cb;
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the case where block timecodes are not monotonically
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // increasing but stay above the cluster timecode.
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cb.SetClusterTimecode(5);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 5);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 10);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 7);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 15);
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(cb.Finish());
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that AppendData() ignores data after the error.
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2));
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size());
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) {
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
1206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClusterBuilder cb;
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test timecodes going backwards and including values less than the cluster
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // timecode.
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cb.SetClusterTimecode(5);
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 5);
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 5);
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 3);
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 3);
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(cb.Finish());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that AppendData() ignores data after the error.
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2));
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size());
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) {
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
1229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClusterBuilder cb;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test monotonic increasing timestamps on a per stream
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // basis.
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cb.SetClusterTimecode(5);
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 5);
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 5);
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 4);
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 7);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(cb.Finish());
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Test the case where a cluster is passed to AppendCluster() before
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// INFO & TRACKS data.
1247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) {
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 1));
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test cases where we get an MarkEndOfStream() call during initialization.
1258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EOSDuringInit) {
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
1262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) {
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
1273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShutdownDemuxer();
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->RemoveId(kSourceId);
1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  demuxer_.reset();
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWithNoMediaAppend) {
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
1284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DecodeErrorEndOfStream) {
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kDefaultFirstClusterRange);
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_ERROR_DECODE);
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kDefaultFirstClusterRange);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, NetworkErrorEndOfStream) {
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kDefaultFirstClusterRange);
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK));
1306ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_ERROR_NETWORK);
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class to reduce duplicate code when testing end of stream
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Read() behavior.
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EndOfStreamHelper {
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit EndOfStreamHelper(Demuxer* demuxer)
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : demuxer_(demuxer),
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_read_done_(false),
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        video_read_done_(false) {
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request a read on the audio and video streams.
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RequestReads() {
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(audio_read_done_);
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(video_read_done_);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    audio->Read(base::Bind(&OnEndOfStreamReadDone, &audio_read_done_));
1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    video->Read(base::Bind(&OnEndOfStreamReadDone, &video_read_done_));
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see if |audio_read_done_| and |video_read_done_| variables
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // match |expected|.
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIfReadDonesWereCalled(bool expected) {
1335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::MessageLoop::current()->RunUntilIdle();
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected, audio_read_done_);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected, video_read_done_);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void OnEndOfStreamReadDone(
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool* called,
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DemuxerStream::Status status,
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<DecoderBuffer>& buffer) {
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(status, DemuxerStream::kOk);
1346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(buffer->end_of_stream());
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *called = true;
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Demuxer* demuxer_;
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done_;
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done_;
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EndOfStreamHelper);
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that all pending reads that we don't have media data for get an
1358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// "end of stream" buffer when MarkEndOfStream() is called.
1359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWithPendingReads) {
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done_1 = false;
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done_1 = false;
1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done_1));
1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done_1));
1375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done_1);
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done_1);
1379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  end_of_stream_helper_1.RequestReads();
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kVideoBlockDuration)));
1384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
1387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  end_of_stream_helper_2.RequestReads();
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Make sure that all Read() calls after we get an MarkEndOfStream()
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call return an "end of stream" buffer.
1394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ReadsAfterEndOfStream) {
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done_1 = false;
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done_1 = false;
1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_3(demuxer_.get());
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done_1));
1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done_1));
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.RequestReads();
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done_1);
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done_1);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.CheckIfReadDonesWereCalled(false);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kVideoBlockDuration)));
1420ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request a few more reads and make sure we immediately get
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // end of stream buffers.
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_2.RequestReads();
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_3.RequestReads();
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_3.CheckIfReadDonesWereCalled(true);
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamDuringCanceledSeek) {
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendCluster(0, 10);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(138)));
1438ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first seek.
1441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(20));
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate another seek being requested before the first
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // seek has finished prerolling.
1445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(30);
1446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time2);
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finish second seek.
1449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time2);
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DemuxerStream::Status status;
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta last_timestamp;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure audio can reach end of stream.
1455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure video can reach end of stream.
1459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure AppendData() will accept elements that span multiple calls.
1464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendingInPieces) {
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> info_tracks;
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int info_tracks_size = 0;
1473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateInitSegment(true, true, false,
1474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    false, false, &info_tracks, &info_tracks_size);
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster());
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster());
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size();
1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> buffer(new uint8[buffer_size]);
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8* dst = buffer.get();
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, info_tracks.get(), info_tracks_size);
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dst += info_tracks_size;
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, cluster_a->data(), cluster_a->size());
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dst += cluster_a->size();
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, cluster_b->data(), cluster_b->size());
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dst += cluster_b->size();
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendDataInPieces(buffer.get(), buffer_size);
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 9);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_AudioAndVideo) {
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, 0},
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 3},
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, 6},
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, 9},
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {133, 12},
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240.webm", buffer_timestamps,
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2744)));
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_LiveAudioAndVideo) {
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, 0},
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 3},
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, 6},
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, 9},
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {133, 12},
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-live.webm", buffer_timestamps,
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kInfiniteDuration()));
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_AudioOnly) {
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 0},
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 3},
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 6},
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 9},
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 12},
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps,
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2744),
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            true, false));
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_VideoOnly) {
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, kSkip},
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, kSkip},
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, kSkip},
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, kSkip},
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {133, kSkip},
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps,
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2703),
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            false, true));
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1554a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_AltRefFrames) {
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, 0},
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 3},
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 6},
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, 9},
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, 12},
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-altref.webm", buffer_timestamps,
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2767)));
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we output buffers before the entire cluster has been parsed.
1569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, IncrementalClusterParsing) {
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendEmptyCluster(0);
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster(GenerateCluster(0, 6));
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
1577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the reads haven't completed yet.
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append data one byte at a time until the audio read completes.
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i = 0;
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; i < cluster->size() && !audio_read_done; ++i) {
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(cluster->data() + i, 1);
1592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_loop_.RunUntilIdle();
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(i, 0);
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(i, cluster->size());
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append data one byte at a time until the video read completes.
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; i < cluster->size() && !video_read_done; ++i) {
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(cluster->data() + i, 1);
1603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_loop_.RunUntilIdle();
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(i, cluster->size());
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio_read_done = false;
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video_read_done = false;
1611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(23),
1613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(33),
1616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the reads haven't completed yet.
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the remaining data.
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LT(i, cluster->size());
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(cluster->data() + i, cluster->size() - i);
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) {
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(
1636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 tmp = 0;
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->AppendData(kSourceId, &tmp, 1);
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) {
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(kNoTimestamp(),
1648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               DEMUXER_ERROR_COULD_NOT_OPEN), true);
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> codecs(1);
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codecs[0] = "vorbis";
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs),
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ChunkDemuxer::kOk);
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendInitSegment(true, true);
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1658a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) {
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(kNoTimestamp(),
1662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               DEMUXER_ERROR_COULD_NOT_OPEN), true);
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> codecs(1);
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codecs[0] = "vp8";
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs),
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ChunkDemuxer::kOk);
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendInitSegment(true, true);
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1672a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, MultipleHeaders) {
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append another identical initialization segment.
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendInitSegment(true, true);
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1680a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 9);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) {
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append audio and video data into separate source ids.
1691a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id,
1692a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
1694a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id,
1695a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) {
1700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(matthewjheaney): Here and elsewhere, we need more tests
1701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // for inband text tracks (http://crbug/321455).
1702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string audio_id = "audio1";
1704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string video_id = "video1";
1705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_,_))
1707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    .Times(Exactly(2));
1708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, true));
1709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Append audio and video data into separate source ids.
1711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendCluster(audio_id,
1712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
1714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendCluster(video_id,
1715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
1716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
1717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1719a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AddIdFailures) {
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(audio_id, true, false), ChunkDemuxer::kOk);
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding an id with audio/video should fail because we already added audio.
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit);
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendInitSegmentWithSourceId(audio_id, true, false, false);
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding an id after append should fail.
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit);
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Read() calls after a RemoveId() return "end of stream" buffers.
1739a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, RemoveId) {
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Append audio and video data into separate source ids.
1745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id,
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id,
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() from audio should return normal buffers.
1751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the audio id.
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->RemoveId(audio_id);
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() from audio should return "end of stream" buffers.
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
1758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
1759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() from video should still return normal buffers.
1763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that removing an ID immediately after adding it does not interfere with
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// quota for new IDs in the future.
1768a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, RemoveAndAddId) {
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id_1 = "audio1";
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(AddId(audio_id_1, true, false) == ChunkDemuxer::kOk);
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->RemoveId(audio_id_1);
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id_2 = "audio2";
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(AddId(audio_id_2, true, false) == ChunkDemuxer::kOk);
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1777a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekCanceled) {
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append cluster at the beginning of the stream.
1781a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 4));
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to an unbuffered region.
1784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(50));
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to read in unbuffered area; should not fulfill the read.
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
1789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_AbortExpected, &audio_read_done));
1790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone_AbortExpected, &video_read_done));
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now cancel the pending seek, which should flush the reads with empty
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffers.
1796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(0);
1797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time);
1798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A seek back to the buffered region should succeed.
1803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time);
1804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 4);
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1807a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekCanceledWhileWaitingForSeek) {
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append cluster at the beginning of the stream.
1811a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 4));
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start waiting for a seek.
1814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time1 = base::TimeDelta::FromSeconds(50);
1815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time2 = base::TimeDelta::FromSeconds(0);
1816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time1);
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now cancel the upcoming seek to an unbuffered region.
1819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time2);
1820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time1, NewExpectedStatusCB(PIPELINE_OK));
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read requests should be fulfilled with empty buffers.
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
1825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_AbortExpected, &audio_read_done));
1826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone_AbortExpected, &video_read_done));
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A seek back to the buffered region should succeed.
1831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time2);
1832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 4);
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Seek() successfully seeks to all source IDs.
1836a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekAudioAndVideoSources) {
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1841a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
1842a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      audio_id,
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
1844a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
1845a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      video_id,
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() should return buffers at 0.
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
1851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to 3 (an unbuffered region).
1861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(3));
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio_read_done = false;
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video_read_done = false;
1865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromSeconds(3),
1867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromSeconds(3),
1870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read()s should not return until after data is appended at the Seek point.
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id,
1876a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                GenerateSingleStreamCluster(
1877a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    3000, 3092, kAudioTrackNum, kAudioBlockDuration));
1878a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id,
1879a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                GenerateSingleStreamCluster(
1880a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    3000, 3132, kVideoTrackNum, kVideoBlockDuration));
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() should return buffers at 3.
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test that Seek() completes successfully when EndOfStream
18907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// is called before data is available for that seek point.
18917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This scenario might be useful if seeking past the end of stream
18927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// of either audio or video (or both).
1893a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamAfterPastEosSeek) {
18947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
18957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1896a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 120, kAudioTrackNum, 10));
1897a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 5));
18987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Seeking past the end of video.
19007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Note: audio data is available for that seek point.
19017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool seek_cb_was_called = false;
1902eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(110);
1903eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
1904eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time,
19057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
1906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(seek_cb_was_called);
19097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
19107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
19117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(120)));
1912ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
1913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(seek_cb_was_called);
19167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
19177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ShutdownDemuxer();
19187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
19197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
19207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test that EndOfStream is ignored if coming during a pending seek
19217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// whose seek time is before some existing ranges.
1922a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamDuringPendingSeek) {
19237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
19247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1925a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 120, kAudioTrackNum, 10));
1926a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 5));
1927a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(200, 300, kAudioTrackNum, 10));
1928a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(200, 300, kVideoTrackNum, 5));
19297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
19307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool seek_cb_was_called = false;
1931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(160);
1932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
1933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time,
19347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
1935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(seek_cb_was_called);
19387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1939a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(300)));
1940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
1941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(seek_cb_was_called);
19447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1945ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  demuxer_->UnmarkEndOfStream();
1946ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1947a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(140, 180, kAudioTrackNum, 10));
1948a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(140, 180, kVideoTrackNum, 5));
1949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(seek_cb_was_called);
19537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
19547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ShutdownDemuxer();
19557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
19567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test ranges in an audio-only stream.
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) {
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk);
19642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendInitSegment(true, false);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a simple cluster.
1967a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
1968a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,92) }");
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append a disjoint cluster to check for two separate ranges.
1973a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
1974a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      150, 219, kAudioTrackNum, kAudioBlockDuration));
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,92) [150,219) }");
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test ranges in a video-only stream.
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) {
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk);
19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendInitSegment(false, true);
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a simple cluster.
1989a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
1990a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,132) }");
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append a disjoint cluster to check for two separate ranges.
1995a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
1996a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      200, 299, kVideoTrackNum, kVideoBlockDuration));
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,132) [200,299) }");
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 0 -> 23
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 0 -> 33
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 0 -> 23
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio block duration is smaller than video block duration,
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the buffered ranges should correspond to the audio blocks.
2009a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
2010a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kAudioBlockDuration, kAudioTrackNum, kAudioBlockDuration));
2011a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
2012a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kVideoBlockDuration, kVideoTrackNum, kVideoBlockDuration));
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) }");
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 300 -> 400
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 320 -> 420
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 320 -> 400  (end overlap)
2019a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(300, 400, kAudioTrackNum, 50));
2020a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(320, 420, kVideoTrackNum, 50));
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) }");
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 520 -> 590
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 500 -> 570
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 520 -> 570  (front overlap)
2027a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(520, 590, kAudioTrackNum, 70));
2028a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(500, 570, kVideoTrackNum, 70));
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) }");
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 720 -> 750
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 700 -> 770
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 720 -> 750  (complete overlap, audio)
2035a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(720, 750, kAudioTrackNum, 30));
2036a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(700, 770, kVideoTrackNum, 70));
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) }");
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 900 -> 970
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 920 -> 950
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 920 -> 950  (complete overlap, video)
2043a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(900, 970, kAudioTrackNum, 70));
2044a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(920, 950, kVideoTrackNum, 30));
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appending within buffered range should not affect buffered ranges.
2049a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(930, 950, kAudioTrackNum, 20));
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appending to single stream outside buffered ranges should not affect
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffered ranges.
2054a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(1230, 1240, kVideoTrackNum, 10));
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2058ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Once MarkEndOfStream() is called, GetBufferedRanges should not cut off any
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// over-hanging tails at the end of the ranges as this is likely due to block
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// duration differences.
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) {
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2064a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 90, kAudioTrackNum, 90));
2065a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 100));
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,90) }");
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(100)));
2070ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,100) }");
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DifferentStreamTimecodes) {
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a cluster where the video timecode begins 25ms after the audio.
2079a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 25, 8));
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(0));
2082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 25, 8);
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to 5 seconds.
2085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(5));
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a cluster to fulfill this seek, where audio timecode begins 25ms
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after the video.
2089a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(5025, 5000, 8));
2090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(5025, 5000, 8);
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2093a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesSeparateSources) {
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate two streams where the video stream starts 5ms after the audio
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stream and append them.
2100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(
2101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      25, 4 * kAudioBlockDuration + 25, kAudioTrackNum, kAudioBlockDuration));
2102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(
2103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      30, 4 * kVideoBlockDuration + 30, kVideoTrackNum, kVideoBlockDuration));
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both streams should be able to fulfill a seek to 25.
2106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(25));
2107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(25, 4);
2108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(30, 4);
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesOutOfRange) {
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate two streams where the video stream starts 10s after the audio
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stream and append them.
2118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(0,
2119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      4 * kAudioBlockDuration + 0, kAudioTrackNum, kAudioBlockDuration));
2120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(10000,
2121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      4 * kVideoBlockDuration + 10000, kVideoTrackNum, kVideoBlockDuration));
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not be able to fulfill a seek to 0.
2124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(0);
2125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
2126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time,
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 NewExpectedStatusCB(PIPELINE_ERROR_ABORT));
2128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
2129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectEndOfStream(DemuxerStream::VIDEO);
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ClusterWithNoBuffers) {
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate and append an empty cluster beginning at 0.
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendEmptyCluster(0);
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check that data can be appended after this cluster correctly.
2139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
2140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
2141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CodecPrefixMatching) {
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected = ChunkDemuxer::kOk;
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> codecs;
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codecs.push_back("avc1.4D4041");
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(demuxer_->AddId("source_id", "video/mp4", codecs), expected);
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test codec ID's that are not compliant with RFC6381, but have been
21582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// seen in the wild.
2159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) {
21602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
21612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
21632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected = ChunkDemuxer::kOk;
21642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
21652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* codec_ids[] = {
21662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // GPAC places leading zeros on the audio object type.
21672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "mp4a.40.02",
21682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "mp4a.40.05"
21692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
21702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(codec_ids); ++i) {
21722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<std::string> codecs;
21732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    codecs.push_back(codec_ids[i]);
21742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChunkDemuxer::Status result =
21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        demuxer_->AddId("source_id", "audio/mp4", codecs);
21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(result, expected)
21792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Fail to add codec_id '" << codec_ids[i] << "'";
21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (result == ChunkDemuxer::kOk)
21822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      demuxer_->RemoveId("source_id");
21832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
21842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) {
21872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
21882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(host_, SetDuration(_))
21902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(AnyNumber());
21912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta kLastAudioTimestamp = base::TimeDelta::FromMilliseconds(92);
21932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta kLastVideoTimestamp = base::TimeDelta::FromMilliseconds(99);
21942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
2196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
2197ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
21982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DemuxerStream::Status status;
22002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta last_timestamp;
22012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that we can read audio & video to the end w/o problems.
2203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
22042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
22052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
22062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
22082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
22092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
22102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Seek back to 0 and verify that we can read to the end again..
2212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(0));
22132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
22152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
22162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
22172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
22192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
22202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
22212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) {
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
2225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true);
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId("audio", true, false), ChunkDemuxer::kOk);
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId("video", false, true), ChunkDemuxer::kOk);
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("audio", "{ }");
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("video", "{ }");
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Seek() completes successfully when the first cluster
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arrives.
2235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) {
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(0);
2243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kDefaultSecondClusterEndTimestamp)));
2248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 4);
2253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(46, 66, 5);
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper(demuxer_.get());
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper.RequestReads();
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper.CheckIfReadDonesWereCalled(true);
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ConfigChange_Video) {
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithConfigChangeData());
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DemuxerStream::Status status;
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta last_timestamp;
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
2269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch initial video config and verify it matches what we expect.
2271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_1.IsValidConfig());
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().width(), 320);
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().height(), 240);
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_timestamp.InMilliseconds(), 501);
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the new decoder config.
2284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_2.IsValidConfig());
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().width(), 640);
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().height(), 360);
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 527);
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read until the next config change.
2292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_timestamp.InMilliseconds(), 793);
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the new config and verify that it matches the first one.
2297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 801);
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read until the end of the stream just to make sure there aren't any other
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // config changes.
2303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ConfigChange_Audio) {
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithConfigChangeData());
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DemuxerStream::Status status;
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta last_timestamp;
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
2316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch initial audio config and verify it matches what we expect.
2318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const AudioDecoderConfig& audio_config_1 = audio->audio_decoder_config();
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(audio_config_1.IsValidConfig());
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_1.samples_per_second(), 44100);
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_1.extra_data_size(), 3863u);
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_timestamp.InMilliseconds(), 524);
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the new decoder config.
2331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const AudioDecoderConfig& audio_config_2 = audio->audio_decoder_config();
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(audio_config_2.IsValidConfig());
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_2.samples_per_second(), 44100);
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_2.extra_data_size(), 3935u);
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 527);
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read until the next config change.
2339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_timestamp.InMilliseconds(), 759);
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the new config and verify that it matches the first one.
2344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(audio_config_1.Matches(audio->audio_decoder_config()));
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 779);
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read until the end of the stream just to make sure there aren't any other
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // config changes.
2350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ConfigChange_Seek) {
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithConfigChangeData());
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch initial video config and verify it matches what we expect.
2362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_1.IsValidConfig());
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().width(), 320);
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().height(), 240);
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to a location with a different config.
2370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(527));
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the config change is signalled.
2373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectConfigChanged(DemuxerStream::VIDEO);
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the new decoder config and verify it is what we expect.
2376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_2.IsValidConfig());
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().width(), 640);
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().height(), 360);
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that Read() will return a buffer now.
2382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 527);
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek back to the beginning and verify we get another config change.
2385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(0));
2386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectConfigChanged(DemuxerStream::VIDEO);
2387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
2388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to a location that requires a config change and then
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // seek to a new location that has the same configuration as
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the start of the file without a Read() in the middle.
2393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(527));
2394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(801));
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that no config change is signalled.
2397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 801);
2398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, TimestampPositiveOffset) {
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSourceId, base::TimeDelta::FromSeconds(30)));
2406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(30000));
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(30000, 2);
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, TimestampNegativeOffset) {
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSourceId, base::TimeDelta::FromSeconds(-1)));
2418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(1000, 2));
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 2);
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, TimestampOffsetSeparateStreams) {
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_id, base::TimeDelta::FromMilliseconds(-2500)));
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_id, base::TimeDelta::FromMilliseconds(-2500)));
2432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(2500,
2433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      2500 + kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration));
2434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(2500,
2435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      2500 + kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration));
2436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
2437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(27300));
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_id, base::TimeDelta::FromMilliseconds(27300)));
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_id, base::TimeDelta::FromMilliseconds(27300)));
2445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(
2446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration));
2447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(
2448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration));
2449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(27300, 4);
2450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(27300, 4);
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, TimestampOffsetMidParse) {
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster = GenerateCluster(0, 2);
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append only part of the cluster data.
24582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(cluster->data(), cluster->size() - 13);
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting a timestamp should fail because we're in the middle of a cluster.
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(demuxer_->SetTimestampOffset(
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSourceId, base::TimeDelta::FromSeconds(25)));
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Abort(kSourceId);
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After Abort(), setting a timestamp should succeed since we're no longer
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the middle of a cluster
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSourceId, base::TimeDelta::FromSeconds(25)));
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DurationChange) {
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kStreamDuration = kDefaultDuration().InMilliseconds();
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add data leading up to the currently set duration.
2476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(kStreamDuration - kAudioBlockDuration,
2477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                kStreamDuration - kVideoBlockDuration,
2478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                2));
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [201191,201224) }");
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add data at the currently set duration. The duration should not increase.
2483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(kDefaultDuration().InMilliseconds(), 2));
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Range should not be affected.
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [201191,201224) }");
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now add data past the duration and expect a new duration to be signalled.
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNewStreamDuration =
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kStreamDuration + kAudioBlockDuration * 2;
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kNewStreamDuration)));
2493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(kStreamDuration + kAudioBlockDuration,
2494a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                kStreamDuration + kVideoBlockDuration,
2495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                2));
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that the range has increased appropriately.
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [201191,201270) }");
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DurationChangeTimestampOffset) {
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(demuxer_->SetTimestampOffset(kSourceId, kDefaultDuration()));
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kDefaultDuration() + base::TimeDelta::FromMilliseconds(
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kAudioBlockDuration * 2)));
2509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 4));
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamTruncateDuration) {
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kDefaultFirstClusterEndTimestamp)));
2519ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ZeroLengthAppend) {
25242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
25252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(NULL, 0);
25262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendAfterEndOfStream) {
25292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
25302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(host_, SetDuration(_))
25322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(AnyNumber());
25332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
2535ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
2536ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2537ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  demuxer_->UnmarkEndOfStream();
25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
2540ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test receiving a Shutdown() call before we get an Initialize()
25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// call. This can happen if video element gets destroyed before
25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the pipeline has a chance to initialize the demuxer.
2546a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ShutdownBeforeInitialize) {
25472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->Shutdown();
25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->Initialize(
2549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
25502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.RunUntilIdle();
25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(ChunkDemuxerTest, ReadAfterAudioDisabled) {
2554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
2555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
2556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
2558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(stream);
2559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The stream should no longer be present.
2561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  demuxer_->OnAudioRendererDisabled();
2562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(demuxer_->GetStream(DemuxerStream::AUDIO));
2563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Normally this would return an audio buffer at timestamp zero, but
2565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // all reads should return EOS buffers when disabled.
2566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool audio_read_done = false;
2567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream->Read(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
2568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.RunUntilIdle();
2569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(audio_read_done);
2571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Verifies that signalling end of stream while stalled at a gap
25747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// boundary does not trigger end of stream buffers to be returned.
2575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWhileWaitingForGapToBeFilled) {
25767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
25777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
25787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppendCluster(0, 10);
25797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppendCluster(300, 10);
25807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,132) [300,432) }");
25817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
25827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
25837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GenerateExpectedReads(0, 10);
25847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
25857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool audio_read_done = false;
25867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool video_read_done = false;
25877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
25887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::TimeDelta::FromMilliseconds(138),
25897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &audio_read_done));
25907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
25917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::TimeDelta::FromMilliseconds(138),
25927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &video_read_done));
25937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
25947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads didn't complete
25957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
25967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
25977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
25987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(438)));
2599ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
26007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
26017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads still haven't completed.
26027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
26037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
26047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2605ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  demuxer_->UnmarkEndOfStream();
2606ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
26077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppendCluster(138, 24);
26087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
2610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
26117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,438) }");
26127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
26137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads have completed.
26147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
26157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
26167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
26177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Read the rest of the buffers.
26187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GenerateExpectedReads(161, 171, 22);
26197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
26207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that reads block because the append cleared the end of stream state.
26217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  audio_read_done = false;
26227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  video_read_done = false;
26237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_EOSExpected,
26247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &audio_read_done));
26257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone_EOSExpected,
26267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &video_read_done));
26277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
26287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads don't complete.
26297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
26307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
26317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2632ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
26337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
26347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
26357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
26367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
26377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2638a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CanceledSeekDuringInitialPreroll) {
2639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(InitDemuxer(true, true));
2640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Cancel preroll.
2642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(200);
2643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time);
2644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Initiate the seek to the new location.
2646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time);
2647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append data to satisfy the seek.
2649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendCluster(seek_time.InMilliseconds(), 10);
2650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
2651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2652a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GCDuringSeek) {
2653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(InitDemuxer(true, false));
2654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->SetMemoryLimitsForTesting(5 * kBlockSize);
2656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time1 = base::TimeDelta::FromMilliseconds(1000);
2658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(500);
2659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Initiate a seek to |seek_time1|.
2661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time1);
2662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append data to satisfy the first seek request.
2664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
2665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                            seek_time1.InMilliseconds(), 5);
2666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckExpectedRanges(kSourceId, "{ [1000,1115) }");
2667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Signal that the second seek is starting.
2669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time2);
2670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append data to satisfy the second seek. This append triggers
2672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the garbage collection logic since we set the memory limit to
2673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // 5 blocks.
2674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
2675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                            seek_time2.InMilliseconds(), 5);
2676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Verify that the buffers that cover |seek_time2| do not get
2678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // garbage collected.
2679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckExpectedRanges(kSourceId, "{ [500,615) }");
2680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Complete the seek.
2682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time2, NewExpectedStatusCB(PIPELINE_OK));
2683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append more data and make sure that the blocks for |seek_time2|
2686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // don't get removed.
2687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
2688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // NOTE: The current GC algorithm tries to preserve the GOP at the
2689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  current position as well as the last appended GOP. This is
2690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  why there are 2 ranges in the expectations.
2691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5);
2692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }");
2693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
2694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2695bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(ChunkDemuxerTest, RemoveBeforeInitSegment) {
2696bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    EXPECT_CALL(*this, DemuxerOpened());
2697bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    demuxer_->Initialize(
2698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_OK), true);
2699bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
2700bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, true, true));
2701bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
2702bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0),
2703bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                     base::TimeDelta::FromMilliseconds(1));
2704bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
2705bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
2706558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(ChunkDemuxerTest, AppendWindow) {
2707558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_TRUE(InitDemuxer(false, true));
2708558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
2709558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2710558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Set the append window to [20,280).
2711558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  demuxer_->SetAppendWindowStart(kSourceId,
2712558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                 base::TimeDelta::FromMilliseconds(20));
2713558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  demuxer_->SetAppendWindowEnd(kSourceId,
2714558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                               base::TimeDelta::FromMilliseconds(280));
2715558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2716558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Append a cluster that starts before and ends after the append window.
2717558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
2718558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                            "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
2719558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2720558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Verify that GOPs that start outside the window are not included
2721558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // in the buffer. Also verify that buffers that extend beyond the
2722558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // window are not included.
2723558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  CheckExpectedRanges(kSourceId, "{ [120,300) }");
2724558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  CheckExpectedBuffers(stream, "120 150 180 210 240 270");
2725558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2726558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Extend the append window to [20,650).
2727558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  demuxer_->SetAppendWindowEnd(kSourceId,
2728558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                               base::TimeDelta::FromMilliseconds(650));
2729558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2730558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Append more data and verify that adding buffers start at the next
2731558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // keyframe.
2732558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
2733558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                            "360 390 420K 450 480 510 540K 570 600 630K");
2734558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  CheckExpectedRanges(kSourceId, "{ [120,300) [420,660) }");
2735558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
2736558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2737a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) {
2738a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(true, true));
2739a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
2740a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendGarbage();
2741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50);
2742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  demuxer_->StartWaitingForSeek(seek_time);
2743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
2744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
2746