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