Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Unified Diff: media/base/composite_filter.cc

Issue 10796074: Move VideoRenderer out of Filter heirarchy. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: GetMediaTime Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/composite_filter.h ('k') | media/base/composite_filter_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/composite_filter.cc
diff --git a/media/base/composite_filter.cc b/media/base/composite_filter.cc
deleted file mode 100644
index 21bad5cb1f1976f00b74184945d20ef945f83956..0000000000000000000000000000000000000000
--- a/media/base/composite_filter.cc
+++ /dev/null
@@ -1,471 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/base/composite_filter.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
-#include "base/location.h"
-#include "base/message_loop_proxy.h"
-#include "base/stl_util.h"
-
-namespace media {
-
-class CompositeFilter::FilterHostImpl : public FilterHost {
- public:
- FilterHostImpl(CompositeFilter* parent, FilterHost* host);
-
- FilterHost* host();
-
- // media::FilterHost methods.
- virtual void SetError(PipelineStatus error) OVERRIDE;
- virtual base::TimeDelta GetTime() const OVERRIDE;
- virtual base::TimeDelta GetDuration() const OVERRIDE;
- virtual void SetNaturalVideoSize(const gfx::Size& size) OVERRIDE;
- virtual void NotifyEnded() OVERRIDE;
-
- private:
- CompositeFilter* parent_;
- FilterHost* host_;
-
- DISALLOW_COPY_AND_ASSIGN(FilterHostImpl);
-};
-
-CompositeFilter::CompositeFilter(
- const scoped_refptr<base::MessageLoopProxy>& message_loop)
- : state_(kCreated),
- sequence_index_(0),
- message_loop_(message_loop),
- status_(PIPELINE_OK),
- weak_ptr_factory_(this) {
- DCHECK(message_loop);
-}
-
-CompositeFilter::~CompositeFilter() {
- DCHECK(message_loop_->BelongsToCurrentThread());
- DCHECK(state_ == kCreated || state_ == kStopped);
-
- filters_.clear();
-}
-
-void CompositeFilter::AddFilter(scoped_refptr<Filter> filter) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- CHECK(filter && state_ == kCreated && host());
-
- // Register ourselves as the filter's host.
- filter->SetHost(host_impl_.get());
- filters_.push_back(make_scoped_refptr(filter.get()));
-}
-
-void CompositeFilter::SetHost(FilterHost* host) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- DCHECK(host);
- DCHECK(!host_impl_.get());
- host_impl_.reset(new FilterHostImpl(this, host));
-}
-
-void CompositeFilter::Play(const base::Closure& play_cb) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- if (IsOperationPending()) {
- SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
- play_cb.Run();
- return;
- } else if (state_ == kPlaying) {
- play_cb.Run();
- return;
- } else if (!host() || (state_ != kPaused && state_ != kCreated)) {
- SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
- play_cb.Run();
- return;
- }
-
- ChangeState(kPlayPending);
- callback_ = play_cb;
- StartSerialCallSequence();
-}
-
-void CompositeFilter::Pause(const base::Closure& pause_cb) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- if (IsOperationPending()) {
- SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
- pause_cb.Run();
- return;
- } else if (state_ == kPaused) {
- pause_cb.Run();
- return;
- } else if (!host() || state_ != kPlaying) {
- SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
- pause_cb.Run();
- return;
- }
-
- ChangeState(kPausePending);
- callback_ = pause_cb;
- StartSerialCallSequence();
-}
-
-void CompositeFilter::Flush(const base::Closure& flush_cb) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- if (IsOperationPending()) {
- SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
- flush_cb.Run();
- return;
- } else if (!host() || (state_ != kCreated && state_ != kPaused)) {
- SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
- flush_cb.Run();
- return;
- }
-
- ChangeState(kFlushPending);
- callback_ = flush_cb;
- StartParallelCallSequence();
-}
-
-void CompositeFilter::Stop(const base::Closure& stop_cb) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- if (!host()) {
- SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
- stop_cb.Run();
- return;
- } else if (state_ == kStopped) {
- stop_cb.Run();
- return;
- }
-
- switch (state_) {
- case kError:
- case kCreated:
- case kPaused:
- case kPlaying:
- ChangeState(kStopPending);
- break;
- case kPlayPending:
- ChangeState(kStopWhilePlayPending);
- break;
- case kPausePending:
- ChangeState(kStopWhilePausePending);
- break;
- case kFlushPending:
- ChangeState(kStopWhileFlushPending);
- break;
- case kSeekPending:
- ChangeState(kStopWhileSeekPending);
- break;
- default:
- SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
- stop_cb.Run();
- return;
- }
-
- if (!status_cb_.is_null()) {
- DCHECK_EQ(state_, kStopWhileSeekPending);
- status_cb_.Reset();
- }
-
- callback_ = stop_cb;
- if (state_ == kStopPending) {
- StartSerialCallSequence();
- }
-}
-
-void CompositeFilter::SetPlaybackRate(float playback_rate) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- for (FilterVector::iterator iter = filters_.begin();
- iter != filters_.end();
- ++iter) {
- (*iter)->SetPlaybackRate(playback_rate);
- }
-}
-
-void CompositeFilter::Seek(base::TimeDelta time,
- const PipelineStatusCB& seek_cb) {
- DCHECK(message_loop_->BelongsToCurrentThread());
-
- if (IsOperationPending()) {
- seek_cb.Run(PIPELINE_ERROR_OPERATION_PENDING);
- return;
- } else if (!host() || (state_ != kPaused && state_ != kCreated)) {
- seek_cb.Run(PIPELINE_ERROR_INVALID_STATE);
- return;
- }
-
- ChangeState(kSeekPending);
- status_cb_ = seek_cb;
- pending_seek_time_ = time;
- StartSerialCallSequence();
-}
-
-void CompositeFilter::ChangeState(State new_state) {
- DCHECK(message_loop_->BelongsToCurrentThread());
- state_ = new_state;
-}
-
-void CompositeFilter::StartSerialCallSequence() {
- DCHECK(message_loop_->BelongsToCurrentThread());
- status_ = PIPELINE_OK;
- sequence_index_ = 0;
-
- if (!filters_.empty()) {
- CallFilter(filters_[sequence_index_],
- NewThreadSafeCallback(&CompositeFilter::SerialCallback));
- } else {
- SerialCallback();
- }
-}
-
-void CompositeFilter::StartParallelCallSequence() {
- DCHECK(message_loop_->BelongsToCurrentThread());
- status_ = PIPELINE_OK;
- sequence_index_ = 0;
-
- if (!filters_.empty()) {
- for (size_t i = 0; i < filters_.size(); i++) {
- CallFilter(filters_[i],
- NewThreadSafeCallback(&CompositeFilter::ParallelCallback));
- }
- } else {
- ParallelCallback();
- }
-}
-
-void CompositeFilter::CallFilter(scoped_refptr<Filter>& filter,
- const base::Closure& callback) {
- switch (state_) {
- case kPlayPending:
- filter->Play(callback);
- break;
- case kPausePending:
- filter->Pause(callback);
- break;
- case kFlushPending:
- filter->Flush(callback);
- break;
- case kStopPending:
- filter->Stop(callback);
- break;
- case kSeekPending:
- filter->Seek(pending_seek_time_,
- base::Bind(&CompositeFilter::OnStatusCB, this, callback));
- break;
- default:
- ChangeState(kError);
- DispatchPendingCallback(PIPELINE_ERROR_INVALID_STATE);
- }
-}
-
-void CompositeFilter::DispatchPendingCallback(PipelineStatus status) {
- DCHECK(status_cb_.is_null() ^ callback_.is_null());
-
- if (!status_cb_.is_null()) {
- base::ResetAndReturn(&status_cb_).Run(status);
- return;
- }
-
- if (!callback_.is_null()) {
- if (status != PIPELINE_OK)
- SendErrorToHost(status);
- base::ResetAndReturn(&callback_).Run();
- }
-}
-
-CompositeFilter::State CompositeFilter::GetNextState(State state) const {
- State ret = kInvalid;
- switch (state) {
- case kPlayPending:
- ret = kPlaying;
- break;
- case kPausePending:
- case kFlushPending:
- ret = kPaused;
- break;
- case kStopPending:
- ret = kStopped;
- break;
- case kSeekPending:
- ret = kPaused;
- break;
- case kStopWhilePlayPending:
- case kStopWhilePausePending:
- case kStopWhileFlushPending:
- case kStopWhileSeekPending:
- ret = kStopPending;
- break;
-
- case kInvalid:
- case kCreated:
- case kPlaying:
- case kPaused:
- case kStopped:
- case kError:
- ret = kInvalid;
- break;
-
- // default: intentionally left out to catch missing states.
- }
-
- return ret;
-}
-
-void CompositeFilter::SerialCallback() {
- DCHECK(message_loop_->BelongsToCurrentThread());
- if (status_ != PIPELINE_OK) {
- // We encountered an error. Terminate the sequence now.
- ChangeState(kError);
- DispatchPendingCallback(status_);
- return;
- }
- if (!filters_.empty())
- sequence_index_++;
-
- if (sequence_index_ == filters_.size()) {
- // All filters have been successfully called without error.
- OnCallSequenceDone();
- } else if (GetNextState(state_) == kStopPending) {
- // Abort sequence early and start issuing Stop() calls.
- ChangeState(kStopPending);
- StartSerialCallSequence();
- } else {
- // We aren't done with the sequence. Call the next filter.
- CallFilter(filters_[sequence_index_],
- NewThreadSafeCallback(&CompositeFilter::SerialCallback));
- }
-}
-
-void CompositeFilter::ParallelCallback() {
- DCHECK(message_loop_->BelongsToCurrentThread());
-
- if (!filters_.empty())
- sequence_index_++;
-
- if (sequence_index_ == filters_.size()) {
- if (status_ != PIPELINE_OK) {
- // We encountered an error.
- ChangeState(kError);
- DispatchPendingCallback(status_);
- return;
- }
-
- OnCallSequenceDone();
- }
-}
-
-void CompositeFilter::OnCallSequenceDone() {
- State next_state = GetNextState(state_);
- if (next_state == kInvalid) {
- // We somehow got into an unexpected state.
- ChangeState(kError);
- DispatchPendingCallback(PIPELINE_ERROR_INVALID_STATE);
- return;
- }
-
- ChangeState(next_state);
-
- if (state_ == kStopPending) {
- // Handle a deferred Stop().
- StartSerialCallSequence();
- } else {
- // Call the callback to indicate that the operation has completed.
- DispatchPendingCallback(PIPELINE_OK);
- }
-}
-
-void CompositeFilter::SendErrorToHost(PipelineStatus error) {
- if (host_impl_.get())
- host_impl_.get()->host()->SetError(error);
-}
-
-// Execute |closure| if on |message_loop|, otherwise post to it.
-static void TrampolineClosureIfNecessary(
- const scoped_refptr<base::MessageLoopProxy>& message_loop,
- const base::Closure& closure) {
- if (message_loop->BelongsToCurrentThread())
- closure.Run();
- else
- message_loop->PostTask(FROM_HERE, closure);
-}
-
-base::Closure CompositeFilter::NewThreadSafeCallback(
- void (CompositeFilter::*method)()) {
- return base::Bind(&TrampolineClosureIfNecessary,
- message_loop_,
- base::Bind(method, weak_ptr_factory_.GetWeakPtr()));
-}
-
-bool CompositeFilter::CanForwardError() {
- return (state_ == kCreated) || (state_ == kPlaying) || (state_ == kPaused);
-}
-
-bool CompositeFilter::IsOperationPending() const {
- DCHECK(callback_.is_null() || status_cb_.is_null());
-
- return !callback_.is_null() || !status_cb_.is_null();
-}
-
-void CompositeFilter::OnStatusCB(const base::Closure& callback,
- PipelineStatus status) {
- if (status != PIPELINE_OK)
- SetError(status);
-
- callback.Run();
-}
-
-FilterHost* CompositeFilter::host() {
- return host_impl_.get() ? host_impl_.get()->host() : NULL;
-}
-
-void CompositeFilter::SetError(PipelineStatus error) {
- if (!message_loop_->BelongsToCurrentThread()) {
- message_loop_->PostTask(FROM_HERE,
- base::Bind(&CompositeFilter::SetError, this, error));
- return;
- }
-
- DCHECK(message_loop_->BelongsToCurrentThread());
- DCHECK_NE(state_, kCreated);
-
- // Drop errors recieved while stopping or stopped.
- // This shields the owner of this object from having
- // to deal with errors it can't do anything about.
- if (state_ == kStopPending || state_ == kStopped)
- return;
-
- status_ = error;
- if (CanForwardError())
- SendErrorToHost(error);
-}
-
-CompositeFilter::FilterHostImpl::FilterHostImpl(CompositeFilter* parent,
- FilterHost* host)
- : parent_(parent),
- host_(host) {
-}
-
-FilterHost* CompositeFilter::FilterHostImpl::host() {
- return host_;
-}
-
-// media::FilterHost methods.
-void CompositeFilter::FilterHostImpl::SetError(PipelineStatus error) {
- parent_->SetError(error);
-}
-
-base::TimeDelta CompositeFilter::FilterHostImpl::GetTime() const {
- return host_->GetTime();
-}
-
-base::TimeDelta CompositeFilter::FilterHostImpl::GetDuration() const {
- return host_->GetDuration();
-}
-
-void CompositeFilter::FilterHostImpl::SetNaturalVideoSize(
- const gfx::Size& size) {
- host_->SetNaturalVideoSize(size);
-}
-
-void CompositeFilter::FilterHostImpl::NotifyEnded() {
- host_->NotifyEnded();
-}
-
-} // namespace media
« no previous file with comments | « media/base/composite_filter.h ('k') | media/base/composite_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698