| Index: media/base/composite_filter.cc
|
| diff --git a/media/base/composite_filter.cc b/media/base/composite_filter.cc
|
| index 537d26231bd39d1f236b41b0fb082c44af09e6cf..134aa4f43bc3c9e779304bb7d367fbc58d6a456b 100644
|
| --- a/media/base/composite_filter.cc
|
| +++ b/media/base/composite_filter.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "media/base/composite_filter.h"
|
|
|
| +#include "base/bind.h"
|
| #include "base/message_loop.h"
|
| #include "base/stl_util-inl.h"
|
| #include "media/base/callback.h"
|
| @@ -83,7 +84,7 @@ FilterHost* CompositeFilter::host() {
|
| void CompositeFilter::Play(FilterCallback* play_callback) {
|
| DCHECK_EQ(message_loop_, MessageLoop::current());
|
| scoped_ptr<FilterCallback> callback(play_callback);
|
| - if (callback_.get()) {
|
| + if (IsOperationPending()) {
|
| SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
|
| callback->Run();
|
| return;
|
| @@ -104,7 +105,7 @@ void CompositeFilter::Play(FilterCallback* play_callback) {
|
| void CompositeFilter::Pause(FilterCallback* pause_callback) {
|
| DCHECK_EQ(message_loop_, MessageLoop::current());
|
| scoped_ptr<FilterCallback> callback(pause_callback);
|
| - if (callback_.get()) {
|
| + if (IsOperationPending()) {
|
| SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
|
| callback->Run();
|
| return;
|
| @@ -125,7 +126,7 @@ void CompositeFilter::Pause(FilterCallback* pause_callback) {
|
| void CompositeFilter::Flush(FilterCallback* flush_callback) {
|
| DCHECK_EQ(message_loop_, MessageLoop::current());
|
| scoped_ptr<FilterCallback> callback(flush_callback);
|
| - if (callback_.get()) {
|
| + if (IsOperationPending()) {
|
| SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
|
| callback->Run();
|
| return;
|
| @@ -193,21 +194,19 @@ void CompositeFilter::SetPlaybackRate(float playback_rate) {
|
| }
|
|
|
| void CompositeFilter::Seek(base::TimeDelta time,
|
| - FilterCallback* seek_callback) {
|
| + const FilterStatusCB& seek_cb) {
|
| DCHECK_EQ(message_loop_, MessageLoop::current());
|
| - scoped_ptr<FilterCallback> callback(seek_callback);
|
| - if (callback_.get()) {
|
| - SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
|
| - callback->Run();
|
| +
|
| + if (IsOperationPending()) {
|
| + seek_cb.Run(PIPELINE_ERROR_OPERATION_PENDING);
|
| return;
|
| } else if (!host() || (state_ != kPaused && state_ != kCreated)) {
|
| - SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
|
| - callback->Run();
|
| + seek_cb.Run(PIPELINE_ERROR_INVALID_STATE);
|
| return;
|
| }
|
|
|
| ChangeState(kSeekPending);
|
| - callback_.reset(callback.release());
|
| + status_cb_ = seek_cb;
|
| pending_seek_time_ = time;
|
| StartSerialCallSequence();
|
| }
|
| @@ -229,13 +228,12 @@ void CompositeFilter::ChangeState(State new_state) {
|
| void CompositeFilter::StartSerialCallSequence() {
|
| DCHECK_EQ(message_loop_, MessageLoop::current());
|
| status_ = PIPELINE_OK;
|
| + sequence_index_ = 0;
|
|
|
| if (!filters_.empty()) {
|
| - sequence_index_ = 0;
|
| CallFilter(filters_[sequence_index_],
|
| NewThreadSafeCallback(&CompositeFilter::SerialCallback));
|
| } else {
|
| - sequence_index_ = 0;
|
| SerialCallback();
|
| }
|
| }
|
| @@ -243,15 +241,14 @@ void CompositeFilter::StartSerialCallSequence() {
|
| void CompositeFilter::StartParallelCallSequence() {
|
| DCHECK_EQ(message_loop_, MessageLoop::current());
|
| status_ = PIPELINE_OK;
|
| + sequence_index_ = 0;
|
|
|
| if (!filters_.empty()) {
|
| - sequence_index_ = 0;
|
| for (size_t i = 0; i < filters_.size(); i++) {
|
| CallFilter(filters_[i],
|
| NewThreadSafeCallback(&CompositeFilter::ParallelCallback));
|
| }
|
| } else {
|
| - sequence_index_ = 0;
|
| ParallelCallback();
|
| }
|
| }
|
| @@ -272,17 +269,29 @@ void CompositeFilter::CallFilter(scoped_refptr<Filter>& filter,
|
| filter->Stop(callback);
|
| break;
|
| case kSeekPending:
|
| - filter->Seek(pending_seek_time_, callback);
|
| + filter->Seek(pending_seek_time_,
|
| + base::Bind(&CompositeFilter::OnStatusCB, this, callback));
|
| break;
|
| default:
|
| delete callback;
|
| ChangeState(kError);
|
| - HandleError(PIPELINE_ERROR_INVALID_STATE);
|
| + DispatchPendingCallback(PIPELINE_ERROR_INVALID_STATE);
|
| }
|
| }
|
|
|
| -void CompositeFilter::DispatchPendingCallback() {
|
| +void CompositeFilter::DispatchPendingCallback(PipelineStatus status) {
|
| + DCHECK((status_cb_.is_null() && callback_.get()) ||
|
| + (!status_cb_.is_null() && !callback_.get()));
|
| +
|
| + if (!status_cb_.is_null()) {
|
| + RunAndResetCB(&status_cb_, status);
|
| + return;
|
| + }
|
| +
|
| if (callback_.get()) {
|
| + if (status != PIPELINE_OK)
|
| + SendErrorToHost(status);
|
| +
|
| scoped_ptr<FilterCallback> callback(callback_.release());
|
| callback->Run();
|
| }
|
| @@ -331,7 +340,7 @@ void CompositeFilter::SerialCallback() {
|
| if (status_ != PIPELINE_OK) {
|
| // We encountered an error. Terminate the sequence now.
|
| ChangeState(kError);
|
| - HandleError(status_);
|
| + DispatchPendingCallback(status_);
|
| return;
|
| }
|
|
|
| @@ -362,7 +371,7 @@ void CompositeFilter::ParallelCallback() {
|
| if (status_ != PIPELINE_OK) {
|
| // We encountered an error.
|
| ChangeState(kError);
|
| - HandleError(status_);
|
| + DispatchPendingCallback(status_);
|
| return;
|
| }
|
|
|
| @@ -376,7 +385,8 @@ void CompositeFilter::OnCallSequenceDone() {
|
| if (next_state == kInvalid) {
|
| // We somehow got into an unexpected state.
|
| ChangeState(kError);
|
| - HandleError(PIPELINE_ERROR_INVALID_STATE);
|
| + DispatchPendingCallback(PIPELINE_ERROR_INVALID_STATE);
|
| + return;
|
| }
|
|
|
| ChangeState(next_state);
|
| @@ -386,7 +396,7 @@ void CompositeFilter::OnCallSequenceDone() {
|
| StartSerialCallSequence();
|
| } else {
|
| // Call the callback to indicate that the operation has completed.
|
| - DispatchPendingCallback();
|
| + DispatchPendingCallback(PIPELINE_OK);
|
| }
|
| }
|
|
|
| @@ -395,12 +405,6 @@ void CompositeFilter::SendErrorToHost(PipelineStatus error) {
|
| host_impl_.get()->host()->SetError(error);
|
| }
|
|
|
| -void CompositeFilter::HandleError(PipelineStatus error) {
|
| - DCHECK_NE(error, PIPELINE_OK);
|
| - SendErrorToHost(error);
|
| - DispatchPendingCallback();
|
| -}
|
| -
|
| FilterCallback* CompositeFilter::NewThreadSafeCallback(
|
| void (CompositeFilter::*method)()) {
|
| return TaskToCallbackAdapter::NewCallback(
|
| @@ -432,6 +436,21 @@ bool CompositeFilter::CanForwardError() {
|
| return (state_ == kCreated) || (state_ == kPlaying) || (state_ == kPaused);
|
| }
|
|
|
| +bool CompositeFilter::IsOperationPending() const {
|
| + DCHECK(!(callback_.get() && !status_cb_.is_null()));
|
| +
|
| + return callback_.get() || !status_cb_.is_null();
|
| +}
|
| +
|
| +void CompositeFilter::OnStatusCB(FilterCallback* callback,
|
| + PipelineStatus status) {
|
| + if (status != PIPELINE_OK)
|
| + SetError(status);
|
| +
|
| + callback->Run();
|
| + delete callback;
|
| +}
|
| +
|
| void CompositeFilter::SetError(PipelineStatus error) {
|
| // TODO(acolwell): Temporary hack to handle errors that occur
|
| // during filter initialization. In this case we just forward
|
|
|