| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/base/pipeline.h" | 5 #include "media/base/pipeline.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 | 262 |
| 263 case kPlaying: | 263 case kPlaying: |
| 264 case kStopping: | 264 case kStopping: |
| 265 case kStopped: | 265 case kStopped: |
| 266 break; | 266 break; |
| 267 } | 267 } |
| 268 NOTREACHED() << "State has no transition: " << state_; | 268 NOTREACHED() << "State has no transition: " << state_; |
| 269 return state_; | 269 return state_; |
| 270 } | 270 } |
| 271 | 271 |
| 272 // The use of base::Unretained(this) in the following 3 functions is safe | |
| 273 // because these functions are called by the Demuxer directly, before the stop | |
| 274 // callback is posted by the Demuxer. So the posted tasks will always be | |
| 275 // executed before the stop callback is executed, and hence before the Pipeline | |
| 276 // is destructed. | |
| 277 | |
| 278 void Pipeline::OnDemuxerError(PipelineStatus error) { | 272 void Pipeline::OnDemuxerError(PipelineStatus error) { |
| 279 task_runner_->PostTask(FROM_HERE, | 273 task_runner_->PostTask(FROM_HERE, |
| 280 base::Bind(&Pipeline::ErrorChangedTask, | 274 base::Bind(&Pipeline::ErrorChangedTask, |
| 281 base::Unretained(this), | 275 weak_this_for_demuxer_, |
| 282 error)); | 276 error)); |
| 283 } | 277 } |
| 284 | 278 |
| 285 void Pipeline::AddTextStream(DemuxerStream* text_stream, | 279 void Pipeline::AddTextStream(DemuxerStream* text_stream, |
| 286 const TextTrackConfig& config) { | 280 const TextTrackConfig& config) { |
| 287 task_runner_->PostTask(FROM_HERE, | 281 task_runner_->PostTask(FROM_HERE, |
| 288 base::Bind(&Pipeline::AddTextStreamTask, | 282 base::Bind(&Pipeline::AddTextStreamTask, |
| 289 base::Unretained(this), | 283 weak_this_for_demuxer_, |
| 290 text_stream, | 284 text_stream, |
| 291 config)); | 285 config)); |
| 292 } | 286 } |
| 293 | 287 |
| 294 void Pipeline::RemoveTextStream(DemuxerStream* text_stream) { | 288 void Pipeline::RemoveTextStream(DemuxerStream* text_stream) { |
| 295 task_runner_->PostTask(FROM_HERE, | 289 task_runner_->PostTask(FROM_HERE, |
| 296 base::Bind(&Pipeline::RemoveTextStreamTask, | 290 base::Bind(&Pipeline::RemoveTextStreamTask, |
| 297 base::Unretained(this), | 291 weak_this_for_demuxer_, |
| 298 text_stream)); | 292 text_stream)); |
| 299 } | 293 } |
| 300 | 294 |
| 301 void Pipeline::OnError(PipelineStatus error) { | 295 void Pipeline::OnError(PipelineStatus error) { |
| 302 DCHECK(task_runner_->BelongsToCurrentThread()); | 296 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 303 DCHECK(IsRunning()); | 297 DCHECK(IsRunning()); |
| 304 DCHECK_NE(PIPELINE_OK, error); | 298 DCHECK_NE(PIPELINE_OK, error); |
| 305 VLOG(1) << "Media pipeline error: " << error; | 299 VLOG(1) << "Media pipeline error: " << error; |
| 306 | 300 |
| 307 task_runner_->PostTask(FROM_HERE, base::Bind( | 301 task_runner_->PostTask(FROM_HERE, base::Bind( |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 DCHECK(!text_renderer_); | 537 DCHECK(!text_renderer_); |
| 544 { | 538 { |
| 545 base::AutoLock l(lock_); | 539 base::AutoLock l(lock_); |
| 546 running_ = false; | 540 running_ = false; |
| 547 } | 541 } |
| 548 | 542 |
| 549 SetState(kStopped); | 543 SetState(kStopped); |
| 550 filter_collection_.reset(); | 544 filter_collection_.reset(); |
| 551 demuxer_ = NULL; | 545 demuxer_ = NULL; |
| 552 | 546 |
| 547 // Invalid all weak pointers so it's safe to destroy |this| on the render |
| 548 // main thread. |
| 549 weak_factory_.InvalidateWeakPtrs(); |
| 550 |
| 553 // If we stop during initialization/seeking we want to run |seek_cb_| | 551 // If we stop during initialization/seeking we want to run |seek_cb_| |
| 554 // followed by |stop_cb_| so we don't leave outstanding callbacks around. | 552 // followed by |stop_cb_| so we don't leave outstanding callbacks around. |
| 555 if (!seek_cb_.is_null()) { | 553 if (!seek_cb_.is_null()) { |
| 556 base::ResetAndReturn(&seek_cb_).Run(status_); | 554 base::ResetAndReturn(&seek_cb_).Run(status_); |
| 557 error_cb_.Reset(); | 555 error_cb_.Reset(); |
| 558 } | 556 } |
| 559 if (!stop_cb_.is_null()) { | 557 if (!stop_cb_.is_null()) { |
| 560 error_cb_.Reset(); | 558 error_cb_.Reset(); |
| 561 base::ResetAndReturn(&stop_cb_).Run(); | 559 base::ResetAndReturn(&stop_cb_).Run(); |
| 562 | 560 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 } | 770 } |
| 773 | 771 |
| 774 void Pipeline::RemoveTextStreamTask(DemuxerStream* text_stream) { | 772 void Pipeline::RemoveTextStreamTask(DemuxerStream* text_stream) { |
| 775 DCHECK(task_runner_->BelongsToCurrentThread()); | 773 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 776 text_renderer_->RemoveTextStream(text_stream); | 774 text_renderer_->RemoveTextStream(text_stream); |
| 777 } | 775 } |
| 778 | 776 |
| 779 void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) { | 777 void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) { |
| 780 DCHECK(task_runner_->BelongsToCurrentThread()); | 778 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 781 | 779 |
| 780 weak_this_for_demuxer_ = weak_factory_.GetWeakPtr(); |
| 782 demuxer_ = filter_collection_->GetDemuxer(); | 781 demuxer_ = filter_collection_->GetDemuxer(); |
| 783 demuxer_->Initialize(this, done_cb, text_renderer_); | 782 demuxer_->Initialize(this, done_cb, text_renderer_); |
| 784 } | 783 } |
| 785 | 784 |
| 786 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { | 785 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { |
| 787 DCHECK(task_runner_->BelongsToCurrentThread()); | 786 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 788 | 787 |
| 789 audio_renderer_ = filter_collection_->GetAudioRenderer(); | 788 audio_renderer_ = filter_collection_->GetAudioRenderer(); |
| 790 base::WeakPtr<Pipeline> weak_this = weak_factory_.GetWeakPtr(); | 789 base::WeakPtr<Pipeline> weak_this = weak_factory_.GetWeakPtr(); |
| 791 audio_renderer_->Initialize( | 790 audio_renderer_->Initialize( |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 916 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
| 918 lock_.AssertAcquired(); | 917 lock_.AssertAcquired(); |
| 919 if (interpolation_state_ != INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE) | 918 if (interpolation_state_ != INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE) |
| 920 return; | 919 return; |
| 921 | 920 |
| 922 interpolation_state_ = INTERPOLATION_STARTED; | 921 interpolation_state_ = INTERPOLATION_STARTED; |
| 923 interpolator_->StartInterpolating(); | 922 interpolator_->StartInterpolating(); |
| 924 } | 923 } |
| 925 | 924 |
| 926 } // namespace media | 925 } // namespace media |
| OLD | NEW |