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) |