OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "base/bind.h" |
5 #include "base/logging.h" | 6 #include "base/logging.h" |
6 #include "base/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
7 #include "base/string_split.h" | 8 #include "base/string_split.h" |
8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
9 #include "media/filters/adaptive_demuxer.h" | 10 #include "media/filters/adaptive_demuxer.h" |
10 | 11 |
11 namespace media { | 12 namespace media { |
12 | 13 |
13 // | 14 // |
14 // AdaptiveDemuxerStream | 15 // AdaptiveDemuxerStream |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 return (current_video_demuxer_index_ < 0) ? NULL : | 154 return (current_video_demuxer_index_ < 0) ? NULL : |
154 demuxers_[current_video_demuxer_index_]; | 155 demuxers_[current_video_demuxer_index_]; |
155 default: | 156 default: |
156 LOG(DFATAL) << "Unexpected type: " << type; | 157 LOG(DFATAL) << "Unexpected type: " << type; |
157 return NULL; | 158 return NULL; |
158 } | 159 } |
159 } | 160 } |
160 | 161 |
161 // Helper class that wraps a FilterCallback and expects to get called a set | 162 // Helper class that wraps a FilterCallback and expects to get called a set |
162 // number of times, after which the wrapped callback is fired (and deleted). | 163 // number of times, after which the wrapped callback is fired (and deleted). |
| 164 // |
| 165 // TODO: Remove this class once Stop() is converted to FilterStatusCB. |
163 class CountingCallback { | 166 class CountingCallback { |
164 public: | 167 public: |
165 CountingCallback(int count, FilterCallback* orig_cb) | 168 CountingCallback(int count, FilterCallback* orig_cb) |
166 : remaining_count_(count), orig_cb_(orig_cb) { | 169 : remaining_count_(count), orig_cb_(orig_cb) { |
167 DCHECK_GT(remaining_count_, 0); | 170 DCHECK_GT(remaining_count_, 0); |
168 DCHECK(orig_cb); | 171 DCHECK(orig_cb); |
169 } | 172 } |
170 | 173 |
171 FilterCallback* GetACallback() { | 174 FilterCallback* GetACallback() { |
172 return NewCallback(this, &CountingCallback::OnChildCallbackDone); | 175 return NewCallback(this, &CountingCallback::OnChildCallbackDone); |
(...skipping 11 matching lines...) Expand all Loading... |
184 orig_cb_->Run(); | 187 orig_cb_->Run(); |
185 delete this; | 188 delete this; |
186 } | 189 } |
187 } | 190 } |
188 | 191 |
189 base::Lock lock_; | 192 base::Lock lock_; |
190 int remaining_count_; | 193 int remaining_count_; |
191 scoped_ptr<FilterCallback> orig_cb_; | 194 scoped_ptr<FilterCallback> orig_cb_; |
192 }; | 195 }; |
193 | 196 |
| 197 // Helper class that wraps FilterStatusCB and expects to get called a set |
| 198 // number of times, after which the wrapped callback is fired. If an error |
| 199 // is reported in any of the callbacks, only the first error code is passed |
| 200 // to the wrapped callback. |
| 201 class CountingStatusCB : public base::RefCountedThreadSafe<CountingStatusCB> { |
| 202 public: |
| 203 CountingStatusCB(int count, const FilterStatusCB& orig_cb) |
| 204 : remaining_count_(count), orig_cb_(orig_cb), |
| 205 overall_status_(PIPELINE_OK) { |
| 206 DCHECK_GT(remaining_count_, 0); |
| 207 DCHECK(!orig_cb.is_null()); |
| 208 } |
| 209 |
| 210 FilterStatusCB GetACallback() { |
| 211 return base::Bind(&CountingStatusCB::OnChildCallbackDone, this); |
| 212 } |
| 213 |
| 214 private: |
| 215 void OnChildCallbackDone(PipelineStatus status) { |
| 216 bool fire_orig_cb = false; |
| 217 PipelineStatus overall_status = PIPELINE_OK; |
| 218 |
| 219 { |
| 220 base::AutoLock auto_lock(lock_); |
| 221 |
| 222 if (overall_status_ == PIPELINE_OK && status != PIPELINE_OK) |
| 223 overall_status_ = status; |
| 224 |
| 225 if (--remaining_count_ == 0) { |
| 226 fire_orig_cb = true; |
| 227 overall_status = overall_status_; |
| 228 } |
| 229 } |
| 230 |
| 231 if (fire_orig_cb) |
| 232 orig_cb_.Run(overall_status); |
| 233 } |
| 234 |
| 235 base::Lock lock_; |
| 236 int remaining_count_; |
| 237 FilterStatusCB orig_cb_; |
| 238 PipelineStatus overall_status_; |
| 239 |
| 240 DISALLOW_COPY_AND_ASSIGN(CountingStatusCB); |
| 241 }; |
| 242 |
194 void AdaptiveDemuxer::Stop(FilterCallback* callback) { | 243 void AdaptiveDemuxer::Stop(FilterCallback* callback) { |
195 // Stop() must be called on all of the demuxers even though only one demuxer | 244 // Stop() must be called on all of the demuxers even though only one demuxer |
196 // is actively delivering audio and another one is delivering video. This | 245 // is actively delivering audio and another one is delivering video. This |
197 // just satisfies the contract that all demuxers must have Stop() called on | 246 // just satisfies the contract that all demuxers must have Stop() called on |
198 // them before they are destroyed. | 247 // them before they are destroyed. |
| 248 // |
| 249 // TODO: Remove CountingCallback once Stop() is converted to FilterStatusCB. |
199 CountingCallback* wrapper = new CountingCallback(demuxers_.size(), callback); | 250 CountingCallback* wrapper = new CountingCallback(demuxers_.size(), callback); |
200 for (size_t i = 0; i < demuxers_.size(); ++i) | 251 for (size_t i = 0; i < demuxers_.size(); ++i) |
201 demuxers_[i]->Stop(wrapper->GetACallback()); | 252 demuxers_[i]->Stop(wrapper->GetACallback()); |
202 } | 253 } |
203 | 254 |
204 void AdaptiveDemuxer::Seek(base::TimeDelta time, FilterCallback* callback) { | 255 void AdaptiveDemuxer::Seek(base::TimeDelta time, const FilterStatusCB& cb) { |
205 Demuxer* audio = current_demuxer(DemuxerStream::AUDIO); | 256 Demuxer* audio = current_demuxer(DemuxerStream::AUDIO); |
206 Demuxer* video = current_demuxer(DemuxerStream::VIDEO); | 257 Demuxer* video = current_demuxer(DemuxerStream::VIDEO); |
207 int count = (audio ? 1 : 0) + (video && audio != video ? 1 : 0); | 258 int count = (audio ? 1 : 0) + (video && audio != video ? 1 : 0); |
208 CountingCallback* wrapper = new CountingCallback(count, callback); | 259 CountingStatusCB* wrapper = new CountingStatusCB(count, cb); |
209 if (audio) | 260 if (audio) |
210 audio->Seek(time, wrapper->GetACallback()); | 261 audio->Seek(time, wrapper->GetACallback()); |
211 if (video && audio != video) | 262 if (video && audio != video) |
212 video->Seek(time, wrapper->GetACallback()); | 263 video->Seek(time, wrapper->GetACallback()); |
213 } | 264 } |
214 | 265 |
215 void AdaptiveDemuxer::OnAudioRendererDisabled() { | 266 void AdaptiveDemuxer::OnAudioRendererDisabled() { |
216 for (size_t i = 0; i < demuxers_.size(); ++i) | 267 for (size_t i = 0; i < demuxers_.size(); ++i) |
217 demuxers_[i]->OnAudioRendererDisabled(); | 268 demuxers_[i]->OnAudioRendererDisabled(); |
218 } | 269 } |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 delete cb; | 485 delete cb; |
435 return; | 486 return; |
436 } | 487 } |
437 DemuxerAccumulator* accumulator = new DemuxerAccumulator( | 488 DemuxerAccumulator* accumulator = new DemuxerAccumulator( |
438 audio_index, video_index, urls.size(), cb); | 489 audio_index, video_index, urls.size(), cb); |
439 for (size_t i = 0; i < urls.size(); ++i) | 490 for (size_t i = 0; i < urls.size(); ++i) |
440 delegate_factory_->Build(urls[i], accumulator->GetNthCallback(i)); | 491 delegate_factory_->Build(urls[i], accumulator->GetNthCallback(i)); |
441 } | 492 } |
442 | 493 |
443 } // namespace media | 494 } // namespace media |
OLD | NEW |