| 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_impl.h" | 5 #include "media/base/pipeline_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/location.h" | 16 #include "base/location.h" |
| 17 #include "base/memory/ptr_util.h" |
| 17 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 18 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 19 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
| 20 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 22 #include "base/synchronization/condition_variable.h" | 23 #include "base/synchronization/condition_variable.h" |
| 23 #include "media/base/media_log.h" | 24 #include "media/base/media_log.h" |
| 24 #include "media/base/media_switches.h" | 25 #include "media/base/media_switches.h" |
| 25 #include "media/base/renderer.h" | 26 #include "media/base/renderer.h" |
| 26 #include "media/base/text_renderer.h" | 27 #include "media/base/text_renderer.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 55 | 56 |
| 56 PipelineImpl::~PipelineImpl() { | 57 PipelineImpl::~PipelineImpl() { |
| 57 DCHECK(thread_checker_.CalledOnValidThread()) | 58 DCHECK(thread_checker_.CalledOnValidThread()) |
| 58 << "Pipeline must be destroyed on same thread that created it"; | 59 << "Pipeline must be destroyed on same thread that created it"; |
| 59 DCHECK(!running_) << "Stop() must complete before destroying object"; | 60 DCHECK(!running_) << "Stop() must complete before destroying object"; |
| 60 DCHECK(stop_cb_.is_null()); | 61 DCHECK(stop_cb_.is_null()); |
| 61 DCHECK(seek_cb_.is_null()); | 62 DCHECK(seek_cb_.is_null()); |
| 62 } | 63 } |
| 63 | 64 |
| 64 void PipelineImpl::Start(Demuxer* demuxer, | 65 void PipelineImpl::Start(Demuxer* demuxer, |
| 65 scoped_ptr<Renderer> renderer, | 66 std::unique_ptr<Renderer> renderer, |
| 66 const base::Closure& ended_cb, | 67 const base::Closure& ended_cb, |
| 67 const PipelineStatusCB& error_cb, | 68 const PipelineStatusCB& error_cb, |
| 68 const PipelineStatusCB& seek_cb, | 69 const PipelineStatusCB& seek_cb, |
| 69 const PipelineMetadataCB& metadata_cb, | 70 const PipelineMetadataCB& metadata_cb, |
| 70 const BufferingStateCB& buffering_state_cb, | 71 const BufferingStateCB& buffering_state_cb, |
| 71 const base::Closure& duration_change_cb, | 72 const base::Closure& duration_change_cb, |
| 72 const AddTextTrackCB& add_text_track_cb, | 73 const AddTextTrackCB& add_text_track_cb, |
| 73 const base::Closure& waiting_for_decryption_key_cb) { | 74 const base::Closure& waiting_for_decryption_key_cb) { |
| 74 DCHECK(!ended_cb.is_null()); | 75 DCHECK(!ended_cb.is_null()); |
| 75 DCHECK(!error_cb.is_null()); | 76 DCHECK(!error_cb.is_null()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 base::Bind(&PipelineImpl::PlaybackRateChangedTask, | 135 base::Bind(&PipelineImpl::PlaybackRateChangedTask, |
| 135 weak_this_, playback_rate)); | 136 weak_this_, playback_rate)); |
| 136 } | 137 } |
| 137 } | 138 } |
| 138 | 139 |
| 139 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) { | 140 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) { |
| 140 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SuspendTask, | 141 task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SuspendTask, |
| 141 weak_this_, suspend_cb)); | 142 weak_this_, suspend_cb)); |
| 142 } | 143 } |
| 143 | 144 |
| 144 void PipelineImpl::Resume(scoped_ptr<Renderer> renderer, | 145 void PipelineImpl::Resume(std::unique_ptr<Renderer> renderer, |
| 145 base::TimeDelta timestamp, | 146 base::TimeDelta timestamp, |
| 146 const PipelineStatusCB& seek_cb) { | 147 const PipelineStatusCB& seek_cb) { |
| 147 task_runner_->PostTask( | 148 task_runner_->PostTask( |
| 148 FROM_HERE, base::Bind(&PipelineImpl::ResumeTask, weak_this_, | 149 FROM_HERE, base::Bind(&PipelineImpl::ResumeTask, weak_this_, |
| 149 base::Passed(&renderer), timestamp, seek_cb)); | 150 base::Passed(&renderer), timestamp, seek_cb)); |
| 150 } | 151 } |
| 151 | 152 |
| 152 float PipelineImpl::GetVolume() const { | 153 float PipelineImpl::GetVolume() const { |
| 153 base::AutoLock auto_lock(lock_); | 154 base::AutoLock auto_lock(lock_); |
| 154 return volume_; | 155 return volume_; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 pending_callbacks_ = SerialRunner::Run(bound_fns, done_cb); | 432 pending_callbacks_ = SerialRunner::Run(bound_fns, done_cb); |
| 432 } | 433 } |
| 433 | 434 |
| 434 void PipelineImpl::DoStop(const PipelineStatusCB& done_cb) { | 435 void PipelineImpl::DoStop(const PipelineStatusCB& done_cb) { |
| 435 DVLOG(2) << __FUNCTION__; | 436 DVLOG(2) << __FUNCTION__; |
| 436 DCHECK(task_runner_->BelongsToCurrentThread()); | 437 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 437 DCHECK(!pending_callbacks_.get()); | 438 DCHECK(!pending_callbacks_.get()); |
| 438 | 439 |
| 439 // TODO(scherkus): Enforce that Renderer is only called on a single thread, | 440 // TODO(scherkus): Enforce that Renderer is only called on a single thread, |
| 440 // even for accessing media time http://crbug.com/370634 | 441 // even for accessing media time http://crbug.com/370634 |
| 441 scoped_ptr<Renderer> renderer; | 442 std::unique_ptr<Renderer> renderer; |
| 442 { | 443 { |
| 443 base::AutoLock auto_lock(lock_); | 444 base::AutoLock auto_lock(lock_); |
| 444 renderer.swap(renderer_); | 445 renderer.swap(renderer_); |
| 445 } | 446 } |
| 446 renderer.reset(); | 447 renderer.reset(); |
| 447 text_renderer_.reset(); | 448 text_renderer_.reset(); |
| 448 | 449 |
| 449 if (demuxer_) { | 450 if (demuxer_) { |
| 450 demuxer_->Stop(); | 451 demuxer_->Stop(); |
| 451 demuxer_ = NULL; | 452 demuxer_ = NULL; |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 | 677 |
| 677 if (text_renderer_) { | 678 if (text_renderer_) { |
| 678 fns.Push(base::Bind(&TextRenderer::Flush, | 679 fns.Push(base::Bind(&TextRenderer::Flush, |
| 679 base::Unretained(text_renderer_.get()))); | 680 base::Unretained(text_renderer_.get()))); |
| 680 } | 681 } |
| 681 | 682 |
| 682 pending_callbacks_ = SerialRunner::Run( | 683 pending_callbacks_ = SerialRunner::Run( |
| 683 fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this_)); | 684 fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this_)); |
| 684 } | 685 } |
| 685 | 686 |
| 686 void PipelineImpl::ResumeTask(scoped_ptr<Renderer> renderer, | 687 void PipelineImpl::ResumeTask(std::unique_ptr<Renderer> renderer, |
| 687 base::TimeDelta timestamp, | 688 base::TimeDelta timestamp, |
| 688 const PipelineStatusCB& seek_cb) { | 689 const PipelineStatusCB& seek_cb) { |
| 689 DCHECK(task_runner_->BelongsToCurrentThread()); | 690 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 690 | 691 |
| 691 // Suppress resuming if we're not suspended. | 692 // Suppress resuming if we're not suspended. |
| 692 if (state_ != kSuspended) { | 693 if (state_ != kSuspended) { |
| 693 DCHECK(state_ == kStopping || state_ == kStopped) | 694 DCHECK(state_ == kStopping || state_ == kStopped) |
| 694 << "Receive resume in unexpected state: " << state_; | 695 << "Receive resume in unexpected state: " << state_; |
| 695 seek_cb.Run(PIPELINE_ERROR_INVALID_STATE); | 696 seek_cb.Run(PIPELINE_ERROR_INVALID_STATE); |
| 696 return; | 697 return; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 if (renderer_ && !renderer_ended_) | 779 if (renderer_ && !renderer_ended_) |
| 779 return; | 780 return; |
| 780 | 781 |
| 781 if (text_renderer_ && text_renderer_->HasTracks() && !text_renderer_ended_) | 782 if (text_renderer_ && text_renderer_->HasTracks() && !text_renderer_ended_) |
| 782 return; | 783 return; |
| 783 | 784 |
| 784 DCHECK_EQ(status_, PIPELINE_OK); | 785 DCHECK_EQ(status_, PIPELINE_OK); |
| 785 ended_cb_.Run(); | 786 ended_cb_.Run(); |
| 786 } | 787 } |
| 787 | 788 |
| 788 scoped_ptr<TextRenderer> PipelineImpl::CreateTextRenderer() { | 789 std::unique_ptr<TextRenderer> PipelineImpl::CreateTextRenderer() { |
| 789 DCHECK(task_runner_->BelongsToCurrentThread()); | 790 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 790 | 791 |
| 791 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 792 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| 792 if (!cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) | 793 if (!cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) |
| 793 return scoped_ptr<media::TextRenderer>(); | 794 return nullptr; |
| 794 | 795 |
| 795 return scoped_ptr<media::TextRenderer>(new media::TextRenderer( | 796 return base::WrapUnique(new media::TextRenderer( |
| 796 task_runner_, base::Bind(&PipelineImpl::OnAddTextTrack, weak_this_))); | 797 task_runner_, base::Bind(&PipelineImpl::OnAddTextTrack, weak_this_))); |
| 797 } | 798 } |
| 798 | 799 |
| 799 void PipelineImpl::AddTextStreamTask(DemuxerStream* text_stream, | 800 void PipelineImpl::AddTextStreamTask(DemuxerStream* text_stream, |
| 800 const TextTrackConfig& config) { | 801 const TextTrackConfig& config) { |
| 801 DCHECK(task_runner_->BelongsToCurrentThread()); | 802 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 802 // TODO(matthewjheaney): fix up text_ended_ when text stream | 803 // TODO(matthewjheaney): fix up text_ended_ when text stream |
| 803 // is added (http://crbug.com/321446). | 804 // is added (http://crbug.com/321446). |
| 804 if (text_renderer_) | 805 if (text_renderer_) |
| 805 text_renderer_->AddTextStream(text_stream, config); | 806 text_renderer_->AddTextStream(text_stream, config); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 metadata_cb_.Run(metadata); | 864 metadata_cb_.Run(metadata); |
| 864 } | 865 } |
| 865 | 866 |
| 866 void PipelineImpl::BufferingStateChanged(BufferingState new_buffering_state) { | 867 void PipelineImpl::BufferingStateChanged(BufferingState new_buffering_state) { |
| 867 DVLOG(1) << __FUNCTION__ << "(" << new_buffering_state << ") "; | 868 DVLOG(1) << __FUNCTION__ << "(" << new_buffering_state << ") "; |
| 868 DCHECK(task_runner_->BelongsToCurrentThread()); | 869 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 869 buffering_state_cb_.Run(new_buffering_state); | 870 buffering_state_cb_.Run(new_buffering_state); |
| 870 } | 871 } |
| 871 | 872 |
| 872 } // namespace media | 873 } // namespace media |
| OLD | NEW |