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