summaryrefslogtreecommitdiffstats
path: root/media/base
diff options
context:
space:
mode:
authorsandersd <sandersd@chromium.org>2016-03-18 15:14:35 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-18 22:16:00 +0000
commit7655364f9ae672fdbd05e5751006387207b0bf51 (patch)
tree1804978b9101559f0503f8c34c2b68dec238bc9d /media/base
parentd816f6dcb4d7ab7493bbba1a84d858fb06be3c06 (diff)
downloadchromium_src-7655364f9ae672fdbd05e5751006387207b0bf51.zip
chromium_src-7655364f9ae672fdbd05e5751006387207b0bf51.tar.gz
chromium_src-7655364f9ae672fdbd05e5751006387207b0bf51.tar.bz2
Restore CDM context on Resume().
Also converts all uses of |weak_factory_| to use a |weak_this_|, as GetWeakPtr() is not threadsafe. BUG=595898 Review URL: https://codereview.chromium.org/1815013002 Cr-Commit-Position: refs/heads/master@{#382109}
Diffstat (limited to 'media/base')
-rw-r--r--media/base/pipeline_impl.cc127
-rw-r--r--media/base/pipeline_impl.h22
2 files changed, 79 insertions, 70 deletions
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index da4e210..5f4705b 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -47,8 +47,9 @@ PipelineImpl::PipelineImpl(
renderer_ended_(false),
text_renderer_ended_(false),
demuxer_(NULL),
- pending_cdm_context_(nullptr),
+ cdm_context_(nullptr),
weak_factory_(this) {
+ weak_this_ = weak_factory_.GetWeakPtr();
media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
}
@@ -91,15 +92,14 @@ void PipelineImpl::Start(Demuxer* demuxer,
add_text_track_cb_ = add_text_track_cb;
waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
- task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::StartTask,
- weak_factory_.GetWeakPtr()));
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&PipelineImpl::StartTask, weak_this_));
}
void PipelineImpl::Stop(const base::Closure& stop_cb) {
DVLOG(2) << __FUNCTION__;
task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&PipelineImpl::StopTask, weak_factory_.GetWeakPtr(), stop_cb));
+ FROM_HERE, base::Bind(&PipelineImpl::StopTask, weak_this_, stop_cb));
}
void PipelineImpl::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) {
@@ -109,9 +109,8 @@ void PipelineImpl::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) {
return;
}
- task_runner_->PostTask(
- FROM_HERE, base::Bind(&PipelineImpl::SeekTask, weak_factory_.GetWeakPtr(),
- time, seek_cb));
+ task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SeekTask,
+ weak_this_, time, seek_cb));
}
bool PipelineImpl::IsRunning() const {
@@ -131,25 +130,23 @@ void PipelineImpl::SetPlaybackRate(double playback_rate) {
base::AutoLock auto_lock(lock_);
playback_rate_ = playback_rate;
if (running_) {
- task_runner_->PostTask(
- FROM_HERE, base::Bind(&PipelineImpl::PlaybackRateChangedTask,
- weak_factory_.GetWeakPtr(), playback_rate));
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&PipelineImpl::PlaybackRateChangedTask,
+ weak_this_, playback_rate));
}
}
void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&PipelineImpl::SuspendTask,
- weak_factory_.GetWeakPtr(), suspend_cb));
+ task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SuspendTask,
+ weak_this_, suspend_cb));
}
void PipelineImpl::Resume(scoped_ptr<Renderer> renderer,
base::TimeDelta timestamp,
const PipelineStatusCB& seek_cb) {
task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&PipelineImpl::ResumeTask, weak_factory_.GetWeakPtr(),
- base::Passed(&renderer), timestamp, seek_cb));
+ FROM_HERE, base::Bind(&PipelineImpl::ResumeTask, weak_this_,
+ base::Passed(&renderer), timestamp, seek_cb));
}
float PipelineImpl::GetVolume() const {
@@ -164,9 +161,9 @@ void PipelineImpl::SetVolume(float volume) {
base::AutoLock auto_lock(lock_);
volume_ = volume;
if (running_) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&PipelineImpl::VolumeChangedTask,
- weak_factory_.GetWeakPtr(), volume));
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&PipelineImpl::VolumeChangedTask, weak_this_, volume));
}
}
@@ -202,9 +199,9 @@ PipelineStatistics PipelineImpl::GetStatistics() const {
void PipelineImpl::SetCdm(CdmContext* cdm_context,
const CdmAttachedCB& cdm_attached_cb) {
- task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::SetCdmTask,
- weak_factory_.GetWeakPtr(),
- cdm_context, cdm_attached_cb));
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&PipelineImpl::SetCdmTask, weak_this_, cdm_context,
+ cdm_attached_cb));
}
void PipelineImpl::SetErrorForTesting(PipelineStatus status) {
@@ -282,22 +279,21 @@ PipelineImpl::State PipelineImpl::GetNextState() const {
}
void PipelineImpl::OnDemuxerError(PipelineStatus error) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&PipelineImpl::ErrorChangedTask,
- weak_factory_.GetWeakPtr(), error));
+ task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::ErrorChangedTask,
+ weak_this_, error));
}
void PipelineImpl::AddTextStream(DemuxerStream* text_stream,
const TextTrackConfig& config) {
task_runner_->PostTask(
- FROM_HERE, base::Bind(&PipelineImpl::AddTextStreamTask,
- weak_factory_.GetWeakPtr(), text_stream, config));
+ FROM_HERE, base::Bind(&PipelineImpl::AddTextStreamTask, weak_this_,
+ text_stream, config));
}
void PipelineImpl::RemoveTextStream(DemuxerStream* text_stream) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&PipelineImpl::RemoveTextStreamTask,
- weak_factory_.GetWeakPtr(), text_stream));
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&PipelineImpl::RemoveTextStreamTask, weak_this_, text_stream));
}
void PipelineImpl::OnError(PipelineStatus error) {
@@ -306,9 +302,8 @@ void PipelineImpl::OnError(PipelineStatus error) {
DCHECK_NE(PIPELINE_OK, error);
VLOG(1) << "Media pipeline error: " << error;
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&PipelineImpl::ErrorChangedTask,
- weak_factory_.GetWeakPtr(), error));
+ task_runner_->PostTask(FROM_HERE, base::Bind(&PipelineImpl::ErrorChangedTask,
+ weak_this_, error));
}
void PipelineImpl::SetDuration(TimeDelta duration) {
@@ -346,8 +341,8 @@ void PipelineImpl::StateTransitionTask(PipelineStatus status) {
pending_callbacks_.reset();
- PipelineStatusCB done_cb = base::Bind(&PipelineImpl::StateTransitionTask,
- weak_factory_.GetWeakPtr());
+ PipelineStatusCB done_cb =
+ base::Bind(&PipelineImpl::StateTransitionTask, weak_this_);
// Switch states, performing any entrance actions for the new state as well.
SetState(GetNextState());
@@ -529,14 +524,8 @@ void PipelineImpl::StartTask() {
text_renderer_ = CreateTextRenderer();
if (text_renderer_) {
- text_renderer_->Initialize(base::Bind(&PipelineImpl::OnTextRendererEnded,
- weak_factory_.GetWeakPtr()));
- }
-
- // Set CDM early to avoid unnecessary delay in Renderer::Initialize().
- if (pending_cdm_context_) {
- renderer_->SetCdm(pending_cdm_context_, base::Bind(&IgnoreCdmAttached));
- pending_cdm_context_ = nullptr;
+ text_renderer_->Initialize(
+ base::Bind(&PipelineImpl::OnTextRendererEnded, weak_this_));
}
StateTransitionTask(PIPELINE_OK);
@@ -576,8 +565,7 @@ void PipelineImpl::StopTask(const base::Closure& stop_cb) {
SetState(kStopping);
pending_callbacks_.reset();
- DoStop(
- base::Bind(&PipelineImpl::OnStopCompleted, weak_factory_.GetWeakPtr()));
+ DoStop(base::Bind(&PipelineImpl::OnStopCompleted, weak_this_));
}
void PipelineImpl::ErrorChangedTask(PipelineStatus error) {
@@ -599,8 +587,7 @@ void PipelineImpl::ErrorChangedTask(PipelineStatus error) {
pending_callbacks_.reset();
status_ = error;
- DoStop(
- base::Bind(&PipelineImpl::OnStopCompleted, weak_factory_.GetWeakPtr()));
+ DoStop(base::Bind(&PipelineImpl::OnStopCompleted, weak_this_));
}
void PipelineImpl::PlaybackRateChangedTask(double playback_rate) {
@@ -646,8 +633,8 @@ void PipelineImpl::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) {
text_renderer_ended_ = false;
start_timestamp_ = seek_timestamp;
- DoSeek(seek_timestamp, base::Bind(&PipelineImpl::StateTransitionTask,
- weak_factory_.GetWeakPtr()));
+ DoSeek(seek_timestamp,
+ base::Bind(&PipelineImpl::StateTransitionTask, weak_this_));
}
void PipelineImpl::SuspendTask(const PipelineStatusCB& suspend_cb) {
@@ -692,9 +679,8 @@ void PipelineImpl::SuspendTask(const PipelineStatusCB& suspend_cb) {
base::Unretained(text_renderer_.get())));
}
- pending_callbacks_ =
- SerialRunner::Run(fns, base::Bind(&PipelineImpl::StateTransitionTask,
- weak_factory_.GetWeakPtr()));
+ pending_callbacks_ = SerialRunner::Run(
+ fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this_));
}
void PipelineImpl::ResumeTask(scoped_ptr<Renderer> renderer,
@@ -727,27 +713,37 @@ void PipelineImpl::ResumeTask(scoped_ptr<Renderer> renderer,
// kInitDemuxer, and even if we did the current code would seek to the start
// instead of |timestamp|).
SerialRunner::Queue fns;
- base::WeakPtr<PipelineImpl> weak_this = weak_factory_.GetWeakPtr();
fns.Push(
base::Bind(&Demuxer::Seek, base::Unretained(demuxer_), start_timestamp_));
- fns.Push(base::Bind(&PipelineImpl::InitializeRenderer, weak_this));
+ fns.Push(base::Bind(&PipelineImpl::InitializeRenderer, weak_this_));
pending_callbacks_ = SerialRunner::Run(
- fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this));
+ fns, base::Bind(&PipelineImpl::StateTransitionTask, weak_this_));
}
void PipelineImpl::SetCdmTask(CdmContext* cdm_context,
const CdmAttachedCB& cdm_attached_cb) {
base::AutoLock auto_lock(lock_);
if (!renderer_) {
- pending_cdm_context_ = cdm_context;
+ cdm_context_ = cdm_context;
cdm_attached_cb.Run(true);
return;
}
- renderer_->SetCdm(cdm_context, cdm_attached_cb);
+ renderer_->SetCdm(cdm_context,
+ base::Bind(&PipelineImpl::OnCdmAttached, weak_this_,
+ cdm_attached_cb, cdm_context));
+}
+
+void PipelineImpl::OnCdmAttached(const CdmAttachedCB& cdm_attached_cb,
+ CdmContext* cdm_context,
+ bool success) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (success)
+ cdm_context_ = cdm_context;
+ cdm_attached_cb.Run(success);
}
void PipelineImpl::OnRendererEnded() {
@@ -797,8 +793,7 @@ scoped_ptr<TextRenderer> PipelineImpl::CreateTextRenderer() {
return scoped_ptr<media::TextRenderer>();
return scoped_ptr<media::TextRenderer>(new media::TextRenderer(
- task_runner_,
- base::Bind(&PipelineImpl::OnAddTextTrack, weak_factory_.GetWeakPtr())));
+ task_runner_, base::Bind(&PipelineImpl::OnAddTextTrack, weak_this_)));
}
void PipelineImpl::AddTextStreamTask(DemuxerStream* text_stream,
@@ -840,13 +835,15 @@ void PipelineImpl::InitializeRenderer(const PipelineStatusCB& done_cb) {
return;
}
- base::WeakPtr<PipelineImpl> weak_this = weak_factory_.GetWeakPtr();
+ if (cdm_context_)
+ renderer_->SetCdm(cdm_context_, base::Bind(&IgnoreCdmAttached));
+
renderer_->Initialize(
demuxer_, done_cb,
- base::Bind(&PipelineImpl::OnUpdateStatistics, weak_this),
- base::Bind(&PipelineImpl::BufferingStateChanged, weak_this),
- base::Bind(&PipelineImpl::OnRendererEnded, weak_this),
- base::Bind(&PipelineImpl::OnError, weak_this),
+ base::Bind(&PipelineImpl::OnUpdateStatistics, weak_this_),
+ base::Bind(&PipelineImpl::BufferingStateChanged, weak_this_),
+ base::Bind(&PipelineImpl::OnRendererEnded, weak_this_),
+ base::Bind(&PipelineImpl::OnError, weak_this_),
waiting_for_decryption_key_cb_);
}
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index 8a55ed72..7a6da3a 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -191,6 +191,9 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline, public DemuxerHost {
// will be set in |renderer_| later when |renderer_| is created.
void SetCdmTask(CdmContext* cdm_context,
const CdmAttachedCB& cdm_attached_cb);
+ void OnCdmAttached(const CdmAttachedCB& cdm_attached_cb,
+ CdmContext* cdm_context,
+ bool success);
// Callbacks executed when a renderer has ended.
void OnRendererEnded();
@@ -316,14 +319,23 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline, public DemuxerHost {
scoped_ptr<SerialRunner> pending_callbacks_;
- // CdmContext to be used to decrypt (and decode) encrypted stream in this
- // pipeline. Non-null only when SetCdm() is called and the pipeline has not
- // been started. Then during Start(), this value will be set on |renderer_|.
- CdmContext* pending_cdm_context_;
+ // The CdmContext to be used to decrypt (and decode) encrypted stream in this
+ // pipeline. It is set when SetCdm() succeeds on the renderer (or when
+ // SetCdm() is called before Start()), after which it is guaranteed to outlive
+ // this pipeline. The saved value will be used to configure new renderers,
+ // when starting or resuming.
+ CdmContext* cdm_context_;
base::ThreadChecker thread_checker_;
- // NOTE: Weak pointers must be invalidated before all other member variables.
+ // A weak pointer that can be safely copied on the media thread.
+ base::WeakPtr<PipelineImpl> weak_this_;
+
+ // Weak pointers must be created on the main thread, and must be dereferenced
+ // on the media thread.
+ //
+ // Declared last so that weak pointers will be invalidated before all other
+ // member variables.
base::WeakPtrFactory<PipelineImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PipelineImpl);