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