Chromium Code Reviews| Index: media/filters/adaptive_demuxer.cc |
| diff --git a/media/filters/adaptive_demuxer.cc b/media/filters/adaptive_demuxer.cc |
| index 9a94d11bbd797606ab9035571ece8d1201ba60bf..edbff044bed02c9aa648183f8f59fab2624dcc01 100644 |
| --- a/media/filters/adaptive_demuxer.cc |
| +++ b/media/filters/adaptive_demuxer.cc |
| @@ -2,6 +2,7 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +#include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/string_number_conversions.h" |
| #include "base/string_split.h" |
| @@ -191,6 +192,53 @@ class CountingCallback { |
| scoped_ptr<FilterCallback> orig_cb_; |
| }; |
| +// Helper class that wraps FilterStatusCB and expects to get called a set |
|
Ami GONE FROM CHROMIUM
2011/05/12 20:42:16
Sad panda that this has to coexist w/ CountingCall
acolwell GONE FROM CHROMIUM
2011/05/12 22:30:40
Agreed. It won't last too long. Once I convert Sto
|
| +// number of times, after which the wrapped callback is fired. If an error |
| +// is reported in any of the callbacks, only the first error code is passed |
| +// to the wrapped callback. |
| +class CountingStatusCB { |
| + public: |
| + CountingStatusCB(int count, const FilterStatusCB& orig_cb) |
| + : remaining_count_(count), orig_cb_(orig_cb), |
| + overall_status_(PIPELINE_OK) { |
| + DCHECK_GT(remaining_count_, 0); |
| + DCHECK(!orig_cb.is_null()); |
| + } |
| + |
| + FilterStatusCB GetACallback() { |
| + return base::Bind(&CountingStatusCB::OnChildCallbackDone, |
| + base::Unretained(this)); |
|
Ami GONE FROM CHROMIUM
2011/05/12 20:42:16
I think if you drop the unretained then you can al
acolwell GONE FROM CHROMIUM
2011/05/12 22:30:40
Yes. I had to derive from RefCountedThreadSafe<> t
|
| + } |
| + |
| + private: |
| + void OnChildCallbackDone(PipelineStatus status) { |
| + bool fire_orig_cb = false; |
| + PipelineStatus overall_status = PIPELINE_OK; |
| + |
| + { |
| + base::AutoLock auto_lock(lock_); |
| + |
| + if (overall_status_ == PIPELINE_OK && status != PIPELINE_OK) |
| + overall_status_ = status; |
| + |
| + if (--remaining_count_ == 0) { |
| + fire_orig_cb = true; |
| + overall_status = overall_status_; |
| + } |
| + } |
| + |
| + if (fire_orig_cb) { |
| + orig_cb_.Run(overall_status); |
| + delete this; |
| + } |
| + } |
| + |
| + base::Lock lock_; |
| + int remaining_count_; |
| + FilterStatusCB orig_cb_; |
| + PipelineStatus overall_status_; |
| +}; |
| + |
| void AdaptiveDemuxer::Stop(FilterCallback* callback) { |
| // Stop() must be called on all of the demuxers even though only one demuxer |
| // is actively delivering audio and another one is delivering video. This |
| @@ -201,11 +249,11 @@ void AdaptiveDemuxer::Stop(FilterCallback* callback) { |
| demuxers_[i]->Stop(wrapper->GetACallback()); |
| } |
| -void AdaptiveDemuxer::Seek(base::TimeDelta time, FilterCallback* callback) { |
| +void AdaptiveDemuxer::Seek(base::TimeDelta time, const FilterStatusCB& cb) { |
| Demuxer* audio = current_demuxer(DemuxerStream::AUDIO); |
| Demuxer* video = current_demuxer(DemuxerStream::VIDEO); |
| int count = (audio ? 1 : 0) + (video && audio != video ? 1 : 0); |
| - CountingCallback* wrapper = new CountingCallback(count, callback); |
| + CountingStatusCB* wrapper = new CountingStatusCB(count, cb); |
| if (audio) |
| audio->Seek(time, wrapper->GetACallback()); |
| if (video && audio != video) |