summaryrefslogtreecommitdiffstats
path: root/media/base
diff options
context:
space:
mode:
authoracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 21:28:59 +0000
committeracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 21:28:59 +0000
commitd82b18ae3cf1a5976e85f773e9212431e46146cb (patch)
tree7547c63a852a7e9164985fedd9de7622a59234a5 /media/base
parent238ca86df5ced41e7de04492fb547259803a93a4 (diff)
downloadchromium_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.cc5
-rw-r--r--media/base/mock_filters.h3
-rw-r--r--media/base/pipeline_impl.cc32
-rw-r--r--media/base/pipeline_impl_unittest.cc43
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
+