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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/decrypt_config.h" 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "media/base/media_log.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/mock_demuxer_host.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/test_helpers.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/ffmpeg_demuxer.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/file_data_source.h" 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/formats/mp4/avc.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_crypto_helpers.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AnyNumber; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DoAll; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Exactly; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::InSequence; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Invoke; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::NotNull; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SaveArg; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SetArgPointee; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::StrictMock; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::WithArgs; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MATCHER(IsEndOfStreamBuffer, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string(negation ? "isn't" : "is") + " end of stream") { 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return arg->end_of_stream(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void EosOnReadDone(bool* got_eos_buffer, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemuxerStream::Status status, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& buffer) { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(status, DemuxerStream::kOk); 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (buffer->end_of_stream()) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *got_eos_buffer = true; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_TRUE(buffer->data()); 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_GT(buffer->data_size(), 0); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *got_eos_buffer = false; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fixture class to facilitate writing tests. Takes care of setting up the 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FFmpeg, pipeline and filter host mocks. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FFmpegDemuxerTest : public testing::Test { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FFmpegDemuxerTest() {} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FFmpegDemuxerTest() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (demuxer_) { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WaitableMessageLoopEvent event; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) demuxer_->Stop(event.GetClosure()); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event.RunAndWait(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateDemuxer(const std::string& name) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!demuxer_); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDataSource(name); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Demuxer::NeedKeyCB need_key_cb = 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this)); 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) demuxer_.reset(new FFmpegDemuxer(message_loop_.message_loop_proxy(), 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) data_source_.get(), 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) need_key_cb, 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new MediaLog())); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(CheckPoint, void(int v)); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 952f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) void InitializeDemuxerText(bool enable_text) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(host_, SetDuration(_)); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitableMessageLoopEvent event; 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), enable_text); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.RunAndWaitForStatus(PIPELINE_OK); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void InitializeDemuxer() { 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeDemuxerText(false); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD2(OnReadDoneCalled, void(int, int64)); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verifies that |buffer| has a specific |size| and |timestamp|. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |location| simply indicates where the call to this function was made. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This makes it easier to track down where test failures occur. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnReadDone(const tracked_objects::Location& location, 1122f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) int size, int64 timestampInMicroseconds, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemuxerStream::Status status, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& buffer) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string location_str; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location.Write(true, false, &location_str); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location_str += "\n"; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(location_str); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(status, DemuxerStream::kOk); 1202f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) OnReadDoneCalled(size, timestampInMicroseconds); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(buffer.get() != NULL); 122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(size, buffer->data_size()); 1232f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) EXPECT_EQ(base::TimeDelta::FromMicroseconds(timestampInMicroseconds), 1242f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) buffer->timestamp()); 1252f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(&message_loop_, base::MessageLoop::current()); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemuxerStream::ReadCB NewReadCB(const tracked_objects::Location& location, 1312f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) int size, int64 timestampInMicroseconds) { 1322f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) EXPECT_CALL(*this, OnReadDoneCalled(size, timestampInMicroseconds)); 1332f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) return base::Bind(&FFmpegDemuxerTest::OnReadDone, base::Unretained(this), 1342f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) location, size, timestampInMicroseconds); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(xhwang): This is a workaround of the issue that move-only parameters 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // are not supported in mocked methods. Remove this when the issue is fixed 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // std::string instead of scoped_ptr<uint8[]> (http://crbug.com/130689). 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MOCK_METHOD3(NeedKeyCBMock, void(const std::string& type, 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint8* init_data, int init_data_size)); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NeedKeyCB(const std::string& type, 144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::vector<uint8>& init_data) { 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0]; 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NeedKeyCBMock(type, init_data_ptr, init_data.size()); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accessor to demuxer internals. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_duration_known(bool duration_known) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demuxer_->duration_known_ = duration_known; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsStreamStopped(DemuxerStream::Type type) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemuxerStream* stream = demuxer_->GetStream(type); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(stream); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !static_cast<FFmpegDemuxerStream*>(stream)->demuxer_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fixture members. 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<FileDataSource> data_source_; 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<FFmpegDemuxer> demuxer_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StrictMock<MockDemuxerHost> host_; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop message_loop_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AVFormatContext* format_context() { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return demuxer_->glue_->format_context(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ReadUntilEndOfStream(DemuxerStream* stream) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool got_eos_buffer = false; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxBuffers = 170; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(got_eos_buffer); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CreateDataSource(const std::string& name) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!data_source_); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file_path; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_path = file_path.Append(FILE_PATH_LITERAL("media")) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Append(FILE_PATH_LITERAL("test")) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Append(FILE_PATH_LITERAL("data")) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .AppendASCII(name); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data_source_.reset(new FileDataSource()); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(data_source_->Initialize(file_path)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simulate avformat_open_input() failing. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDemuxer("ten_byte_file"); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitableMessageLoopEvent event; 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(acolwell): Uncomment this test when we discover a file that passes 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avformat_open_input(), but has avformat_find_stream_info() fail. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ("find_stream_info_fail.webm"); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// demuxer_->Initialize( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// message_loop_.RunUntilIdle(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a file with no streams whatsoever. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("no_streams.webm"); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitableMessageLoopEvent event; 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a file containing streams but none of which are audio/video streams. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("no_audio_video.webm"); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitableMessageLoopEvent event; 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_Successful) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240.webm"); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Video stream should be present. 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(stream); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VideoDecoderConfig& video_config = stream->video_decoder_config(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kCodecVP8, video_config.codec()); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(VideoFrame::YV12, video_config.format()); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(320, video_config.coded_size().width()); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(240, video_config.coded_size().height()); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, video_config.visible_rect().x()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, video_config.visible_rect().y()); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(320, video_config.visible_rect().width()); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(240, video_config.visible_rect().height()); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(320, video_config.natural_size().width()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(240, video_config.natural_size().height()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(video_config.extra_data()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, video_config.extra_data_size()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio stream should be present. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream = demuxer_->GetStream(DemuxerStream::AUDIO); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(stream); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioDecoderConfig& audio_config = stream->audio_decoder_config(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kCodecVorbis, audio_config.codec()); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(32, audio_config.bits_per_channel()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(CHANNEL_LAYOUT_STEREO, audio_config.channel_layout()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(44100, audio_config.samples_per_second()); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kSampleFormatPlanarF32, audio_config.sample_format()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(audio_config.extra_data()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(audio_config.extra_data_size(), 0u); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unknown stream should never be present. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a file containing the following streams: 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stream #0: Video (VP8) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stream #1: Audio (Vorbis) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stream #2: Subtitles (SRT) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stream #3: Video (Theora) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stream #4: Audio (16-bit signed little endian PCM) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should only pick the first audio/video streams we come across. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240-multitrack.webm"); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Video stream should be VP8. 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(stream); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio stream should be Vorbis. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream = demuxer_->GetStream(DemuxerStream::AUDIO); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(stream); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unknown stream should never be present. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_MultitrackText) { 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Open a file containing the following streams: 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stream #0: Video (VP8) 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stream #1: Audio (Vorbis) 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stream #2: Text (WebVTT) 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateDemuxer("bear-vp8-webvtt.webm"); 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DemuxerStream* text_stream = NULL; 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(host_, AddTextStream(_, _)) 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .WillOnce(SaveArg<0>(&text_stream)); 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeDemuxerText(true); 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(text_stream); 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Video stream should be VP8. 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(stream); 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Audio stream should be Vorbis. 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) stream = demuxer_->GetStream(DemuxerStream::AUDIO); 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(stream); 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Unknown stream should never be present. 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) { 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*this, NeedKeyCBMock(kWebMEncryptInitDataType, NotNull(), 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DecryptConfig::kDecryptionKeySize)) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Times(Exactly(2)); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDemuxer("bear-320x240-av_enc-av.webm"); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InitializeDemuxer(); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_Audio) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We test that on a successful audio packet read. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240.webm"); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt a read from the audio stream and run the message loop until done. 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 29, 0)); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 27, 3000)); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_Video) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We test that on a successful video packet read. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240.webm"); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt a read from the video stream and run the message loop until done. 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 22084, 0)); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 1057, 33000)); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_Text) { 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We test that on a successful text packet read. 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateDemuxer("bear-vp8-webvtt.webm"); 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DemuxerStream* text_stream = NULL; 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(host_, AddTextStream(_, _)) 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .WillOnce(SaveArg<0>(&text_stream)); 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeDemuxerText(true); 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(text_stream); 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3892f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the start time is the first timestamp of the video and audio stream. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("nonzero-start-time.webm"); 3922f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) InitializeDemuxer(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt a read from the video stream and run the message loop until done. 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3982f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) // Check first buffer in video stream. 3992f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 5636, 400000)); 4002f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) message_loop_.Run(); 401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4022f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) // Check first buffer in audio stream. 4032f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 165, 396000)); 4042f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) message_loop_.Run(); 405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4062f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) // Verify that the start time is equal to the lowest timestamp (ie the audio). 4072f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) EXPECT_EQ(demuxer_->GetStartTime().InMicroseconds(), 396000); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that end of stream buffers are created. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240.webm"); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO)); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStreamText) { 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Verify that end of stream buffers are created. 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateDemuxer("bear-vp8-webvtt.webm"); 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DemuxerStream* text_stream = NULL; 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(host_, AddTextStream(_, _)) 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .WillOnce(SaveArg<0>(&text_stream)); 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeDemuxerText(true); 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(text_stream); 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool got_eos_buffer = false; 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int kMaxBuffers = 10; 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) text_stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(got_eos_buffer); 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that end of stream buffers are created. 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDemuxer("bear-320x240.webm"); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_duration_known(false); 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2767))); 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO)); 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::VIDEO)); 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_VideoOnly) { 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify that end of stream buffers are created. 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateDemuxer("bear-320x240-video-only.webm"); 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InitializeDemuxer(); 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_duration_known(false); 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2703))); 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::VIDEO)); 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_AudioOnly) { 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify that end of stream buffers are created. 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateDemuxer("bear-320x240-audio-only.webm"); 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InitializeDemuxer(); 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_duration_known(false); 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(2767))); 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO)); 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration_UnsupportedStream) { 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify that end of stream buffers are created and we don't crash 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // if there are streams in the file that we don't support. 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateDemuxer("vorbis_audio_wmv_video.mkv"); 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InitializeDemuxer(); 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_duration_known(false); 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(1014))); 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO)); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Seek) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're testing that the demuxer frees all queued packets when it receives 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a Seek(). 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240.webm"); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get our streams. 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(video); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(audio); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read a video packet and release it. 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 22084, 0)); 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issue a simple forward seek, which should discard queued packets. 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitableMessageLoopEvent event; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.GetPipelineStatusCB()); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.RunAndWaitForStatus(PIPELINE_OK); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio read #1. 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 145, 803000)); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio read #2. 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 148, 826000)); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Video read #1. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 5425, 801000)); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Video read #2. 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 1906, 834000)); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, SeekText) { 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We're testing that the demuxer frees all queued packets when it receives 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // a Seek(). 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateDemuxer("bear-vp8-webvtt.webm"); 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DemuxerStream* text_stream = NULL; 519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_CALL(host_, AddTextStream(_, _)) 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .WillOnce(SaveArg<0>(&text_stream)); 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeDemuxerText(true); 522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(text_stream); 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); 524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Get our streams. 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(video); 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(audio); 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Read a text packet and release it. 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Issue a simple forward seek, which should discard queued packets. 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WaitableMessageLoopEvent event; 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event.GetPipelineStatusCB()); 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event.RunAndWaitForStatus(PIPELINE_OK); 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Audio read #1. 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 145, 803000)); 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Audio read #2. 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 148, 826000)); 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Video read #1. 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 5425, 801000)); 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Video read #2. 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 1906, 834000)); 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Text read #1. 558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); 559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Text read #2. 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) text_stream->Read(NewReadCB(FROM_HERE, 19, 1000000)); 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_.Run(); 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockReadCB { 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockReadCB() {} 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~MockReadCB() {} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD2(Run, void(DemuxerStream::Status status, 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& buffer)); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MockReadCB); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Stop) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tests that calling Read() on a stopped demuxer stream immediately deletes 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the callback. 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240.webm"); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get our stream. 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(audio); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) WaitableMessageLoopEvent event; 5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) demuxer_->Stop(event.GetClosure()); 5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) event.RunAndWait(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reads after being stopped are all EOS buffers. 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StrictMock<MockReadCB> callback; 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(callback, Run(DemuxerStream::kOk, IsEndOfStreamBuffer())); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt the read... 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) audio->Read(base::Bind(&MockReadCB::Run, base::Unretained(&callback))); 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.RunUntilIdle(); 5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Don't let the test call Stop() again. 6003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) demuxer_.reset(); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that seek works properly when the WebM cues data is at the start of 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the file instead of at the end. 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("bear-320x240-cues-in-front.webm"); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get our streams. 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(video); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(audio); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read a video packet and release it. 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 22084, 0)); 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issue a simple forward seek, which should discard queued packets. 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitableMessageLoopEvent event; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000), 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.GetPipelineStatusCB()); 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.RunAndWaitForStatus(PIPELINE_OK); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio read #1. 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 40, 2403000)); 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio read #2. 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio->Read(NewReadCB(FROM_HERE, 42, 2406000)); 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Video read #1. 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 5276, 2402000)); 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Video read #2. 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video->Read(NewReadCB(FROM_HERE, 1740, 2436000)); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.Run(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure ID3v1 tag reading is disabled. id3_test.mp3 has an ID3v1 tag with the 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// field "title" set to "sample for id3 test". 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, NoID3TagData) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("id3_test.mp3"); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(av_dict_get(format_context()->metadata, "title", NULL, 0)); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 65023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure MP3 files with large image/video based ID3 tags demux okay. FFmpeg 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will hand us a video stream to the data which will likely be in a format we 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// don't accept as video; e.g. PNG. 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, Mp3WithVideoStreamID3TagData) { 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("id3_png_test.mp3"); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the expected streams are present. 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::VIDEO)); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(demuxer_->GetStream(DemuxerStream::AUDIO)); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 66423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure a video with an unsupported audio track still results in the video 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream being demuxed. 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, UnsupportedAudioSupportedVideoDemux) { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("speex_audio_vorbis_video.ogv"); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the expected streams are present. 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(demuxer_->GetStream(DemuxerStream::VIDEO)); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::AUDIO)); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure a video with an unsupported video track still results in the audio 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream being demuxed. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FFmpegDemuxerTest, UnsupportedVideoSupportedAudioDemux) { 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDemuxer("vorbis_audio_wmv_video.mkv"); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeDemuxer(); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the expected streams are present. 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::VIDEO)); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(demuxer_->GetStream(DemuxerStream::AUDIO)); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS) 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// FFmpeg returns null data pointers when samples have zero size, leading to 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// mistakenly creating end of stream buffers http://crbug.com/169133 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) { 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4"); 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InitializeDemuxer(); 6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO)); 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 696010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 697010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 698010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static void ValidateAnnexB(DemuxerStream* stream, 699010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DemuxerStream::Status status, 700010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const scoped_refptr<DecoderBuffer>& buffer) { 701010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_EQ(status, DemuxerStream::kOk); 702010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 703010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (buffer->end_of_stream()) { 704010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoop::current()->PostTask( 705010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 706010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 707010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 708010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 709010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool is_valid = 710010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mp4::AVC::IsValidAnnexB(buffer->data(), buffer->data_size()); 711010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_TRUE(is_valid); 712010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 713010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!is_valid) { 714010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(ERROR) << "Buffer contains invalid Annex B data."; 715010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoop::current()->PostTask( 716010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 717010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 718010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 719010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 720010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) stream->Read(base::Bind(&ValidateAnnexB, stream)); 721010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 722010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 723010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(FFmpegDemuxerTest, IsValidAnnexB) { 724010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const char* files[] = { 725010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "bear-1280x720-av_frag.mp4", 726010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "bear-1280x720-av_with-aud-nalus_frag.mp4" 727010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 728010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 729010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (size_t i = 0; i < arraysize(files); ++i) { 730010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DVLOG(1) << "Testing " << files[i]; 731010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CreateDemuxer(files[i]); 732010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) InitializeDemuxer(); 733010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Ensure the expected streams are present. 735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ASSERT_TRUE(stream); 737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) stream->EnableBitstreamConverter(); 738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) stream->Read(base::Bind(&ValidateAnnexB, stream)); 740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) message_loop_.Run(); 741010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 742010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WaitableMessageLoopEvent event; 743010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) demuxer_->Stop(event.GetClosure()); 744010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) event.RunAndWait(); 745010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) demuxer_.reset(); 746010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) data_source_.reset(); 747010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 748010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 749010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 75023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 753