diff options
author | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 21:28:59 +0000 |
---|---|---|
committer | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 21:28:59 +0000 |
commit | d82b18ae3cf1a5976e85f773e9212431e46146cb (patch) | |
tree | 7547c63a852a7e9164985fedd9de7622a59234a5 /media/base | |
parent | 238ca86df5ced41e7de04492fb547259803a93a4 (diff) | |
download | chromium_src-d82b18ae3cf1a5976e85f773e9212431e46146cb.zip chromium_src-d82b18ae3cf1a5976e85f773e9212431e46146cb.tar.gz chromium_src-d82b18ae3cf1a5976e85f773e9212431e46146cb.tar.bz2 |
Build a raw video pipeline for the <video> with a special src attribute (media://...).
The raw video pipeline graph only has two filters - one pass-thru decoder filter and one renderer filter.
Contributed by ronghuawu@google.com
Original code reviews:
http://codereview.chromium.org/6658001/ (pipeline changes)
http://codereview.chromium.org/6621049/ (pass-thru filter)
BUG=none
TEST=media_unittests
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=79149
Review URL: http://codereview.chromium.org/6726006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79185 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base')
-rw-r--r-- | media/base/mock_filters.cc | 5 | ||||
-rw-r--r-- | media/base/mock_filters.h | 3 | ||||
-rw-r--r-- | media/base/pipeline_impl.cc | 32 | ||||
-rw-r--r-- | media/base/pipeline_impl_unittest.cc | 43 |
4 files changed, 67 insertions, 16 deletions
diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc index 5fc5b55..da601c4 100644 --- a/media/base/mock_filters.cc +++ b/media/base/mock_filters.cc @@ -135,6 +135,7 @@ MockFilterCollection::~MockFilterCollection() {} FilterCollection* MockFilterCollection::filter_collection( bool include_demuxer, bool run_build_callback, + bool run_build, PipelineStatus build_status) const { FilterCollection* collection = new FilterCollection(); @@ -151,7 +152,9 @@ FilterCollection* MockFilterCollection::filter_collection( ON_CALL(*demuxer_factory, Build(_, NotNull())).WillByDefault(Invoke( demuxer_factory, &MockDemuxerFactory::DestroyBuildCallback)); } - EXPECT_CALL(*demuxer_factory, Build(_, NotNull())); + + if (run_build) + EXPECT_CALL(*demuxer_factory, Build(_, NotNull())); collection->SetDemuxerFactory(demuxer_factory); collection->AddVideoDecoder(video_decoder_); diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index c108c57..44d3236 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h @@ -289,11 +289,12 @@ class MockFilterCollection { MockAudioRenderer* audio_renderer() const { return audio_renderer_; } FilterCollection* filter_collection() const { - return filter_collection(true, true, PIPELINE_OK); + return filter_collection(true, true, true, PIPELINE_OK); } FilterCollection* filter_collection(bool include_demuxer, bool run_build_callback, + bool run_build, PipelineStatus build_status) const; private: diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index 2b66661..7f5f3f3 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc @@ -5,14 +5,18 @@ // TODO(scherkus): clean up PipelineImpl... too many crazy function names, // potential deadlocks, etc... +#include "media/base/pipeline_impl.h" + +#include <algorithm> + #include "base/callback.h" #include "base/compiler_specific.h" #include "base/stl_util-inl.h" #include "base/synchronization/condition_variable.h" +#include "media/filters/rtc_video_decoder.h" #include "media/base/clock.h" #include "media/base/filter_collection.h" #include "media/base/media_format.h" -#include "media/base/pipeline_impl.h" namespace media { @@ -578,12 +582,17 @@ void PipelineImpl::StartTask(FilterCollection* filter_collection, seek_callback_.reset(start_callback); // Kick off initialization. - set_state(kInitDemuxer); pipeline_init_state_.reset(new PipelineInitState()); pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); pipeline_init_state_->composite_->set_host(this); - InitializeDemuxer(); + if (RTCVideoDecoder::IsUrlSupported(url)) { + set_state(kInitVideoDecoder); + InitializeVideoDecoder(NULL); + } else { + set_state(kInitDemuxer); + InitializeDemuxer(); + } } // Main initialization method called on the pipeline thread. This code attempts @@ -914,7 +923,7 @@ void PipelineImpl::FilterStateTransitionTask() { NewCallback(this, &PipelineImpl::OnFilterStateTransition)); } else if (state_ == kStarting) { pipeline_filter_->Play( - NewCallback(this,&PipelineImpl::OnFilterStateTransition)); + NewCallback(this, &PipelineImpl::OnFilterStateTransition)); } else if (state_ == kStopping) { pipeline_filter_->Stop( NewCallback(this, &PipelineImpl::OnFilterStateTransition)); @@ -946,7 +955,7 @@ void PipelineImpl::FilterStateTransitionTask() { void PipelineImpl::TeardownStateTransitionTask() { DCHECK(IsPipelineTearingDown()); - switch(state_) { + switch (state_) { case kStopping: set_state(error_caused_teardown_ ? kError : kStopped); FinishDestroyingFiltersTask(); @@ -1087,11 +1096,14 @@ bool PipelineImpl::InitializeVideoDecoder( DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(IsPipelineOk()); - scoped_refptr<DemuxerStream> stream = - demuxer->GetStream(DemuxerStream::VIDEO); + scoped_refptr<DemuxerStream> stream; - if (!stream) - return false; + if (demuxer) { + stream = demuxer->GetStream(DemuxerStream::VIDEO); + + if (!stream) + return false; + } scoped_refptr<VideoDecoder> video_decoder; filter_collection_->SelectVideoDecoder(&video_decoder); @@ -1169,7 +1181,7 @@ void PipelineImpl::TearDownPipeline() { // Mark that we already start tearing down operation. tearing_down_ = true; - switch(state_) { + switch (state_) { case kCreated: case kError: set_state(kStopped); diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index 396b69c..87f3e96 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc @@ -33,6 +33,9 @@ static const int kTotalBytes = 1024; // Buffered bytes of the data source. static const int kBufferedBytes = 1024; +// Test url for raw video pipeline. +static const std::string kUrlMedia = "media://raw_video_stream"; + // Used for setting expectations on pipeline callbacks. Using a StrictMock // also lets us test for missing callbacks. class CallbackHelper { @@ -187,11 +190,27 @@ class PipelineImplTest : public ::testing::Test { // But some tests require different statuses in build & Start. void InitializePipeline(PipelineStatus build_status, PipelineStatus start_status) { + InitializePipeline(build_status, start_status, ""); + } + + void InitializePipeline(PipelineStatus build_status, + PipelineStatus start_status, + const std::string& url) { // Expect an initialization callback. EXPECT_CALL(callbacks_, OnStart(start_status)); - pipeline_->Start(mocks_->filter_collection(true, true, build_status), "", + + bool run_build = true; + if (url.compare(kUrlMedia) == 0) + run_build = false; + + pipeline_->Start(mocks_->filter_collection(true, + true, + run_build, + build_status), + url, NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), &CallbackHelper::OnStart)); + message_loop_.RunAllPending(); } @@ -232,7 +251,6 @@ class PipelineImplTest : public ::testing::Test { // We expect a successful seek callback. EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); - } void DoSeek(const base::TimeDelta& seek_time) { @@ -309,7 +327,11 @@ TEST_F(PipelineImplTest, NeverInitializes) { // This test hangs during initialization by never calling // InitializationComplete(). StrictMock<> will ensure that the callback is // never executed. - pipeline_->Start(mocks_->filter_collection(false, false, PIPELINE_OK), "", + pipeline_->Start(mocks_->filter_collection(false, + false, + true, + PIPELINE_OK), + "", NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), &CallbackHelper::OnStart)); message_loop_.RunAllPending(); @@ -333,7 +355,9 @@ TEST_F(PipelineImplTest, RequiredFilterMissing) { // Create a filter collection with missing filter. FilterCollection* collection = - mocks_->filter_collection(false, true, + mocks_->filter_collection(false, + true, + true, PIPELINE_ERROR_REQUIRED_FILTER_MISSING); pipeline_->Start(collection, "", NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), @@ -396,6 +420,16 @@ TEST_F(PipelineImplTest, VideoStream) { EXPECT_TRUE(pipeline_->HasVideo()); } +TEST_F(PipelineImplTest, RawVideoStream) { + InitializeVideoDecoder(NULL); + InitializeVideoRenderer(); + + InitializePipeline(PIPELINE_OK, PIPELINE_OK, kUrlMedia); + EXPECT_TRUE(pipeline_->IsInitialized()); + EXPECT_FALSE(pipeline_->HasAudio()); + EXPECT_TRUE(pipeline_->HasVideo()); +} + TEST_F(PipelineImplTest, AudioVideoStream) { CreateAudioStream(); CreateVideoStream(); @@ -816,3 +850,4 @@ TEST(PipelineStatusNotificationTest, DelayedCallback) { } } // namespace media + |