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"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/cluster_builder.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_constants.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/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)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)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.
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)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.
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint8 kVP8Interframe[] = { 0x11, 0x00, 0x00 };
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)static const uint8 kCuesHeader[] = {
496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  0x1C, 0x53, 0xBB, 0x6B,  // Cues ID
506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // cues(size = 0)
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kTracksHeaderSize = sizeof(kTracksHeader);
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kTracksSizeOffset = 4;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The size of TrackEntry element in test file "webm_vorbis_track_entry" starts
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at index 1 and spans 8 bytes.
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAudioTrackSizeOffset = 1;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAudioTrackSizeWidth = 8;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAudioTrackEntryHeaderSize =
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    kAudioTrackSizeOffset + kAudioTrackSizeWidth;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The size of TrackEntry element in test file "webm_vp8_track_entry" starts at
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// index 1 and spans 8 bytes.
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kVideoTrackSizeOffset = 1;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kVideoTrackSizeWidth = 8;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kVideoTrackEntryHeaderSize =
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    kVideoTrackSizeOffset + kVideoTrackSizeWidth;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kVideoTrackNum = 1;
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAudioTrackNum = 2;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kTextTrackNum = 3;
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const int kAlternateTextTrackNum = 4;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAudioBlockDuration = 23;
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kVideoBlockDuration = 33;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kTextBlockDuration = 100;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kBlockSize = 10;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSourceId[] = "SourceId";
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kDefaultFirstClusterRange[] = "{ [0,46) }";
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kDefaultFirstClusterEndTimestamp = 66;
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kDefaultSecondClusterEndTimestamp = 132;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta kDefaultDuration() {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::TimeDelta::FromMilliseconds(201224);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Write an integer into buffer in the form of vint that spans 8 bytes.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The data pointed by |buffer| should be at least 8 bytes long.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void WriteInt64(uint8* buffer, int64 number) {
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(number >= 0 && number < 0x00FFFFFFFFFFFFFFLL);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer[0] = 0x01;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 tmp = number;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 7; i > 0; i--) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer[i] = tmp & 0xff;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tmp >>= 8;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MATCHER_P(HasTimestamp, timestamp_in_ms, "") {
103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return arg.get() && !arg->end_of_stream() &&
104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch         arg->timestamp().InMilliseconds() == timestamp_in_ms;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochMATCHER(IsEndOfStream, "") { return arg.get() && arg->end_of_stream(); }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnReadDone(const base::TimeDelta& expected_time,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bool* called,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       DemuxerStream::Status status,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const scoped_refptr<DecoderBuffer>& buffer) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kOk);
114ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(expected_time, buffer->timestamp());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *called = true;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnReadDone_AbortExpected(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* called, DemuxerStream::Status status,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<DecoderBuffer>& buffer) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kAborted);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, buffer.get());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *called = true;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void OnReadDone_EOSExpected(bool* called,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   DemuxerStream::Status status,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const scoped_refptr<DecoderBuffer>& buffer) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, DemuxerStream::kOk);
130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(buffer->end_of_stream());
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *called = true;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static void OnSeekDone_OKExpected(bool* called, PipelineStatus status) {
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(status, PIPELINE_OK);
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  *called = true;
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static void LogFunc(const std::string& str) { DVLOG(1) << str; }
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class ChunkDemuxerTest : public ::testing::Test {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum CodecsIndex {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUDIO,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VIDEO,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MAX_CODECS_INDEX
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default cluster to append first for simple tests.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> kDefaultFirstCluster() {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GenerateCluster(0, 4);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default cluster to append after kDefaultFirstCluster()
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has been appended. This cluster starts with blocks that
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have timestamps consistent with the end times of the blocks
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in kDefaultFirstCluster() so that these two clusters represent
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a continuous region.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> kDefaultSecondCluster() {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GenerateCluster(46, 66, 5);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ChunkDemuxerTest()
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : append_window_end_for_next_append_(kInfiniteDuration()) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateNewDemuxer();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateNewDemuxer() {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Closure open_cb =
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this));
171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    Demuxer::NeedKeyCB need_key_cb =
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this));
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    demuxer_.reset(
1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        new ChunkDemuxer(open_cb, need_key_cb, base::Bind(&LogFunc), true));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ChunkDemuxerTest() {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShutdownDemuxer();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CreateInitSegment(int stream_flags,
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         bool is_audio_encrypted,
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         bool is_video_encrypted,
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         scoped_ptr<uint8[]>* buffer,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int* size) {
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CreateInitSegmentInternal(
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        stream_flags, is_audio_encrypted, is_video_encrypted, buffer, false,
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        size);
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void CreateInitSegmentWithAlternateTextTrackNum(int stream_flags,
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                  bool is_audio_encrypted,
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                  bool is_video_encrypted,
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                  scoped_ptr<uint8[]>* buffer,
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                  int* size) {
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK(stream_flags & HAS_TEXT);
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CreateInitSegmentInternal(
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        stream_flags, is_audio_encrypted, is_video_encrypted, buffer, true,
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        size);
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void CreateInitSegmentInternal(int stream_flags,
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 bool is_audio_encrypted,
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 bool is_video_encrypted,
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 scoped_ptr<uint8[]>* buffer,
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 bool use_alternate_text_track_id,
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 int* size) {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool has_audio = (stream_flags & HAS_AUDIO) != 0;
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool has_video = (stream_flags & HAS_VIDEO) != 0;
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool has_text = (stream_flags & HAS_TEXT) != 0;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> ebml_header;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> info;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> audio_track_entry;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> video_track_entry;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> audio_content_encodings;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> video_content_encodings;
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<DecoderBuffer> text_track_entry;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ebml_header = ReadTestDataFile("webm_ebml_element");
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info = ReadTestDataFile("webm_info_element");
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tracks_element_size = 0;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_track_entry = ReadTestDataFile("webm_vorbis_track_entry");
227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      tracks_element_size += audio_track_entry->data_size();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_audio_encrypted) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_content_encodings = ReadTestDataFile("webm_content_encodings");
230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        tracks_element_size += audio_content_encodings->data_size();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_track_entry = ReadTestDataFile("webm_vp8_track_entry");
236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      tracks_element_size += video_track_entry->data_size();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_video_encrypted) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        video_content_encodings = ReadTestDataFile("webm_content_encodings");
239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        tracks_element_size += video_content_encodings->data_size();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_text) {
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // TODO(matthewjheaney): create an abstraction to do
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // this (http://crbug/321454).
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // We need it to also handle the creation of multiple text tracks.
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // This is the track entry for a text track,
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // TrackEntry [AE], size=30
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      //   TrackNum [D7], size=1, val=3 (or 4 if use_alternate_text_track_id)
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      //   TrackUID [73] [C5], size=1, value=3 (must remain constant for same
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      //     track, even if TrackNum changes)
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //   TrackType [83], size=1, val=0x11
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      //   CodecId [86], size=18, val="D_WEBVTT/SUBTITLES"
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      char str[] = "\xAE\x9E\xD7\x81\x03\x73\xC5\x81\x03"
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   "\x83\x81\x11\x86\x92"
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   "D_WEBVTT/SUBTITLES";
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK_EQ(str[4], kTextTrackNum);
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (use_alternate_text_track_id)
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        str[4] = kAlternateTextTrackNum;
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const int len = strlen(str);
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK_EQ(len, 32);
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const uint8* const buf = reinterpret_cast<const uint8*>(str);
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      text_track_entry = DecoderBuffer::CopyFrom(buf, len);
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      tracks_element_size += text_track_entry->data_size();
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *size = ebml_header->data_size() + info->data_size() +
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kTracksHeaderSize + tracks_element_size;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer->reset(new uint8[*size]);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* buf = buffer->get();
275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    memcpy(buf, ebml_header->data(), ebml_header->data_size());
276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    buf += ebml_header->data_size();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    memcpy(buf, info->data(), info->data_size());
279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    buf += info->data_size();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(buf, kTracksHeader, kTracksHeaderSize);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteInt64(buf + kTracksSizeOffset, tracks_element_size);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf += kTracksHeaderSize;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(xhwang): Simplify this! Probably have test data files that contain
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ContentEncodings directly instead of trying to create one at run-time.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      memcpy(buf, audio_track_entry->data(),
289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch             audio_track_entry->data_size());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_audio_encrypted) {
291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        memcpy(buf + audio_track_entry->data_size(),
292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               audio_content_encodings->data(),
293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               audio_content_encodings->data_size());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WriteInt64(buf + kAudioTrackSizeOffset,
295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   audio_track_entry->data_size() +
296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   audio_content_encodings->data_size() -
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   kAudioTrackEntryHeaderSize);
298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        buf += audio_content_encodings->data_size();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      buf += audio_track_entry->data_size();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
304ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      memcpy(buf, video_track_entry->data(),
305ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch             video_track_entry->data_size());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_video_encrypted) {
307ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        memcpy(buf + video_track_entry->data_size(),
308ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               video_content_encodings->data(),
309ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch               video_content_encodings->data_size());
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WriteInt64(buf + kVideoTrackSizeOffset,
311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   video_track_entry->data_size() +
312ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                   video_content_encodings->data_size() -
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   kVideoTrackEntryHeaderSize);
314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        buf += video_content_encodings->data_size();
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      buf += video_track_entry->data_size();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_text) {
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      memcpy(buf, text_track_entry->data(),
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             text_track_entry->data_size());
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      buf += text_track_entry->data_size();
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChunkDemuxer::Status AddId() {
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ChunkDemuxer::Status AddId(const std::string& source_id, int stream_flags) {
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool has_audio = (stream_flags & HAS_AUDIO) != 0;
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool has_video = (stream_flags & HAS_VIDEO) != 0;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> codecs;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string type;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      codecs.push_back("vorbis");
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = "audio/webm";
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      codecs.push_back("vp8");
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = "video/webm";
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!has_audio && !has_video) {
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return demuxer_->AddId(source_id, type, codecs);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
353010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ChunkDemuxer::Status AddIdForMp2tSource(const std::string& source_id) {
354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    std::vector<std::string> codecs;
355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    std::string type = "video/mp2t";
356010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    codecs.push_back("mp4a.40.2");
357010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    codecs.push_back("avc1.640028");
3586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return demuxer_->AddId(source_id, type, codecs);
359010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
360010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendData(const uint8* data, size_t length) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(kSourceId, data, length);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void AppendCluster(const std::string& source_id,
366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                     scoped_ptr<Cluster> cluster) {
367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendData(source_id, cluster->data(), cluster->size());
368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void AppendCluster(scoped_ptr<Cluster> cluster) {
371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(kSourceId, cluster.Pass());
372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendCluster(int timecode, int block_count) {
375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(GenerateCluster(timecode, block_count));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void AppendSingleStreamCluster(const std::string& source_id, int track_number,
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 int timecode, int block_count) {
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int block_duration = 0;
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (track_number) {
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      case kVideoTrackNum:
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        block_duration = kVideoBlockDuration;
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        break;
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      case kAudioTrackNum:
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        block_duration = kAudioBlockDuration;
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        break;
388f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      case kTextTrackNum:  // Fall-through.
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      case kAlternateTextTrackNum:
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        block_duration = kTextBlockDuration;
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_NE(block_duration, 0);
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int end_timecode = timecode + block_count * block_duration;
395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(source_id,
396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                  GenerateSingleStreamCluster(
397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                      timecode, end_timecode, track_number, block_duration));
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |cluster_description| - A space delimited string of buffer info that
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  is used to construct a cluster. Each buffer info is a timestamp in
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  milliseconds and optionally followed by a 'K' to indicate that a buffer
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  should be marked as a keyframe. For example "0K 30 60" should constuct
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  a cluster with 3 blocks: a keyframe with timestamp 0 and 2 non-keyframes
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //  at 30ms and 60ms.
406558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void AppendSingleStreamCluster(const std::string& source_id, int track_number,
407558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                 const std::string& cluster_description) {
408558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::vector<std::string> timestamps;
409558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    base::SplitString(cluster_description, ' ', &timestamps);
410558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
411558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ClusterBuilder cb;
412558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::vector<uint8> data(10);
413558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (size_t i = 0; i < timestamps.size(); ++i) {
414558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      std::string timestamp_str = timestamps[i];
415558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      int block_flags = 0;
416558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (EndsWith(timestamp_str, "K", true)) {
417558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        block_flags = kWebMFlagKeyframe;
418558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        // Remove the "K" off of the token.
419558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1);
420558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
421558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      int timestamp_in_ms;
422558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      CHECK(base::StringToInt(timestamp_str, &timestamp_in_ms));
423558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
424558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (i == 0)
425558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        cb.SetClusterTimecode(timestamp_in_ms);
426558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
427f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (track_number == kTextTrackNum ||
428f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          track_number == kAlternateTextTrackNum) {
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        cb.AddBlockGroup(track_number, timestamp_in_ms, kTextBlockDuration,
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         block_flags, &data[0], data.size());
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      } else {
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags,
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          &data[0], data.size());
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
435558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(source_id, cb.Finish());
437558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendData(const std::string& source_id,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const uint8* data, size_t length) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber());
442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    demuxer_->AppendData(source_id, data, length,
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         append_window_start_for_next_append_,
445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         append_window_end_for_next_append_,
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         &timestamp_offset_map_[source_id]);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendDataInPieces(const uint8* data, size_t length) {
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendDataInPieces(data, length, 7);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* start = data;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8* end = data + length;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (start < end) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t append_size = std::min(piece_size,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    static_cast<size_t>(end - start));
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AppendData(start, append_size);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      start += append_size;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AppendInitSegment(int stream_flags) {
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AppendInitSegmentWithSourceId(kSourceId, stream_flags);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendInitSegmentWithSourceId(const std::string& source_id,
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     int stream_flags) {
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AppendInitSegmentWithEncryptedInfo(source_id, stream_flags, false, false);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendInitSegmentWithEncryptedInfo(const std::string& source_id,
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          int stream_flags,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bool is_audio_encrypted,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bool is_video_encrypted) {
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> info_tracks;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int info_tracks_size = 0;
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CreateInitSegment(stream_flags,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      is_audio_encrypted, is_video_encrypted,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &info_tracks, &info_tracks_size);
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(source_id, info_tracks.get(), info_tracks_size);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendGarbage() {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fill up an array with gibberish.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int garbage_cluster_size = 10;
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> garbage_cluster(new uint8[garbage_cluster_size]);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < garbage_cluster_size; ++i)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      garbage_cluster[i] = i;
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(garbage_cluster.get(), garbage_cluster_size);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitDoneCalled(PipelineStatus expected_status,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      PipelineStatus status) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(status, expected_status);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendEmptyCluster(int timecode) {
500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    AppendCluster(GenerateEmptyCluster(timecode));
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    PipelineStatus expected_status) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected_duration != kNoTimestamp())
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_CALL(host_, SetDuration(expected_duration));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CreateInitDoneCB(expected_status);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::Bind(&ChunkDemuxerTest::InitDoneCalled,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(this),
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      expected_status);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  enum StreamFlags {
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HAS_AUDIO = 1 << 0,
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HAS_VIDEO = 1 << 1,
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HAS_TEXT = 1 << 2
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool InitDemuxer(int stream_flags) {
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return InitDemuxerWithEncryptionInfo(stream_flags, false, false);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitDemuxerWithEncryptionInfo(
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int stream_flags, bool is_audio_encrypted, bool is_video_encrypted) {
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PipelineStatus expected_status =
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        (stream_flags != 0) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta expected_duration = kNoTimestamp();
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected_status == PIPELINE_OK)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_duration = kDefaultDuration();
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &host_, CreateInitDoneCB(expected_duration, expected_status), true);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendInitSegmentWithEncryptedInfo(
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        kSourceId, stream_flags,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_audio_encrypted, is_video_encrypted);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool InitDemuxerAudioAndVideoSourcesText(const std::string& audio_id,
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                           const std::string& video_id,
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                           bool has_text) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (AddId(audio_id, HAS_AUDIO) != ChunkDemuxer::kOk)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (AddId(video_id, HAS_VIDEO) != ChunkDemuxer::kOk)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int audio_flags = HAS_AUDIO;
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int video_flags = HAS_VIDEO;
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (has_text) {
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      audio_flags |= HAS_TEXT;
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      video_flags |= HAS_TEXT;
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AppendInitSegmentWithSourceId(audio_id, audio_flags);
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AppendInitSegmentWithSourceId(video_id, video_flags);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool InitDemuxerAudioAndVideoSources(const std::string& audio_id,
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       const std::string& video_id) {
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, false);
577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the demuxer with data from 2 files with different
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // decoder configurations. This is used to test the decoder config change
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // logic.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-320x240.webm VideoDecoderConfig returns 320x240 for its natural_size()
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm VideoDecoderConfig returns 640x360 for its natural_size()
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The resulting video stream returns data from each file for the following
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time ranges.
587effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // bear-320x240.webm : [0-501)       [801-2736)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm :       [527-793)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-320x240.webm AudioDecoderConfig returns 3863 for its extra_data_size()
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm AudioDecoderConfig returns 3935 for its extra_data_size()
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The resulting audio stream returns data from each file for the following
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // time ranges.
594effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // bear-320x240.webm : [0-524)       [779-2736)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bear-640x360.webm :       [527-759)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitDemuxerWithConfigChangeData() {
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> bear1 = ReadTestDataFile("bear-320x240.webm");
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> bear2 = ReadTestDataFile("bear-640x360.webm");
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
601e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &host_, CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744),
604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 PIPELINE_OK), true);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (AddId(kSourceId, HAS_AUDIO | HAS_VIDEO) != ChunkDemuxer::kOk)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append the whole bear1 file.
610e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // TODO(wolenetz/acolwell): Remove this extra SetDuration expectation once
611e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // the files are fixed to have the correct duration in their init segments,
612e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // and the CreateInitDoneCB() call, above, is fixed to used that duration.
613e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // See http://crbug.com/354284.
6140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2746)));
615ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear1->data(), bear1->data_size());
616effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Last audio frame has timestamp 2721 and duration 24 (estimated from max
617effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // seen so far for audio track).
618effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Last video frame has timestamp 2703 and duration 33 (from TrackEntry
619effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // DefaultDuration for video track).
620effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CheckExpectedRanges(kSourceId, "{ [0,2736) }");
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append initialization segment for bear2.
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: Offsets here and below are derived from
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // media/test/data/bear-640x360-manifest.js and
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // media/test/data/bear-320x240-manifest.js which were
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // generated from media/test/data/bear-640x360.webm and
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // media/test/data/bear-320x240.webm respectively.
628ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear2->data(), 4340);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append a media segment that goes from [0.527000, 1.014000).
631ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear2->data() + 55290, 18785);
632effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CheckExpectedRanges(kSourceId, "{ [0,1027) [1201,2736) }");
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Append initialization segment for bear1 & fill gap with [779-1197)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // segment.
636ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear1->data(), 4370);
637ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendData(bear1->data() + 72737, 28183);
638effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CheckExpectedRanges(kSourceId, "{ [0,2736) }");
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
640ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    MarkEndOfStream(PIPELINE_OK);
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return true;
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShutdownDemuxer() {
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (demuxer_) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      demuxer_->Shutdown();
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      message_loop_.RunUntilIdle();
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 data[] = { 0x00 };
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GenerateCluster(timecode, timecode, block_count);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddVideoBlockGroup(ClusterBuilder* cb, int track_num, int64 timecode,
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          int duration, int flags) {
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const uint8* data =
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (flags & kWebMFlagKeyframe) != 0 ? kVP8Keyframe : kVP8Interframe;
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int size = (flags & kWebMFlagKeyframe) != 0 ? sizeof(kVP8Keyframe) :
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        sizeof(kVP8Interframe);
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cb->AddBlockGroup(track_num, timecode, duration, flags, data, size);
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode,
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int first_video_timecode,
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int block_count) {
672f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return GenerateCluster(first_audio_timecode, first_video_timecode,
673f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           block_count, false);
674f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode,
676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      int first_video_timecode,
677f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      int block_count,
678f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      bool unknown_size) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(block_count, 0);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size = 10;
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<uint8[]> data(new uint8[size]);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClusterBuilder cb;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb.SetClusterTimecode(std::min(first_audio_timecode, first_video_timecode));
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (block_count == 1) {
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddBlockGroup(kAudioTrackNum, first_audio_timecode,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kAudioBlockDuration, kWebMFlagKeyframe,
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       data.get(), size);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return cb.Finish();
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int audio_timecode = first_audio_timecode;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int video_timecode = first_video_timecode;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create simple blocks for everything except the last 2 blocks.
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first video frame must be a keyframe.
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 video_flag = kWebMFlagKeyframe;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < block_count - 2; i++) {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (audio_timecode <= video_timecode) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cb.AddSimpleBlock(kAudioTrackNum, audio_timecode, kWebMFlagKeyframe,
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          data.get(), size);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_timecode += kAudioBlockDuration;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddSimpleBlock(kVideoTrackNum, video_timecode, video_flag, data.get(),
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        size);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_timecode += kVideoBlockDuration;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_flag = 0;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make the last 2 blocks BlockGroups so that they don't get delayed by the
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // block duration calculation logic.
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (audio_timecode <= video_timecode) {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration,
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kWebMFlagKeyframe, data.get(), size);
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode,
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         kVideoBlockDuration, video_flag);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode,
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         kVideoBlockDuration, video_flag);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       kWebMFlagKeyframe, data.get(), size);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
728f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish();
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int end_timecode,
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int track_number,
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int block_duration) {
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(end_timecode, timecode);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<uint8> data(kBlockSize);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClusterBuilder cb;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb.SetClusterTimecode(timecode);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create simple blocks for everything except the last block.
743e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    while (timecode < (end_timecode - block_duration)) {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe,
745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        &data[0], data.size());
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      timecode += block_duration;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (track_number == kVideoTrackNum) {
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddVideoBlockGroup(&cb, track_number, timecode, block_duration,
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         kWebMFlagKeyframe);
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cb.AddBlockGroup(track_number, timecode, block_duration,
754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       kWebMFlagKeyframe, &data[0], data.size());
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
756e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cb.Finish();
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Read(DemuxerStream::Type type, const DemuxerStream::ReadCB& read_cb) {
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(read_cb);
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReadAudio(const DemuxerStream::ReadCB& read_cb) {
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Read(DemuxerStream::AUDIO, read_cb);
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReadVideo(const DemuxerStream::ReadCB& read_cb) {
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Read(DemuxerStream::VIDEO, read_cb);
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateExpectedReads(int timecode, int block_count) {
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GenerateExpectedReads(timecode, timecode, block_count);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GenerateExpectedReads(int start_audio_timecode,
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int start_video_timecode,
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             int block_count) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(block_count, 0);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (block_count == 1) {
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExpectRead(DemuxerStream::AUDIO, start_audio_timecode);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int audio_timecode = start_audio_timecode;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int video_timecode = start_video_timecode;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < block_count; i++) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (audio_timecode <= video_timecode) {
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ExpectRead(DemuxerStream::AUDIO, audio_timecode);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_timecode += kAudioBlockDuration;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExpectRead(DemuxerStream::VIDEO, video_timecode);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_timecode += kVideoBlockDuration;
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateSingleStreamExpectedReads(int timecode,
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         int block_count,
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         DemuxerStream::Type type,
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         int block_duration) {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GT(block_count, 0);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int stream_timecode = timecode;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < block_count; i++) {
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExpectRead(type, stream_timecode);
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stream_timecode += block_duration;
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateAudioStreamExpectedReads(int timecode, int block_count) {
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GenerateSingleStreamExpectedReads(
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timecode, block_count, DemuxerStream::AUDIO, kAudioBlockDuration);
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GenerateVideoStreamExpectedReads(int timecode, int block_count) {
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GenerateSingleStreamExpectedReads(
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timecode, block_count, DemuxerStream::VIDEO, kVideoBlockDuration);
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> GenerateEmptyCluster(int timecode) {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClusterBuilder cb;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cb.SetClusterTimecode(timecode);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cb.Finish();
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckExpectedRanges(const std::string& expected) {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckExpectedRanges(kSourceId, expected);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckExpectedRanges(const std::string&  id,
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& expected) {
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Ranges<base::TimeDelta> r = demuxer_->GetBufferedRanges(id);
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::stringstream ss;
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << "{ ";
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < r.size(); ++i) {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ss << "[" << r.start(i).InMilliseconds() << ","
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         << r.end(i).InMilliseconds() << ") ";
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << "}";
8465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(expected, ss.str());
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(ReadDone, void(DemuxerStream::Status status,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const scoped_refptr<DecoderBuffer>&));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StoreStatusAndBuffer(DemuxerStream::Status* status_out,
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            scoped_refptr<DecoderBuffer>* buffer_out,
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            DemuxerStream::Status status,
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const scoped_refptr<DecoderBuffer>& buffer) {
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *status_out = status;
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *buffer_out = buffer;
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReadUntilNotOkOrEndOfStream(DemuxerStream::Type type,
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   DemuxerStream::Status* status,
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   base::TimeDelta* last_timestamp) {
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* stream = demuxer_->GetStream(type);
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<DecoderBuffer> buffer;
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *last_timestamp = kNoTimestamp();
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    do {
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              base::Unretained(this), status, &buffer));
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop::current()->RunUntilIdle();
871ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (*status == DemuxerStream::kOk && !buffer->end_of_stream())
872ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *last_timestamp = buffer->timestamp();
873ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    } while (*status == DemuxerStream::kOk && !buffer->end_of_stream());
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ExpectEndOfStream(DemuxerStream::Type type) {
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, IsEndOfStream()));
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(base::Bind(
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ExpectRead(DemuxerStream::Type type, int64 timestamp_in_ms) {
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                HasTimestamp(timestamp_in_ms)));
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(base::Bind(
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ExpectConfigChanged(DemuxerStream::Type type) {
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_->GetStream(type)->Read(base::Bind(
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.RunUntilIdle();
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
898558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void CheckExpectedBuffers(DemuxerStream* stream,
899558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                            const std::string& expected) {
900558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::vector<std::string> timestamps;
901558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    base::SplitString(expected, ' ', &timestamps);
902558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    std::stringstream ss;
903558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (size_t i = 0; i < timestamps.size(); ++i) {
90446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // Initialize status to kAborted since it's possible for Read() to return
90546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // without calling StoreStatusAndBuffer() if it doesn't have any buffers
90646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // left to return.
90746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      DemuxerStream::Status status = DemuxerStream::kAborted;
908558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      scoped_refptr<DecoderBuffer> buffer;
909558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
910558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                              base::Unretained(this), &status, &buffer));
911558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::MessageLoop::current()->RunUntilIdle();
912558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (status != DemuxerStream::kOk || buffer->end_of_stream())
913558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        break;
914558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
915558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (i > 0)
916558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        ss << " ";
917558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      ss << buffer->timestamp().InMilliseconds();
91846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
91946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // Handle preroll buffers.
92046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      if (EndsWith(timestamps[i], "P", true)) {
92146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ASSERT_EQ(kInfiniteDuration(), buffer->discard_padding().first);
92246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ASSERT_EQ(base::TimeDelta(), buffer->discard_padding().second);
92346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ss << "P";
92446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
925558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
926558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_EQ(expected, ss.str());
927558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
928558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(Checkpoint, void(int id));
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps {
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int video_time_ms;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int audio_time_ms;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kSkip = -1;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test parsing a WebM file.
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |filename| - The name of the file in media/test/data to parse.
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |timestamps| - The expected timestamps on the parsed buffers.
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    a timestamp of kSkip indicates that a Read() call for that stream
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    shouldn't be made on that iteration of the loop. If both streams have
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    a kSkip then the loop will terminate.
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ParseWebMFile(const std::string& filename,
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const BufferTimestamps* timestamps,
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const base::TimeDelta& duration) {
9465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return ParseWebMFile(filename, timestamps, duration, HAS_AUDIO | HAS_VIDEO);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ParseWebMFile(const std::string& filename,
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const BufferTimestamps* timestamps,
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const base::TimeDelta& duration,
9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     int stream_flags) {
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*this, DemuxerOpened());
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    demuxer_->Initialize(
955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &host_, CreateInitDoneCB(duration, PIPELINE_OK), true);
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (AddId(kSourceId, stream_flags) != ChunkDemuxer::kOk)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read a WebM file into memory and send the data to the demuxer.
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
962ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    AppendDataInPieces(buffer->data(), buffer->data_size(), 512);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that the timestamps on the first few packets match what we
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // expect.
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0;
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (timestamps[i].audio_time_ms != kSkip ||
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          timestamps[i].video_time_ms != kSkip);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i++) {
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool audio_read_done = false;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool video_read_done = false;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (timestamps[i].audio_time_ms != kSkip) {
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ReadAudio(base::Bind(&OnReadDone,
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::TimeDelta::FromMilliseconds(
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 timestamps[i].audio_time_ms),
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &audio_read_done));
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(audio_read_done);
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (timestamps[i].video_time_ms != kSkip) {
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ReadVideo(base::Bind(&OnReadDone,
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::TimeDelta::FromMilliseconds(
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 timestamps[i].video_time_ms),
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &video_read_done));
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(video_read_done);
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD0(DemuxerOpened, void());
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(xhwang): This is a workaround of the issue that move-only parameters
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are not supported in mocked methods. Remove this when the issue is fixed
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689).
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD3(NeedKeyMock, void(const std::string& type,
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const uint8* init_data, int init_data_size));
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DemuxerNeedKey(const std::string& type,
1001424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                      const std::vector<uint8>& init_data) {
1002424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
1003424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    NeedKeyMock(type, init_data_ptr, init_data.size());
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Seek(base::TimeDelta seek_time) {
1007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    demuxer_->StartWaitingForSeek(seek_time);
1008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
1009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_loop_.RunUntilIdle();
1010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1012ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void MarkEndOfStream(PipelineStatus status) {
1013ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    demuxer_->MarkEndOfStream(status);
1014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_loop_.RunUntilIdle();
1015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1017a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool SetTimestampOffset(const std::string& id,
1018a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                          base::TimeDelta timestamp_offset) {
1019a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (demuxer_->IsParsingMediaSegment(id))
1020a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
1021a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1022a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    timestamp_offset_map_[id] = timestamp_offset;
1023a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return true;
1024a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1025a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockDemuxerHost host_;
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ChunkDemuxer> demuxer_;
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1031a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TimeDelta append_window_start_for_next_append_;
1032a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TimeDelta append_window_end_for_next_append_;
1033a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1034a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Map of source id to timestamp offset to use for the next AppendData()
1035a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // operation for that source id.
1036a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::map<std::string, base::TimeDelta> timestamp_offset_map_;
1037a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest);
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Init) {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test no streams, audio-only, video-only, and audio & video scenarios.
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio and video streams can be encrypted or not encrypted.
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 16; i++) {
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_audio = (i & 0x1) != 0;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_video = (i & 0x2) != 0;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_audio_encrypted = (i & 0x4) != 0;
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_video_encrypted = (i & 0x8) != 0;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No test on invalid combination.
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((!has_audio && is_audio_encrypted) ||
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (!has_video && is_video_encrypted)) {
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateNewDemuxer();
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_audio_encrypted || is_video_encrypted) {
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int need_key_count = (is_audio_encrypted ? 1 : 0) +
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           (is_video_encrypted ? 1 : 0);
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(*this, NeedKeyMock(kWebMEncryptInitDataType, NotNull(),
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     DecryptConfig::kDecryptionKeySize))
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Times(Exactly(need_key_count));
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int stream_flags = 0;
10685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (has_audio)
10695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stream_flags |= HAS_AUDIO;
10705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (has_video)
10725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stream_flags |= HAS_VIDEO;
10735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
10755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        stream_flags, is_audio_encrypted, is_video_encrypted));
1076f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1077f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
1078f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_audio) {
1079f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ASSERT_TRUE(audio_stream);
1080f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1081f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
1082f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(kCodecVorbis, config.codec());
1083f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(32, config.bits_per_channel());
1084f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout());
1085f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(44100, config.samples_per_second());
1086f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_TRUE(config.extra_data());
1087f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_GT(config.extra_data_size(), 0u);
1088f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
1089f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(is_audio_encrypted,
1090f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                audio_stream->audio_decoder_config().is_encrypted());
1091010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      EXPECT_TRUE(static_cast<ChunkDemuxerStream*>(audio_stream)
1092010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                      ->supports_partial_append_window_trimming());
1093f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
1094f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_FALSE(audio_stream);
1095f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1096f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1097f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
1098f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (has_video) {
1099f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_TRUE(video_stream);
1100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(is_video_encrypted,
1101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                video_stream->video_decoder_config().is_encrypted());
1102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      EXPECT_FALSE(static_cast<ChunkDemuxerStream*>(video_stream)
1103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                       ->supports_partial_append_window_trimming());
1104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
1105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_FALSE(video_stream);
1106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ShutdownDemuxer();
1109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    demuxer_.reset();
1110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(acolwell): Fold this test into Init tests since the tests are
11145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// almost identical.
11156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, InitText) {
1116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Test with 1 video stream and 1 text streams, and 0 or 1 audio streams.
1117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // No encryption cases handled here.
1118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool has_video = true;
1119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_audio_encrypted = false;
1120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_video_encrypted = false;
1121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
1122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool has_audio = (i & 0x1) != 0;
1123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CreateNewDemuxer();
1125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DemuxerStream* text_stream = NULL;
1127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TextTrackConfig text_config;
11285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(host_, AddTextStream(_, _))
1129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        .WillOnce(DoAll(SaveArg<0>(&text_stream),
1130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SaveArg<1>(&text_config)));
1131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int stream_flags = HAS_TEXT;
11335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (has_audio)
11345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stream_flags |= HAS_AUDIO;
11355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (has_video)
11375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stream_flags |= HAS_VIDEO;
11385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
11405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        stream_flags, is_audio_encrypted, is_video_encrypted));
1141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(text_stream);
1142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
1143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(kTextSubtitles, text_config.kind());
1144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_FALSE(static_cast<ChunkDemuxerStream*>(text_stream)
1145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     ->supports_partial_append_window_trimming());
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_audio) {
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(audio_stream);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const AudioDecoderConfig& config = audio_stream->audio_decoder_config();
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(kCodecVorbis, config.codec());
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(32, config.bits_per_channel());
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(CHANNEL_LAYOUT_STEREO, config.channel_layout());
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(44100, config.samples_per_second());
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(config.extra_data());
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_GT(config.extra_data_size(), 0u);
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(is_audio_encrypted,
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                audio_stream->audio_decoder_config().is_encrypted());
1161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      EXPECT_TRUE(static_cast<ChunkDemuxerStream*>(audio_stream)
1162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                      ->supports_partial_append_window_trimming());
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(audio_stream);
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (has_video) {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(video_stream);
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(is_video_encrypted,
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                video_stream->video_decoder_config().is_encrypted());
1172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      EXPECT_FALSE(static_cast<ChunkDemuxerStream*>(video_stream)
1173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                       ->supports_partial_append_window_trimming());
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(video_stream);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShutdownDemuxer();
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    demuxer_.reset();
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SingleTextTrackIdChange) {
1184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Test with 1 video stream, 1 audio, and 1 text stream. Send a second init
1185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // segment in which the text track ID changes. Verify appended buffers before
1186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // and after the second init segment map to the same underlying track buffers.
1187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CreateNewDemuxer();
1188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DemuxerStream* text_stream = NULL;
1189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TextTrackConfig text_config;
1190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
1191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(DoAll(SaveArg<0>(&text_stream),
1192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      SaveArg<1>(&text_config)));
1193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
1194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      HAS_TEXT | HAS_AUDIO | HAS_VIDEO, false, false));
1195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
1196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
1197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(audio_stream);
1198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(video_stream);
1199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(text_stream);
1200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23K");
1202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 30");
1203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "10K");
1204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,46) }");
1205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<uint8[]> info_tracks;
1207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int info_tracks_size = 0;
1208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CreateInitSegmentWithAlternateTextTrackNum(HAS_TEXT | HAS_AUDIO | HAS_VIDEO,
1209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             false, false,
1210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             &info_tracks, &info_tracks_size);
1211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size,
1212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       append_window_start_for_next_append_,
1213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       append_window_end_for_next_append_,
1214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       &timestamp_offset_map_[kSourceId]);
1215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "46K 69K");
1217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "60K");
1218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAlternateTextTrackNum, "45K");
1219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,92) }");
1221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedBuffers(audio_stream, "0 23 46 69");
1222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedBuffers(video_stream, "0 30 60");
1223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedBuffers(text_stream, "10 45");
1224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ShutdownDemuxer();
1226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
12286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, InitSegmentSetsNeedRandomAccessPointFlag) {
1229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Tests that non-keyframes following an init segment are allowed
1230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // and dropped, as expected if the initialization segment received
1231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // algorithm correctly sets the needs random access point flag to true for all
1232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // track buffers. Note that the first initialization segment is insufficient
1233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // to fully test this since needs random access point flag initializes to
1234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // true.
1235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CreateNewDemuxer();
1236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DemuxerStream* text_stream = NULL;
1237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
1238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
1239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithEncryptionInfo(
1240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      HAS_TEXT | HAS_AUDIO | HAS_VIDEO, false, false));
1241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
1242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
1243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(audio_stream && video_stream && text_stream);
1244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0 23K");
1246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0 30K");
1247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0 40K");
1248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [30,46) }");
1249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendInitSegment(HAS_TEXT | HAS_AUDIO | HAS_VIDEO);
1251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "46 69K");
1252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "60 90K");
1253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "80 90K");
1254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [30,92) }");
1255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedBuffers(audio_stream, "23 69");
1257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedBuffers(video_stream, "30 90");
1258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // WebM parser marks all text buffers as keyframes.
1260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedBuffers(text_stream, "0 40 80 90");
1261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that the demuxer reports an error if Shutdown()
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is called before all the initialization segments are appended.
12656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) {
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(
1269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegmentWithSourceId("audio", HAS_AUDIO);
12755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShutdownDemuxer();
1277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) {
1280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
1281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Initialize(
1282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(
1283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
1284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
12865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(AddId("video_and_text", HAS_VIDEO), ChunkDemuxer::kOk);
1287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
1289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .Times(Exactly(1));
1290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegmentWithSourceId("video_and_text", HAS_VIDEO | HAS_TEXT);
12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShutdownDemuxer();
12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verifies that all streams waiting for data receive an end of stream
12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// buffer when Shutdown() is called.
12986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Shutdown_EndOfStreamWhileWaitingForData) {
12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* text_stream = NULL;
13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
13035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
13055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
13065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool audio_read_done = false;
13085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool video_read_done = false;
13095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool text_read_done = false;
13105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  audio_stream->Read(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  video_stream->Read(base::Bind(&OnReadDone_EOSExpected, &video_read_done));
13125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  text_stream->Read(base::Bind(&OnReadDone_EOSExpected, &text_read_done));
13135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_loop_.RunUntilIdle();
13145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
13165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
13175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(text_read_done);
13185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShutdownDemuxer();
13205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
13225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(text_read_done);
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Seek() completes successfully when the first cluster
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arrives.
13286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendDataAfterSeek) {
13295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, Checkpoint(1));
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(46));
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, Checkpoint(2));
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Checkpoint(1);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Checkpoint(2);
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that parsing errors are handled for clusters appended after init.
13506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) {
13515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendGarbage();
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case where a Seek() is requested while the parser
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is in the middle of cluster. This is to verify that the parser
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// does not reset itself on a seek.
13616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) {
13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 6));
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Split the cluster into two appends at an arbitrary point near the end.
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int first_append_size = cluster_a->size() - 11;
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int second_append_size = cluster_a->size() - first_append_size;
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the first part of the cluster.
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(cluster_a->data(), first_append_size);
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, kAudioBlockDuration);
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(5));
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the rest of the cluster.
1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendData(cluster_a->data() + first_append_size, second_append_size);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the new cluster and verify that only the blocks
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the new cluster are returned.
1386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(5000, 6));
1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(5000, 6);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case where AppendData() is called before Init().
13916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) {
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> info_tracks;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int info_tracks_size = 0;
13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateInitSegment(HAS_AUDIO | HAS_VIDEO,
1395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    false, false, &info_tracks, &info_tracks_size);
1396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size,
1397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_start_for_next_append_,
1398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_end_for_next_append_,
1399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       &timestamp_offset_map_[kSourceId]);
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure Read() callbacks are dispatched with the proper data.
14036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Read) {
14045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, OutOfOrderClusters) {
14225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
1424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(10, 4));
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Make sure that AppendCluster() does not fail with a cluster that has
1427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // overlaps with the previously appended cluster.
1428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(5, 4));
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that AppendData() can still accept more data.
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2));
1432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  demuxer_->AppendData(kSourceId, cluster_c->data(), cluster_c->size(),
1433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_start_for_next_append_,
1434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_end_for_next_append_,
1435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       &timestamp_offset_map_[kSourceId]);
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) {
14395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClusterBuilder cb;
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the case where block timecodes are not monotonically
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // increasing but stay above the cluster timecode.
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cb.SetClusterTimecode(5);
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 5);
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 10);
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 7);
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 15);
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(cb.Finish());
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that AppendData() ignores data after the error.
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2));
1457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(),
1458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_start_for_next_append_,
1459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_end_for_next_append_,
1460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       &timestamp_offset_map_[kSourceId]);
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) {
14645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClusterBuilder cb;
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test timecodes going backwards and including values less than the cluster
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // timecode.
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cb.SetClusterTimecode(5);
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 5);
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 5);
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 3);
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 3);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(cb.Finish());
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that AppendData() ignores data after the error.
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2));
1482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(),
1483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_start_for_next_append_,
1484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_end_for_next_append_,
1485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       &timestamp_offset_map_[kSourceId]);
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) {
14905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
1491a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClusterBuilder cb;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test monotonic increasing timestamps on a per stream
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // basis.
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cb.SetClusterTimecode(5);
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 5);
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 5);
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kAudioTrackNum, 4);
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddSimpleBlock(&cb, kVideoTrackNum, 7);
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(cb.Finish());
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Test the case where a cluster is passed to AppendCluster() before
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// INFO & TRACKS data.
15096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ClusterBeforeInitSegment) {
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1516a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 1));
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1519ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test cases where we get an MarkEndOfStream() call during initialization.
15206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EOSDuringInit) {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
1524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWithNoAppend) {
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
1535ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShutdownDemuxer();
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->RemoveId(kSourceId);
1539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  demuxer_.reset();
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWithNoMediaAppend) {
15435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
1546ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ }");
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DecodeErrorEndOfStream) {
15515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1553a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kDefaultFirstClusterRange);
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
1557ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_ERROR_DECODE);
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kDefaultFirstClusterRange);
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, NetworkErrorEndOfStream) {
15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kDefaultFirstClusterRange);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK));
1568ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_ERROR_NETWORK);
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class to reduce duplicate code when testing end of stream
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Read() behavior.
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EndOfStreamHelper {
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit EndOfStreamHelper(Demuxer* demuxer)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : demuxer_(demuxer),
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_read_done_(false),
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        video_read_done_(false) {
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request a read on the audio and video streams.
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RequestReads() {
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(audio_read_done_);
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(video_read_done_);
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
1587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    audio->Read(base::Bind(&OnEndOfStreamReadDone, &audio_read_done_));
1590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    video->Read(base::Bind(&OnEndOfStreamReadDone, &video_read_done_));
1591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see if |audio_read_done_| and |video_read_done_| variables
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // match |expected|.
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIfReadDonesWereCalled(bool expected) {
1597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::MessageLoop::current()->RunUntilIdle();
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected, audio_read_done_);
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected, video_read_done_);
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void OnEndOfStreamReadDone(
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool* called,
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DemuxerStream::Status status,
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<DecoderBuffer>& buffer) {
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(status, DemuxerStream::kOk);
1608ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(buffer->end_of_stream());
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *called = true;
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Demuxer* demuxer_;
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done_;
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done_;
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EndOfStreamHelper);
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that all pending reads that we don't have media data for get an
1620ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// "end of stream" buffer when MarkEndOfStream() is called.
16216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWithPendingReads) {
16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done_1 = false;
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done_1 = false;
1628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
1629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done_1));
1634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done_1));
1637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done_1);
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done_1);
1641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  end_of_stream_helper_1.RequestReads();
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kVideoBlockDuration)));
1646ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
1649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  end_of_stream_helper_2.RequestReads();
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1654ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Make sure that all Read() calls after we get an MarkEndOfStream()
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call return an "end of stream" buffer.
16566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ReadsAfterEndOfStream) {
16575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1659a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done_1 = false;
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done_1 = false;
1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
1665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper_3(demuxer_.get());
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done_1));
1670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done_1));
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.RequestReads();
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done_1);
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done_1);
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.CheckIfReadDonesWereCalled(false);
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kVideoBlockDuration)));
1682ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_1.CheckIfReadDonesWereCalled(true);
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request a few more reads and make sure we immediately get
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // end of stream buffers.
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_2.RequestReads();
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_2.CheckIfReadDonesWereCalled(true);
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_3.RequestReads();
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper_3.CheckIfReadDonesWereCalled(true);
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamDuringCanceledSeek) {
16965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendCluster(0, 10);
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(138)));
1700ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first seek.
1703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(20));
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate another seek being requested before the first
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // seek has finished prerolling.
1707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(30);
1708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time2);
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finish second seek.
1711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time2);
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DemuxerStream::Status status;
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta last_timestamp;
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure audio can reach end of stream.
1717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure video can reach end of stream.
1721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify buffered range change behavior for audio/video/text tracks.
17266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamRangeChanges) {
17275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* text_stream = NULL;
17285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
17305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
17315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
17325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1733e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 33");
17345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23K");
17355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check expected ranges and verify that an empty text track does not
17375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // affect the expected ranges.
17385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,46) }");
17395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1740e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(66)));
17415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MarkEndOfStream(PIPELINE_OK);
17425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check expected ranges and verify that an empty text track does not
17445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // affect the expected ranges.
1745e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [0,66) }");
17465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Unmark end of stream state and verify that the ranges return to
17485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // their pre-"end of stream" values.
17495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  demuxer_->UnmarkEndOfStream();
17505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,46) }");
17515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Add text track data and verify that the buffered ranges don't change
17535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // since the intersection of all the tracks doesn't change.
17545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(200)));
17555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K");
17565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,46) }");
17575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Mark end of stream and verify that text track data is reflected in
17595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the new range.
17605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MarkEndOfStream(PIPELINE_OK);
17615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,200) }");
17625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure AppendData() will accept elements that span multiple calls.
17656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendingInPieces) {
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
1768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> info_tracks;
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int info_tracks_size = 0;
17745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateInitSegment(HAS_AUDIO | HAS_VIDEO,
1775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    false, false, &info_tracks, &info_tracks_size);
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_a(kDefaultFirstCluster());
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster_b(kDefaultSecondCluster());
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size();
1781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> buffer(new uint8[buffer_size]);
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8* dst = buffer.get();
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, info_tracks.get(), info_tracks_size);
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dst += info_tracks_size;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, cluster_a->data(), cluster_a->size());
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dst += cluster_a->size();
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, cluster_b->data(), cluster_b->size());
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dst += cluster_b->size();
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendDataInPieces(buffer.get(), buffer_size);
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 9);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_AudioAndVideo) {
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, 0},
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 3},
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, 6},
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, 9},
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {133, 12},
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1807e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // TODO(wolenetz/acolwell): Remove this SetDuration expectation and update the
1808e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // ParseWebMFile() call's expected duration, below, once the file is fixed to
1809e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // have the correct duration in the init segment. See http://crbug.com/354284.
18100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2746)));
1811e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240.webm", buffer_timestamps,
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2744)));
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_LiveAudioAndVideo) {
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, 0},
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 3},
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, 6},
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, 9},
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {133, 12},
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-live.webm", buffer_timestamps,
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kInfiniteDuration()));
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_AudioOnly) {
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 0},
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 3},
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 6},
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 9},
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, 12},
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1840e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // TODO(wolenetz/acolwell): Remove this SetDuration expectation and update the
1841e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // ParseWebMFile() call's expected duration, below, once the file is fixed to
1842e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // have the correct duration in the init segment. See http://crbug.com/354284.
18430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2746)));
1844e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-audio-only.webm", buffer_timestamps,
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2744),
18475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            HAS_AUDIO));
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_VideoOnly) {
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, kSkip},
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, kSkip},
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, kSkip},
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, kSkip},
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {133, kSkip},
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1860e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // TODO(wolenetz/acolwell): Remove this SetDuration expectation and update the
1861e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // ParseWebMFile() call's expected duration, below, once the file is fixed to
1862e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // have the correct duration in the init segment. See http://crbug.com/354284.
1863e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2736)));
1864e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-video-only.webm", buffer_timestamps,
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2703),
18675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            HAS_VIDEO));
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMFile_AltRefFrames) {
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct BufferTimestamps buffer_timestamps[] = {
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, 0},
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 3},
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {33, 6},
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {67, 9},
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {100, 12},
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {kSkip, kSkip},
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseWebMFile("bear-320x240-altref.webm", buffer_timestamps,
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(2767)));
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that we output buffers before the entire cluster has been parsed.
18856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, IncrementalClusterParsing) {
18865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendEmptyCluster(0);
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster(GenerateCluster(0, 6));
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
1893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
1898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the reads haven't completed yet.
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Append data one byte at a time until one or both reads complete.
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i = 0;
19065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (; i < cluster->size() && !(audio_read_done || video_read_done); ++i) {
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AppendData(cluster->data() + i, 1);
1908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_loop_.RunUntilIdle();
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(audio_read_done || video_read_done);
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(i, 0);
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(i, cluster->size());
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio_read_done = false;
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video_read_done = false;
1917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
1918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(23),
1919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
1920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(33),
1922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the reads haven't completed yet.
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append the remaining data.
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LT(i, cluster->size());
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(cluster->data() + i, cluster->size() - i);
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
1933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) {
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(
1942f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          kNoTimestamp(), DEMUXER_ERROR_COULD_NOT_OPEN), true);
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 tmp = 0;
1947a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  demuxer_->AppendData(kSourceId, &tmp, 1,
1948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_start_for_next_append_,
1949a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       append_window_end_for_next_append_,
1950a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       &timestamp_offset_map_[kSourceId]);
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) {
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(kNoTimestamp(),
1957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               DEMUXER_ERROR_COULD_NOT_OPEN), true);
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> codecs(1);
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codecs[0] = "vorbis";
19616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs),
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ChunkDemuxer::kOk);
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegment(HAS_AUDIO | HAS_VIDEO);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) {
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &host_, CreateInitDoneCB(kNoTimestamp(),
1971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               DEMUXER_ERROR_COULD_NOT_OPEN), true);
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> codecs(1);
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codecs[0] = "vp8";
19756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs),
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ChunkDemuxer::kOk);
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegment(HAS_AUDIO | HAS_VIDEO);
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, MultipleHeaders) {
19825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1984a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append another identical initialization segment.
19875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegment(HAS_AUDIO | HAS_VIDEO);
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1989a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 9);
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideo) {
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append audio and video data into separate source ids.
2000a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id,
2001a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
2002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
2003a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id,
2004a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
2005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AddSeparateSourcesForAudioAndVideoText) {
2009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(matthewjheaney): Here and elsewhere, we need more tests
2010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // for inband text tracks (http://crbug/321455).
2011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string audio_id = "audio1";
2013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string video_id = "video1";
2014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
2016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    .Times(Exactly(2));
2017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSourcesText(audio_id, video_id, true));
2018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Append audio and video data into separate source ids.
2020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendCluster(audio_id,
2021f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
2022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
2023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppendCluster(video_id,
2024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
2025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
2026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AddIdFailures) {
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
2031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AddId(audio_id, HAS_AUDIO), ChunkDemuxer::kOk);
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding an id with audio/video should fail because we already added audio.
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(AddId(), ChunkDemuxer::kReachedIdLimit);
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegmentWithSourceId(audio_id, HAS_AUDIO);
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding an id after append should fail.
20445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AddId(video_id, HAS_VIDEO), ChunkDemuxer::kReachedIdLimit);
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Read() calls after a RemoveId() return "end of stream" buffers.
20486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, RemoveId) {
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2053a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Append audio and video data into separate source ids.
2054a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id,
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
2056a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id,
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() from audio should return normal buffers.
2060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the audio id.
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->RemoveId(audio_id);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() from audio should return "end of stream" buffers.
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
2067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_EOSExpected, &audio_read_done));
2068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() from video should still return normal buffers.
2072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that removing an ID immediately after adding it does not interfere with
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// quota for new IDs in the future.
20776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, RemoveAndAddId) {
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id_1 = "audio1";
20795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(AddId(audio_id_1, HAS_AUDIO) == ChunkDemuxer::kOk);
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->RemoveId(audio_id_1);
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id_2 = "audio2";
20835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(AddId(audio_id_2, HAS_AUDIO) == ChunkDemuxer::kOk);
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekCanceled) {
20875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append cluster at the beginning of the stream.
2090a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 4));
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to an unbuffered region.
2093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(50));
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to read in unbuffered area; should not fulfill the read.
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
2098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_AbortExpected, &audio_read_done));
2099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone_AbortExpected, &video_read_done));
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now cancel the pending seek, which should flush the reads with empty
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffers.
2105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(0);
2106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time);
2107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A seek back to the buffered region should succeed.
2112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time);
2113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 4);
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekCanceledWhileWaitingForSeek) {
21175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append cluster at the beginning of the stream.
2120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 4));
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start waiting for a seek.
2123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time1 = base::TimeDelta::FromSeconds(50);
2124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time2 = base::TimeDelta::FromSeconds(0);
2125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time1);
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now cancel the upcoming seek to an unbuffered region.
2128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time2);
2129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time1, NewExpectedStatusCB(PIPELINE_OK));
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read requests should be fulfilled with empty buffers.
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
2134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_AbortExpected, &audio_read_done));
2135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone_AbortExpected, &video_read_done));
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A seek back to the buffered region should succeed.
2140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time2);
2141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 4);
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Seek() successfully seeks to all source IDs.
21456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekAudioAndVideoSources) {
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
2151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      audio_id,
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
2153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
2154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      video_id,
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() should return buffers at 0.
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool audio_read_done = false;
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool video_read_done = false;
2160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
2161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
2162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
2163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
2164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromMilliseconds(0),
2165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to 3 (an unbuffered region).
2170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(3));
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio_read_done = false;
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video_read_done = false;
2174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
2175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromSeconds(3),
2176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &audio_read_done));
2177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
2178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       base::TimeDelta::FromSeconds(3),
2179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       &video_read_done));
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read()s should not return until after data is appended at the Seek point.
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id,
2185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                GenerateSingleStreamCluster(
2186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    3000, 3092, kAudioTrackNum, kAudioBlockDuration));
2187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id,
2188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                GenerateSingleStreamCluster(
2189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    3000, 3132, kVideoTrackNum, kVideoBlockDuration));
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
2192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read() should return buffers at 3.
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test that Seek() completes successfully when EndOfStream
21997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// is called before data is available for that seek point.
22007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This scenario might be useful if seeking past the end of stream
22017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// of either audio or video (or both).
22026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamAfterPastEosSeek) {
22035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
22047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 120, kAudioTrackNum, 10));
2206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 5));
22077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Seeking past the end of video.
22097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Note: audio data is available for that seek point.
22107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool seek_cb_was_called = false;
2211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(110);
2212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
2213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time,
22147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
2215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
2216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
22177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(seek_cb_was_called);
22187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
22207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(120)));
2221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
2222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
2223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
22247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(seek_cb_was_called);
22257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ShutdownDemuxer();
22277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
22287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test that EndOfStream is ignored if coming during a pending seek
22307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// whose seek time is before some existing ranges.
22316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamDuringPendingSeek) {
22325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
22337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 120, kAudioTrackNum, 10));
2235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 5));
2236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(200, 300, kAudioTrackNum, 10));
2237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(200, 300, kVideoTrackNum, 5));
22387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool seek_cb_was_called = false;
2240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(160);
2241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
2242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time,
22437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
2244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
2245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
22467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(seek_cb_was_called);
22477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(300)));
2249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
2250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
2251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
22527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(seek_cb_was_called);
22537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  demuxer_->UnmarkEndOfStream();
2255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(140, 180, kAudioTrackNum, 10));
2257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(140, 180, kVideoTrackNum, 5));
2258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
2260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
22617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(seek_cb_was_called);
22627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ShutdownDemuxer();
22647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
22657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test ranges in an audio-only stream.
22676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) {
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
2270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AddId(kSourceId, HAS_AUDIO), ChunkDemuxer::kOk);
22735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegment(HAS_AUDIO);
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a simple cluster.
2276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
2277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,92) }");
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append a disjoint cluster to check for two separate ranges.
2282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
2283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      150, 219, kAudioTrackNum, kAudioBlockDuration));
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,92) [150,219) }");
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test ranges in a video-only stream.
22896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) {
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  demuxer_->Initialize(
2292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK), true);
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AddId(kSourceId, HAS_VIDEO), ChunkDemuxer::kOk);
22955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendInitSegment(HAS_VIDEO);
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a simple cluster.
2298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(
2299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,132) }");
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append a disjoint cluster to check for two separate ranges.
2304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
2305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      200, 299, kVideoTrackNum, kVideoBlockDuration));
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,132) [200,299) }");
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
23115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 0 -> 23
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 0 -> 33
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 0 -> 23
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio block duration is smaller than video block duration,
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the buffered ranges should correspond to the audio blocks.
2318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
2319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kAudioBlockDuration, kAudioTrackNum, kAudioBlockDuration));
2320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(
2321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kVideoBlockDuration, kVideoTrackNum, kVideoBlockDuration));
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) }");
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 300 -> 400
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 320 -> 420
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 320 -> 400  (end overlap)
2328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(300, 400, kAudioTrackNum, 50));
2329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(320, 420, kVideoTrackNum, 50));
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) }");
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 520 -> 590
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 500 -> 570
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 520 -> 570  (front overlap)
2336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(520, 590, kAudioTrackNum, 70));
2337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(500, 570, kVideoTrackNum, 70));
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) }");
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 720 -> 750
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 700 -> 770
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 720 -> 750  (complete overlap, audio)
2344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(720, 750, kAudioTrackNum, 30));
2345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(700, 770, kVideoTrackNum, 70));
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) }");
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Audio: 900 -> 970
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video: 920 -> 950
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffered Range: 920 -> 950  (complete overlap, video)
2352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(900, 970, kAudioTrackNum, 70));
2353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(920, 950, kVideoTrackNum, 30));
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appending within buffered range should not affect buffered ranges.
2358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(930, 950, kAudioTrackNum, 20));
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appending to single stream outside buffered ranges should not affect
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffered ranges.
2363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateSingleStreamCluster(1230, 1240, kVideoTrackNum, 10));
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("{ [0,23) [320,400) [520,570) [720,750) [920,950) }");
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideoText) {
23685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _));
23695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
23705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append audio & video data
23725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23");
23735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 33");
23745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that a text track with no cues does not result in an empty buffered
23765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // range.
23775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,46) }");
23785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Add some text cues.
23805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K");
23815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that the new cues did not affect the buffered ranges.
23835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,46) }");
23845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Remove the buffered range.
23865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  demuxer_->Remove(kSourceId, base::TimeDelta(),
23875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::TimeDelta::FromMilliseconds(46));
23885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ }");
23895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
23905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2391ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Once MarkEndOfStream() is called, GetBufferedRanges should not cut off any
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// over-hanging tails at the end of the ranges as this is likely due to block
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// duration differences.
23946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) {
23955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
23965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K 23K");
23985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "0K 33");
23995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,46) }");
24015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(66)));
24035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MarkEndOfStream(PIPELINE_OK);
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that the range extends to the end of the video data.
24065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,66) }");
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that the range reverts to the intersection when end of stream
24095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // has been cancelled.
24105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  demuxer_->UnmarkEndOfStream();
24115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,46) }");
24125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append and remove data so that the 2 streams' end ranges do not overlap.
24145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(246)));
24160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(398)));
24175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "200K 223K");
24185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
24190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            "200K 233 266 299 332K 365");
24205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // At this point, the per-stream ranges are as follows:
24225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Audio: [0,46) [200,246)
24230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Video: [0,66) [200,398)
24245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,46) [200,246) }");
24255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(200),
24275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::TimeDelta::FromMilliseconds(300));
24285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // At this point, the per-stream ranges are as follows:
24305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Audio: [0,46)
24310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Video: [0,66) [332,398)
24325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,46) }");
24335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "200K 223K");
24355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum, "200K 233");
24365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // At this point, the per-stream ranges are as follows:
24385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Audio: [0,46) [200,246)
24390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Video: [0,66) [200,266) [332,398)
24405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NOTE: The last range on each stream do not overlap in time.
24415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges("{ [0,46) [200,246) }");
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NOTE: The last range on each stream gets extended to the highest
24465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // end timestamp according to the spec. The last audio range gets extended
24470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // from [200,246) to [200,398) which is why the intersection results in the
24485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // middle range getting larger AND the new range appearing.
24490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  CheckExpectedRanges("{ [0,46) [200,266) [332,398) }");
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DifferentStreamTimecodes) {
24535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a cluster where the video timecode begins 25ms after the audio.
2456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 25, 8));
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(0));
2459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 25, 8);
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to 5 seconds.
2462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromSeconds(5));
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a cluster to fulfill this seek, where audio timecode begins 25ms
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after the video.
2466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(5025, 5000, 8));
2467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(5025, 5000, 8);
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesSeparateSources) {
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate two streams where the video stream starts 5ms after the audio
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stream and append them.
2477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(
2478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      25, 4 * kAudioBlockDuration + 25, kAudioTrackNum, kAudioBlockDuration));
2479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(
2480a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      30, 4 * kVideoBlockDuration + 30, kVideoTrackNum, kVideoBlockDuration));
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both streams should be able to fulfill a seek to 25.
2483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(25));
2484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(25, 4);
2485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(30, 4);
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DifferentStreamTimecodesOutOfRange) {
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate two streams where the video stream starts 10s after the audio
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stream and append them.
2495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(0,
2496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      4 * kAudioBlockDuration + 0, kAudioTrackNum, kAudioBlockDuration));
2497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(10000,
2498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      4 * kVideoBlockDuration + 10000, kVideoTrackNum, kVideoBlockDuration));
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not be able to fulfill a seek to 0.
2501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(0);
2502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
2503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time,
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 NewExpectedStatusCB(PIPELINE_ERROR_ABORT));
2505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
2506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectEndOfStream(DemuxerStream::VIDEO);
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ClusterWithNoBuffers) {
25105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate and append an empty cluster beginning at 0.
25132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendEmptyCluster(0);
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check that data can be appended after this cluster correctly.
2516a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
2517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
2518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CodecPrefixMatching) {
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected = ChunkDemuxer::kOk;
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> codecs;
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codecs.push_back("avc1.4D4041");
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(demuxer_->AddId("source_id", "video/mp4", codecs), expected);
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test codec ID's that are not compliant with RFC6381, but have been
25352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// seen in the wild.
25366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CodecIDsThatAreNotRFC6381Compliant) {
25372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported;
25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
25402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected = ChunkDemuxer::kOk;
25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* codec_ids[] = {
25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // GPAC places leading zeros on the audio object type.
25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "mp4a.40.02",
25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "mp4a.40.05"
25462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
25472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(codec_ids); ++i) {
25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<std::string> codecs;
25502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    codecs.push_back(codec_ids[i]);
25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChunkDemuxer::Status result =
25536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        demuxer_->AddId("source_id", "audio/mp4", codecs);
25542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(result, expected)
25562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Fail to add codec_id '" << codec_ids[i] << "'";
25572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (result == ChunkDemuxer::kOk)
25592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      demuxer_->RemoveId("source_id");
25602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamStillSetAfterSeek) {
25645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(host_, SetDuration(_))
25672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(AnyNumber());
25682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta kLastAudioTimestamp = base::TimeDelta::FromMilliseconds(92);
25702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta kLastVideoTimestamp = base::TimeDelta::FromMilliseconds(99);
25712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
2573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
2574ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
25752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DemuxerStream::Status status;
25772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta last_timestamp;
25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that we can read audio & video to the end w/o problems.
2580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
25812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
25822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
25832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
25852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
25862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
25872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Seek back to 0 and verify that we can read to the end again..
2589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(0));
25902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastAudioTimestamp, last_timestamp);
25942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
25962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DemuxerStream::kOk, status);
25972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kLastVideoTimestamp, last_timestamp);
25982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) {
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
2602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true);
26035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk);
26045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk);
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("audio", "{ }");
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges("video", "{ }");
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Seek() completes successfully when the first cluster
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arrives.
26126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) {
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2617a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(0);
2620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time);
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kDefaultSecondClusterEndTimestamp)));
2625ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK));
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 4);
2630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(46, 66, 5);
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EndOfStreamHelper end_of_stream_helper(demuxer_.get());
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper.RequestReads();
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end_of_stream_helper.CheckIfReadDonesWereCalled(true);
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ConfigChange_Video) {
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithConfigChangeData());
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DemuxerStream::Status status;
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta last_timestamp;
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
2646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch initial video config and verify it matches what we expect.
2648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_1.IsValidConfig());
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().width(), 320);
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().height(), 240);
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_timestamp.InMilliseconds(), 501);
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the new decoder config.
2661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_2.IsValidConfig());
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().width(), 640);
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().height(), 360);
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 527);
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read until the next config change.
2669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_timestamp.InMilliseconds(), 793);
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the new config and verify that it matches the first one.
2674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 801);
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read until the end of the stream just to make sure there aren't any other
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // config changes.
2680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp);
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ConfigChange_Audio) {
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithConfigChangeData());
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DemuxerStream::Status status;
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta last_timestamp;
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO);
2693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch initial audio config and verify it matches what we expect.
2695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const AudioDecoderConfig& audio_config_1 = audio->audio_decoder_config();
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(audio_config_1.IsValidConfig());
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_1.samples_per_second(), 44100);
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_1.extra_data_size(), 3863u);
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::AUDIO, 0);
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The first config change seen is from a splice frame representing an overlap
27030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // of buffer from config 1 by buffers from config 2.
2704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_timestamp.InMilliseconds(), 524);
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the new decoder config.
2709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const AudioDecoderConfig& audio_config_2 = audio->audio_decoder_config();
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(audio_config_2.IsValidConfig());
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_2.samples_per_second(), 44100);
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(audio_config_2.extra_data_size(), 3935u);
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The next config change is from a splice frame representing an overlap of
27150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // buffers from config 2 by buffers from config 1.
27160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
27170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(status, DemuxerStream::kConfigChanged);
27180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(last_timestamp.InMilliseconds(), 782);
2719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(audio_config_1.Matches(audio->audio_decoder_config()));
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read until the end of the stream just to make sure there aren't any other
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // config changes.
2723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ReadUntilNotOkOrEndOfStream(DemuxerStream::AUDIO, &status, &last_timestamp);
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(status, DemuxerStream::kOk);
27250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(last_timestamp.InMilliseconds(), 2744);
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ConfigChange_Seek) {
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerWithConfigChangeData());
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO);
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch initial video config and verify it matches what we expect.
2736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_1 = video->video_decoder_config();
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_1.IsValidConfig());
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().width(), 320);
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_1.natural_size().height(), 240);
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to a location with a different config.
2744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(527));
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the config change is signalled.
2747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectConfigChanged(DemuxerStream::VIDEO);
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch the new decoder config and verify it is what we expect.
2750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const VideoDecoderConfig& video_config_2 = video->video_decoder_config();
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(video_config_2.IsValidConfig());
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().width(), 640);
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(video_config_2.natural_size().height(), 360);
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that Read() will return a buffer now.
2756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 527);
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek back to the beginning and verify we get another config change.
2759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(0));
2760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectConfigChanged(DemuxerStream::VIDEO);
2761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
2762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 0);
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to a location that requires a config change and then
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // seek to a new location that has the same configuration as
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the start of the file without a Read() in the middle.
2767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(527));
2768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(801));
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that no config change is signalled.
2771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectRead(DemuxerStream::VIDEO, 801);
2772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(video_config_1.Matches(video->video_decoder_config()));
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, TimestampPositiveOffset) {
27765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(kSourceId, base::TimeDelta::FromSeconds(30)));
2779a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 2));
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(30000));
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(30000, 2);
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, TimestampNegativeOffset) {
27875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2789a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(kSourceId, base::TimeDelta::FromSeconds(-1)));
2790a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(1000, 2));
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateExpectedReads(0, 2);
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, TimestampOffsetSeparateStreams) {
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_id = "audio1";
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_id = "video1";
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_id, base::TimeDelta::FromMilliseconds(-2500)));
2802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_id, base::TimeDelta::FromMilliseconds(-2500)));
2804a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(2500,
2805a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      2500 + kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration));
2806a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(2500,
2807a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      2500 + kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration));
2808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(0, 4);
2809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(0, 4);
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(base::TimeDelta::FromMilliseconds(27300));
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2813a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_id, base::TimeDelta::FromMilliseconds(27300)));
2815a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_id, base::TimeDelta::FromMilliseconds(27300)));
2817a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(audio_id, GenerateSingleStreamCluster(
2818a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kAudioBlockDuration * 4, kAudioTrackNum, kAudioBlockDuration));
2819a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(video_id, GenerateSingleStreamCluster(
2820a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0, kVideoBlockDuration * 4, kVideoTrackNum, kVideoBlockDuration));
2821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateVideoStreamExpectedReads(27300, 4);
2822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GenerateAudioStreamExpectedReads(27300, 4);
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, IsParsingMediaSegmentMidMediaSegment) {
28265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cluster> cluster = GenerateCluster(0, 2);
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Append only part of the cluster data.
28302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(cluster->data(), cluster->size() - 13);
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2832a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Confirm we're in the middle of parsing a media segment.
2833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId));
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  demuxer_->Abort(kSourceId,
2836010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                  append_window_start_for_next_append_,
2837010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                  append_window_end_for_next_append_,
2838010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                  &timestamp_offset_map_[kSourceId]);
2839010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2840a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // After Abort(), parsing should no longer be in the middle of a media
2841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // segment.
2842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(demuxer_->IsParsingMediaSegment(kSourceId));
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
2846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(ENABLE_MPEG2TS_STREAM_PARSER)
28476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EmitBuffersDuringAbort) {
2848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
2849010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  demuxer_->Initialize(
2850010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &host_, CreateInitDoneCB(kInfiniteDuration(), PIPELINE_OK), true);
2851010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(ChunkDemuxer::kOk, AddIdForMp2tSource(kSourceId));
2852010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2853010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // For info:
2854010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode
2855010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Video: first PES:
2856010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //        PTS: 126912 (0x0001efc0)  [= 90 kHz-Timestamp: 0:00:01.4101]
2857010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //        DTS: 123909 (0x0001e405)  [= 90 kHz-Timestamp: 0:00:01.3767]
2858010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Audio: first PES:
2859010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //        PTS: 126000 (0x0001ec30)  [= 90 kHz-Timestamp: 0:00:01.4000]
2860010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //        DTS: 123910 (0x0001e406)  [= 90 kHz-Timestamp: 0:00:01.3767]
2861010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Video: last PES:
2862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //        PTS: 370155 (0x0005a5eb)  [= 90 kHz-Timestamp: 0:00:04.1128]
2863010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //        DTS: 367152 (0x00059a30)  [= 90 kHz-Timestamp: 0:00:04.0794]
2864010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Audio: last PES:
2865010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //        PTS: 353788 (0x000565fc)  [= 90 kHz-Timestamp: 0:00:03.9309]
2866010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2867010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts");
2868010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AppendData(kSourceId, buffer->data(), buffer->data_size());
2869010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2870010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Confirm we're in the middle of parsing a media segment.
2871010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId));
2872010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2873010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Abort on the Mpeg2 TS parser triggers the emission of the last video
2874010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // buffer which is pending in the stream parser.
2875010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Ranges<base::TimeDelta> range_before_abort =
2876010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      demuxer_->GetBufferedRanges(kSourceId);
2877010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  demuxer_->Abort(kSourceId,
2878010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                  append_window_start_for_next_append_,
2879010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                  append_window_end_for_next_append_,
2880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                  &timestamp_offset_map_[kSourceId]);
2881010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Ranges<base::TimeDelta> range_after_abort =
2882010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      demuxer_->GetBufferedRanges(kSourceId);
2883010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2884010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ASSERT_EQ(range_before_abort.size(), 1u);
2885010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ASSERT_EQ(range_after_abort.size(), 1u);
2886010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(range_after_abort.start(0), range_before_abort.start(0));
2887010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_GT(range_after_abort.end(0), range_before_abort.end(0));
2888010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
2889010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
2890010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
2891010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
28926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, WebMIsParsingMediaSegmentDetection) {
28935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const uint8 kBuffer[] = {
28945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x1F, 0x43, 0xB6, 0x75, 0x83,  // CLUSTER (size = 3)
28955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xE7, 0x81, 0x01,                // Cluster TIMECODE (value = 1)
2896f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2897f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    0x1F, 0x43, 0xB6, 0x75, 0xFF,  // CLUSTER (size = unknown; really 3 due to:)
2898f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    0xE7, 0x81, 0x02,                // Cluster TIMECODE (value = 2)
2899f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    /* e.g. put some blocks here... */
2900f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    0x1A, 0x45, 0xDF, 0xA3, 0x8A,  // EBMLHEADER (size = 10, not fully appended)
29015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
29025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This array indicates expected return value of IsParsingMediaSegment()
2904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // following each incrementally appended byte in |kBuffer|.
29055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const bool kExpectedReturnValues[] = {
2906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    false, false, false, false, true,
2907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    true, true, false,
2908f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2909f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    false, false, false, false, true,
2910f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    true, true, true,
2911f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2912f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    true, true, true, true, false,
29135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
29145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  COMPILE_ASSERT(arraysize(kBuffer) == arraysize(kExpectedReturnValues),
29165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test_arrays_out_of_sync);
29175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  COMPILE_ASSERT(arraysize(kBuffer) == sizeof(kBuffer), not_one_byte_per_index);
29185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
29205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < sizeof(kBuffer); i++) {
29225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(3) << "Appending and testing index " << i;
29235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AppendData(kBuffer + i, 1);
29245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool expected_return_value = kExpectedReturnValues[i];
2925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(expected_return_value,
2926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              demuxer_->IsParsingMediaSegment(kSourceId));
29275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
29285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
29295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
29306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DurationChange) {
29315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
29325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kStreamDuration = kDefaultDuration().InMilliseconds();
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add data leading up to the currently set duration.
2935a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(kStreamDuration - kAudioBlockDuration,
2936a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                kStreamDuration - kVideoBlockDuration,
2937a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                2));
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [201191,201224) }");
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2941e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Add data beginning at the currently set duration and expect a new duration
2942e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // to be signaled. Note that the last video block will have a higher end
2943e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // timestamp than the last audio block.
2944e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  const int kNewStreamDurationVideo = kStreamDuration + kVideoBlockDuration;
2945e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(host_, SetDuration(
2946e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      base::TimeDelta::FromMilliseconds(kNewStreamDurationVideo)));
2947a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(kDefaultDuration().InMilliseconds(), 2));
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2949e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [201191,201247) }");
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2951e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Add more data to the end of each media type. Note that the last audio block
2952e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // will have a higher end timestamp than the last video block.
2953e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  const int kFinalStreamDuration = kStreamDuration + kAudioBlockDuration * 3;
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
2955e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      base::TimeDelta::FromMilliseconds(kFinalStreamDuration)));
2956a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(kStreamDuration + kAudioBlockDuration,
2957a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                kStreamDuration + kVideoBlockDuration,
2958e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                3));
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2960e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // See that the range has increased appropriately (but not to the full
2961e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // duration of 201293, since there is not enough video appended for that).
2962e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [201191,201290) }");
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, DurationChangeTimestampOffset) {
29665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
2967a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(kSourceId, kDefaultDuration()));
2968e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(host_, SetDuration(
2969e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      kDefaultDuration() + base::TimeDelta::FromMilliseconds(
2970e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          kVideoBlockDuration * 2)));
2971a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 4));
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamTruncateDuration) {
29755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2977a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kDefaultFirstClusterEndTimestamp)));
2981ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ZeroLengthAppend) {
29865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
29872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendData(NULL, 0);
29882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendAfterEndOfStream) {
29915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
29922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(host_, SetDuration(_))
29942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(AnyNumber());
29952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2996a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultFirstCluster());
2997ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
2998ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2999ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  demuxer_->UnmarkEndOfStream();
30002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3001a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendCluster(kDefaultSecondCluster());
3002ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
30032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test receiving a Shutdown() call before we get an Initialize()
30062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// call. This can happen if video element gets destroyed before
30072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the pipeline has a chance to initialize the demuxer.
30086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Shutdown_BeforeInitialize) {
30092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->Shutdown();
30102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  demuxer_->Initialize(
3011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &host_, CreateInitDoneCB(DEMUXER_ERROR_COULD_NOT_OPEN), true);
30122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  message_loop_.RunUntilIdle();
30132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
30142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3015e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Verifies that signaling end of stream while stalled at a gap
30167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// boundary does not trigger end of stream buffers to be returned.
30176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, EndOfStreamWhileWaitingForGapToBeFilled) {
30185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
30197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppendCluster(0, 10);
30217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppendCluster(300, 10);
30227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,132) [300,432) }");
30237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GenerateExpectedReads(0, 10);
30257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool audio_read_done = false;
30277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool video_read_done = false;
30287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone,
30297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::TimeDelta::FromMilliseconds(138),
30307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &audio_read_done));
30317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone,
30327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::TimeDelta::FromMilliseconds(138),
30337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &video_read_done));
30347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads didn't complete
30367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
30377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
30387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(438)));
3040ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
30417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads still haven't completed.
30437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
30447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
30457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3046ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  demuxer_->UnmarkEndOfStream();
3047ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3048e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  AppendCluster(138, 22);
30497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  message_loop_.RunUntilIdle();
3051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3052e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [0,435) }");
30537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads have completed.
30557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
30567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
30577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Read the rest of the buffers.
3059e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  GenerateExpectedReads(161, 171, 20);
30607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that reads block because the append cleared the end of stream state.
30627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  audio_read_done = false;
30637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  video_read_done = false;
30647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadAudio(base::Bind(&OnReadDone_EOSExpected,
30657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &audio_read_done));
30667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ReadVideo(base::Bind(&OnReadDone_EOSExpected,
30677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       &video_read_done));
30687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify that the reads don't complete.
30707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(audio_read_done);
30717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(video_read_done);
30727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3073e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(437)));
3074ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MarkEndOfStream(PIPELINE_OK);
30757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(audio_read_done);
30777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(video_read_done);
30787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
30797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
30806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CanceledSeekDuringInitialPreroll) {
30815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Cancel preroll.
3084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(200);
3085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->CancelPendingSeek(seek_time);
3086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Initiate the seek to the new location.
3088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time);
3089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append data to satisfy the seek.
3091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendCluster(seek_time.InMilliseconds(), 10);
3092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
3093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
30946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, GCDuringSeek) {
30955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->SetMemoryLimitsForTesting(5 * kBlockSize);
3098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time1 = base::TimeDelta::FromMilliseconds(1000);
3100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(500);
3101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Initiate a seek to |seek_time1|.
3103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Seek(seek_time1);
3104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append data to satisfy the first seek request.
3106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                            seek_time1.InMilliseconds(), 5);
3108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckExpectedRanges(kSourceId, "{ [1000,1115) }");
3109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Signal that the second seek is starting.
3111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->StartWaitingForSeek(seek_time2);
3112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append data to satisfy the second seek. This append triggers
3114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the garbage collection logic since we set the memory limit to
3115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // 5 blocks.
3116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
3117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                            seek_time2.InMilliseconds(), 5);
3118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Verify that the buffers that cover |seek_time2| do not get
3120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // garbage collected.
3121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckExpectedRanges(kSourceId, "{ [500,615) }");
3122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Complete the seek.
3124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  demuxer_->Seek(seek_time2, NewExpectedStatusCB(PIPELINE_OK));
3125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Append more data and make sure that the blocks for |seek_time2|
3128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // don't get removed.
3129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
3130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // NOTE: The current GC algorithm tries to preserve the GOP at the
3131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  current position as well as the last appended GOP. This is
3132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  why there are 2 ranges in the expectations.
3133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5);
3134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }");
3135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
3136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
31376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendWindow_Video) {
31385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
3139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3140558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
314146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set the append window to [50,280).
314246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280);
3144558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3145558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Append a cluster that starts before and ends after the append window.
3146558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                            "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
3148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3149558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Verify that GOPs that start outside the window are not included
31505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in the buffer. Also verify that buffers that start inside the
3151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // window and extend beyond the end of the window are not included.
3152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [120,270) }");
3153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedBuffers(stream, "120 150 180 210 240");
3154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
315546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Extend the append window to [50,650).
3156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
3157558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Append more data and verify that adding buffers start at the next
3159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // keyframe.
3160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                            "360 390 420K 450 480 510 540K 570 600 630K");
3162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }");
3163558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
3164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
31656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendWindow_Audio) {
31665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
31675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
31685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
316946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set the append window to [50,280).
317046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280);
31725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append a cluster that starts before and ends after the append window.
31745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(
31755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kSourceId, kAudioTrackNum,
31765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K");
31775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Verify that frames that end outside the window are not included
31795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in the buffer. Also verify that buffers that start inside the
3180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // window and extend beyond the end of the window are not included.
3181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  //
318246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The first 50ms of the range should be truncated since it overlaps
318346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // the start of the append window.
318446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [50,270) }");
31855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
318646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The "50P" buffer is the "0" buffer marked for complete discard.  The next
318746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // "50" buffer is the "30" buffer marked with 20ms of start discard.
318846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedBuffers(stream, "50P 50 60 90 120 150 180 210 240");
318946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
319046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Extend the append window to [50,650).
3191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
31925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append more data and verify that a new range is created.
31945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(
31955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kSourceId, kAudioTrackNum,
31965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K");
319746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [50,270) [360,630) }");
3198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
3199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
32006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) {
3201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Set the append window to [10,20).
3204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10);
3205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20);
3206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Append a cluster that starts before and ends after the append window.
3208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K");
3209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Verify that everything is dropped in this case.  No partial append should
3211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // be generated.
3212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ }");
32135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
32145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) {
321646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
321746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  demuxer_->Initialize(
321846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      &host_,
321946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK),
322046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      true);
322146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO));
322246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
322346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set the append window to [50,150).
322446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
322546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(150);
322646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
322746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Read a WebM file into memory and send the data to the demuxer.  The chunk
322846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // size has been chosen carefully to ensure the preroll buffer used by the
322946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // partial append window trim must come from a previous Append() call.
323046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<DecoderBuffer> buffer =
323146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ReadTestDataFile("bear-320x240-audio-only.webm");
323246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppendDataInPieces(buffer->data(), buffer->data_size(), 128);
323346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
323446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
323546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedBuffers(stream, "50P 50 62 86 109 122 125 128");
323646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
323746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) {
323946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_CALL(*this, DemuxerOpened());
324046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  demuxer_->Initialize(
324146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      &host_,
324246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK),
324346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      true);
324446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO));
324546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
324646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set the append window such that the first file is completely before the
324746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // append window.
324846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(wolenetz/acolwell): Update this duration once the files are fixed to
324946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // have the correct duration in their init segments, and the
325046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // CreateInitDoneCB() call, above, is fixed to used that duration. See
325146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // http://crbug.com/354284.
325246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const base::TimeDelta duration_1 = base::TimeDelta::FromMilliseconds(2746);
325346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  append_window_start_for_next_append_ = duration_1;
325446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
325546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Read a WebM file into memory and append the data.
325646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<DecoderBuffer> buffer =
325746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ReadTestDataFile("bear-320x240-audio-only.webm");
325846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppendDataInPieces(buffer->data(), buffer->data_size(), 512);
325946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ }");
326046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
326146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
326246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AudioDecoderConfig config_1 = stream->audio_decoder_config();
326346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
326446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Read a second WebM with a different config in and append the data.
326546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<DecoderBuffer> buffer2 =
326646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ReadTestDataFile("bear-320x240-audio-only-48khz.webm");
326746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_CALL(host_, SetDuration(_)).Times(AnyNumber());
326846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(SetTimestampOffset(kSourceId, duration_1));
326946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppendDataInPieces(buffer2->data(), buffer2->data_size(), 512);
327046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [2746,5519) }");
327146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
327246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Seek(duration_1);
327346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ExpectConfigChanged(DemuxerStream::AUDIO);
327446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(config_1.Matches(stream->audio_decoder_config()));
327546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedBuffers(stream, "2746 2767 2789 2810");
327646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
327746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, AppendWindow_Text) {
32795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* text_stream = NULL;
32805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
32815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
32825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT));
32835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
32845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set the append window to [20,280).
3286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20);
3287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280);
32885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append a cluster that starts before and ends after the append
32905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // window.
32915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
32925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
32935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K 200K 300K");
32945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that text cues that start outside the window are not included
32965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in the buffer. Also verify that cues that extend beyond the
3297e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // window are not included.
3298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [120,270) }");
3299e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedBuffers(video_stream, "120 150 180 210 240");
3300e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedBuffers(text_stream, "100");
33015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Extend the append window to [20,650).
3303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
33045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append more data and verify that a new range is created.
33065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
33075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "360 390 420K 450 480 510 540K 570 600 630K");
33085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "400K 500K 600K 700K");
3309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }");
33105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Seek to the new range and verify that the expected buffers are returned.
33125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Seek(base::TimeDelta::FromMilliseconds(420));
3313e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedBuffers(video_stream, "420 450 480 510 540 570 600");
3314e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  CheckExpectedBuffers(text_stream, "400 500");
33155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
33165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) {
33185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
3320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AppendGarbage();
3321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(50);
3322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  demuxer_->StartWaitingForSeek(seek_time);
3323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
3324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
33256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Remove_AudioVideoText) {
33265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* text_stream = NULL;
33275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
33285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
33295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
33305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
33325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
33335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
33355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "0K 20K 40K 60K 80K 100K 120K 140K");
33365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
33375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "0K 30 60 90 120K 150 180");
33385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "0K 100K 200K");
33395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(audio_stream, "0 20 40 60 80 100 120 140");
33415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(video_stream, "0 30 60 90 120 150 180");
33425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(text_stream, "0 100 200");
33435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Remove the buffers that were added.
33455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  demuxer_->Remove(kSourceId, base::TimeDelta(),
33465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::TimeDelta::FromMilliseconds(300));
33475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that all the appended data has been removed.
33495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ }");
33505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append new buffers that are clearly different than the original
33525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ones and verify that only the new buffers are returned.
33535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
33545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "1K 21K 41K 61K 81K 101K 121K 141K");
33555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
33565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "1K 31 61 91 121K 151 181");
33575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "1K 101K 201K");
33585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Seek(base::TimeDelta());
33605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(audio_stream, "1 21 41 61 81 101 121 141");
33615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(video_stream, "1 31 61 91 121 151 181");
33625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(text_stream, "1 101 201");
33635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
33645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, Remove_StartAtDuration) {
336646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
336746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
336846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
336946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set the duration to something small so that the append that
337046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // follows updates the duration to reflect the end of the appended data.
337146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
337246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(1)));
337346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  demuxer_->SetDuration(0.001);
337446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
337546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_CALL(host_, SetDuration(
337646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(160)));
337746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
337846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                            "0K 20K 40K 60K 80K 100K 120K 140K");
337946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
338046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,160) }");
338146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedBuffers(audio_stream, "0 20 40 60 80 100 120 140");
338246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
338346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  demuxer_->Remove(kSourceId,
338446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::TimeDelta::FromSecondsD(demuxer_->GetDuration()),
338546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   kInfiniteDuration());
338646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
338746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Seek(base::TimeDelta());
338846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,160) }");
338946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckExpectedBuffers(audio_stream, "0 20 40 60 80 100 120 140");
339046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
339146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
33925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verifies that a Seek() will complete without text cues for
33935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the seek point and will return cues after the seek position
33945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// when they are eventually appended.
33956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, SeekCompletesWithoutTextCues) {
33965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* text_stream = NULL;
33975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(host_, AddTextStream(_, _))
33985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(SaveArg<0>(&text_stream));
33995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO | HAS_TEXT));
34005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
34025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
34035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(120);
34055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool seek_cb_was_called = false;
34065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  demuxer_->StartWaitingForSeek(seek_time);
34075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  demuxer_->Seek(seek_time,
34085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Bind(OnSeekDone_OKExpected, &seek_cb_was_called));
34095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_loop_.RunUntilIdle();
34105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(seek_cb_was_called);
34125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool text_read_done = false;
34145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  text_stream->Read(base::Bind(&OnReadDone,
34155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(125),
34165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               &text_read_done));
34175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append audio & video data so the seek completes.
34195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
34205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "0K 20K 40K 60K 80K 100K 120K 140K 160K 180K");
34215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
34225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            "0K 30 60 90 120K 150 180 210");
34235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_loop_.RunUntilIdle();
34255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(seek_cb_was_called);
34265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(text_read_done);
34275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Read some audio & video buffers to further verify seek completion.
34295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(audio_stream, "120 140");
34305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(video_stream, "120 150");
34315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(text_read_done);
34335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Append text cues that start after the seek point and verify that
34355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // they are returned by Read() calls.
34365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendSingleStreamCluster(kSourceId, kTextTrackNum, "125K 175K 225K");
34375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_loop_.RunUntilIdle();
34395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(text_read_done);
34405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NOTE: we start at 175 here because the buffer at 125 was returned
34425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to the pending read initiated above.
34435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(text_stream, "175 225");
34445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3445e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Verify that audio & video streams continue to return expected values.
34465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(audio_stream, "160 180");
34475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckExpectedBuffers(video_stream, "180 210");
34485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
34495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
34506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, ClusterWithUnknownSize) {
3451f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
3452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 0, 4, true));
3454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,46) }");
3455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A new cluster indicates end of the previous cluster with unknown size.
3457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppendCluster(GenerateCluster(46, 66, 5, true));
3458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,115) }");
3459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
3460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
34616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CuesBetweenClustersWithUnknownSize) {
34626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
34636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
34646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Add two clusters separated by Cues in a single Append() call.
34656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<Cluster> cluster = GenerateCluster(0, 0, 4, true);
34666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::vector<uint8> data(cluster->data(), cluster->data() + cluster->size());
34676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  data.insert(data.end(), kCuesHeader, kCuesHeader + sizeof(kCuesHeader));
34686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  cluster = GenerateCluster(46, 66, 5, true);
34696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  data.insert(data.end(), cluster->data(), cluster->data() + cluster->size());
34706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AppendData(&*data.begin(), data.size());
34716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
34726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,115) }");
34736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
34746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
34756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(ChunkDemuxerTest, CuesBetweenClusters) {
34766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
34776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
34786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AppendCluster(GenerateCluster(0, 0, 4));
34796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AppendData(kCuesHeader, sizeof(kCuesHeader));
34806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AppendCluster(GenerateCluster(46, 66, 5));
34816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CheckExpectedRanges(kSourceId, "{ [0,115) }");
34826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3483c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
3485