Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(911)

Unified Diff: media/base/pipeline_impl.cc

Issue 2071503003: Avoid flooding main thread by caching state on media thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: adds dcheck Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/pipeline_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/pipeline_impl.cc
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index c5cb4841dc039970d0f8bb3cb8d1c587bcf99b69..36747bd48b3cd7ba73421aa5d2de35966c903170 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -37,24 +37,57 @@ namespace media {
class PipelineImpl::RendererWrapper : public DemuxerHost,
public RendererClient {
public:
- RendererWrapper(base::WeakPtr<PipelineImpl> weak_pipeline,
- scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+ RendererWrapper(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
scoped_refptr<MediaLog> media_log);
~RendererWrapper() final;
void Start(Demuxer* demuxer,
std::unique_ptr<Renderer> renderer,
- std::unique_ptr<TextRenderer> text_renderer);
+ std::unique_ptr<TextRenderer> text_renderer,
+ base::WeakPtr<PipelineImpl> weak_pipeline);
void Stop(const base::Closure& stop_cb);
void Seek(base::TimeDelta time);
void Suspend();
void Resume(std::unique_ptr<Renderer> renderer, base::TimeDelta time);
void SetPlaybackRate(double playback_rate);
void SetVolume(float volume);
- base::TimeDelta GetMediaTime();
+ base::TimeDelta GetMediaTime() const;
+ Ranges<base::TimeDelta> GetBufferedTimeRanges() const;
+ bool DidLoadingProgress();
+ PipelineStatistics GetStatistics() const;
void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb);
private:
+ // Contains state shared between main and media thread.
+ // Main thread can only read. Media thread can both - read and write.
+ // So it is not necessary to lock when reading from the media thread.
+ // This struct should only contain state that is not immediately needed by
+ // PipelineClient and can be cached on the media thread until queried.
+ // Alternatively we could cache it on the main thread by posting the
+ // notification to the main thread. But some of the state change notifications
+ // (OnStatisticsUpdate and OnBufferedTimeRangesChanged) arrive much more
+ // frequently than needed. Posting all those notifications to the main thread
+ // causes performance issues: crbug.com/619975.
+ struct SharedState {
+ // TODO(scherkus): Enforce that Renderer is only called on a single thread,
+ // even for accessing media time http://crbug.com/370634
+ std::unique_ptr<Renderer> renderer;
+
+ // True when OnBufferedTimeRangesChanged() has been called more recently
+ // than DidLoadingProgress().
+ bool did_loading_progress = false;
+
+ // Amount of available buffered data as reported by Demuxer.
+ Ranges<base::TimeDelta> buffered_time_ranges;
+
+ // Accumulated statistics reported by the renderer.
+ PipelineStatistics statistics;
+
+ // The media timestamp to return while the pipeline is suspended.
+ // Otherwise set to kNoTimestamp().
+ base::TimeDelta suspend_timestamp = kNoTimestamp();
+ };
+
// DemuxerHost implementaion.
void OnBufferedTimeRangesChanged(const Ranges<base::TimeDelta>& ranges) final;
void SetDuration(base::TimeDelta duration) final;
@@ -88,24 +121,25 @@ class PipelineImpl::RendererWrapper : public DemuxerHost,
void RemoveTextStreamTask(DemuxerStream* text_stream);
void InitializeDemuxer(const PipelineStatusCB& done_cb);
void InitializeRenderer(const PipelineStatusCB& done_cb);
+ void DestroyRenderer();
void ReportMetadata();
- base::WeakPtr<PipelineImpl> weak_pipeline_;
const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
const scoped_refptr<MediaLog> media_log_;
+ base::WeakPtr<PipelineImpl> weak_pipeline_;
Demuxer* demuxer_;
- std::unique_ptr<Renderer> renderer_;
std::unique_ptr<TextRenderer> text_renderer_;
double playback_rate_;
float volume_;
CdmContext* cdm_context_;
- // Lock used to serialize members - |renderer_| and |suspend_timestamp_| -
- // accessed in GetMediaTime(), which is the only member function called on
- // the main thread.
- mutable base::Lock media_time_lock_;
+ // Lock used to serialize |shared_state_|.
+ mutable base::Lock shared_state_lock_;
+
+ // State shared between main and media thread.
+ SharedState shared_state_;
// Current state of the pipeline.
State state_;
@@ -120,10 +154,6 @@ class PipelineImpl::RendererWrapper : public DemuxerHost,
// completed.
base::TimeDelta start_timestamp_;
- // The media timestamp to return while the pipeline is suspended.
- // Otherwise set to kNoTimestamp().
- base::TimeDelta suspend_timestamp_;
-
// Whether we've received the audio/video/text ended events.
bool renderer_ended_;
bool text_renderer_ended_;
@@ -144,11 +174,9 @@ PipelineImpl::PipelineImpl(
client_(nullptr),
playback_rate_(kDefaultPlaybackRate),
volume_(kDefaultVolume),
- did_loading_progress_(false),
weak_factory_(this) {
DVLOG(2) << __FUNCTION__;
- renderer_wrapper_.reset(new RendererWrapper(weak_factory_.GetWeakPtr(),
- media_task_runner_, media_log_));
+ renderer_wrapper_.reset(new RendererWrapper(media_task_runner_, media_log_));
}
PipelineImpl::~PipelineImpl() {
@@ -157,13 +185,7 @@ PipelineImpl::~PipelineImpl() {
DCHECK(!client_) << "Stop() must complete before destroying object";
DCHECK(seek_cb_.is_null());
DCHECK(suspend_cb_.is_null());
-
- // Invalidate self weak pointers effectively canceling all pending
- // notifications in the message queue.
- // Do this before posting the DeleteSoon task to the media thread to
- // guarantee that the WeakPtr<PipelineImpl> passed to the RendererWrapper
- // is not invalidated on the media thread.
- weak_factory_.InvalidateWeakPtrs();
+ DCHECK(!weak_factory_.HasWeakPtrs());
// RendererWrapper is deleted on the media thread.
media_task_runner_->DeleteSoon(FROM_HERE, renderer_wrapper_.release());
@@ -198,7 +220,8 @@ void PipelineImpl::Start(Demuxer* demuxer,
FROM_HERE,
base::Bind(&RendererWrapper::Start,
base::Unretained(renderer_wrapper_.get()), demuxer,
- base::Passed(&renderer), base::Passed(&text_renderer)));
+ base::Passed(&renderer), base::Passed(&text_renderer),
+ weak_factory_.GetWeakPtr()));
}
void PipelineImpl::Stop() {
@@ -210,11 +233,6 @@ void PipelineImpl::Stop() {
return;
}
- if (statistics_.video_frames_decoded > 0) {
- UMA_HISTOGRAM_COUNTS("Media.DroppedFrameCount",
- statistics_.video_frames_dropped);
- }
-
if (media_task_runner_->BelongsToCurrentThread()) {
// This path is executed by unittests that share media and main threads.
base::Closure stop_cb = base::Bind(&base::DoNothing);
@@ -251,6 +269,10 @@ void PipelineImpl::Stop() {
seek_cb_.Reset();
suspend_cb_.Reset();
client_ = nullptr;
+
+ // Invalidate self weak pointers effectively canceling all pending
+ // notifications in the message queue.
+ weak_factory_.InvalidateWeakPtrs();
}
void PipelineImpl::Seek(base::TimeDelta time, const PipelineStatusCB& seek_cb) {
@@ -351,7 +373,7 @@ base::TimeDelta PipelineImpl::GetMediaTime() const {
Ranges<base::TimeDelta> PipelineImpl::GetBufferedTimeRanges() const {
DCHECK(thread_checker_.CalledOnValidThread());
- return buffered_time_ranges_;
+ return renderer_wrapper_->GetBufferedTimeRanges();
}
base::TimeDelta PipelineImpl::GetMediaDuration() const {
@@ -361,14 +383,12 @@ base::TimeDelta PipelineImpl::GetMediaDuration() const {
bool PipelineImpl::DidLoadingProgress() {
DCHECK(thread_checker_.CalledOnValidThread());
- bool ret = did_loading_progress_;
- did_loading_progress_ = false;
- return ret;
+ return renderer_wrapper_->DidLoadingProgress();
}
PipelineStatistics PipelineImpl::GetStatistics() const {
DCHECK(thread_checker_.CalledOnValidThread());
- return statistics_;
+ return renderer_wrapper_->GetStatistics();
}
void PipelineImpl::SetCdm(CdmContext* cdm_context,
@@ -501,11 +521,16 @@ void PipelineImpl::RendererWrapper::OnEnded() {
void PipelineImpl::RendererWrapper::OnStatisticsUpdate(
const PipelineStatistics& stats) {
+ DVLOG(3) << __FUNCTION__;
DCHECK(media_task_runner_->BelongsToCurrentThread());
- main_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&PipelineImpl::OnStatisticsUpdate, weak_pipeline_, stats));
+ base::AutoLock auto_lock(shared_state_lock_);
+ shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded;
+ shared_state_.statistics.video_bytes_decoded += stats.video_bytes_decoded;
+ shared_state_.statistics.video_frames_decoded += stats.video_frames_decoded;
+ shared_state_.statistics.video_frames_dropped += stats.video_frames_dropped;
+ shared_state_.statistics.audio_memory_usage += stats.audio_memory_usage;
+ shared_state_.statistics.video_memory_usage += stats.video_memory_usage;
}
void PipelineImpl::RendererWrapper::OnBufferingStateChange(
@@ -597,10 +622,10 @@ void PipelineImpl::RendererWrapper::StateTransitionTask(PipelineStatus status) {
case kPlaying:
DCHECK(start_timestamp_ >= base::TimeDelta());
- renderer_->StartPlayingFrom(start_timestamp_);
+ shared_state_.renderer->StartPlayingFrom(start_timestamp_);
{
- base::AutoLock auto_lock(media_time_lock_);
- suspend_timestamp_ = kNoTimestamp();
+ base::AutoLock auto_lock(shared_state_lock_);
+ shared_state_.suspend_timestamp = kNoTimestamp();
}
if (text_renderer_)
@@ -610,15 +635,20 @@ void PipelineImpl::RendererWrapper::StateTransitionTask(PipelineStatus status) {
FROM_HERE, base::Bind(&PipelineImpl::OnSeekDone, weak_pipeline_,
start_timestamp_));
- renderer_->SetPlaybackRate(playback_rate_);
- renderer_->SetVolume(volume_);
+ shared_state_.renderer->SetPlaybackRate(playback_rate_);
+ shared_state_.renderer->SetVolume(volume_);
return;
case kSuspended:
- renderer_.reset();
+ DestroyRenderer();
+ {
+ base::AutoLock auto_lock(shared_state_lock_);
+ shared_state_.statistics.audio_memory_usage = 0;
+ shared_state_.statistics.video_memory_usage = 0;
+ }
main_task_runner_->PostTask(
FROM_HERE, base::Bind(&PipelineImpl::OnSuspendDone, weak_pipeline_,
- suspend_timestamp_));
+ shared_state_.suspend_timestamp));
return;
case kStopping:
@@ -651,9 +681,9 @@ void PipelineImpl::RendererWrapper::DoSeek(base::TimeDelta seek_timestamp,
}
// Flush.
- DCHECK(renderer_);
- bound_fns.Push(
- base::Bind(&Renderer::Flush, base::Unretained(renderer_.get())));
+ DCHECK(shared_state_.renderer);
+ bound_fns.Push(base::Bind(&Renderer::Flush,
+ base::Unretained(shared_state_.renderer.get())));
if (text_renderer_) {
bound_fns.Push(base::Bind(&TextRenderer::Flush,
@@ -673,14 +703,7 @@ void PipelineImpl::RendererWrapper::DoStop(const base::Closure& done_cb) {
DCHECK_EQ(state_, kStopping);
DCHECK(!pending_callbacks_.get());
- // TODO(scherkus): Enforce that Renderer is only called on a single thread,
- // even for accessing media time http://crbug.com/370634
- std::unique_ptr<Renderer> renderer;
- {
- base::AutoLock auto_lock(media_time_lock_);
- renderer.swap(renderer_);
- }
- renderer.reset();
+ DestroyRenderer();
text_renderer_.reset();
if (demuxer_) {
@@ -703,34 +726,37 @@ void PipelineImpl::RendererWrapper::OnBufferedTimeRangesChanged(
const Ranges<base::TimeDelta>& ranges) {
// TODO(alokp): Add thread DCHECK after ensuring that all Demuxer
// implementations call DemuxerHost on the media thread.
- main_task_runner_->PostTask(
- FROM_HERE, base::Bind(&PipelineImpl::OnBufferedTimeRangesChange,
- weak_pipeline_, ranges));
+ base::AutoLock auto_lock(shared_state_lock_);
+ shared_state_.did_loading_progress = true;
+ shared_state_.buffered_time_ranges = ranges;
}
void PipelineImpl::RendererWrapper::Start(
Demuxer* demuxer,
std::unique_ptr<Renderer> renderer,
- std::unique_ptr<TextRenderer> text_renderer) {
+ std::unique_ptr<TextRenderer> text_renderer,
+ base::WeakPtr<PipelineImpl> weak_pipeline) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
DCHECK_EQ(kCreated, state_) << "Received start in unexpected state: "
<< state_;
DCHECK(!demuxer_);
- DCHECK(!renderer_);
+ DCHECK(!shared_state_.renderer);
DCHECK(!text_renderer_);
DCHECK(!renderer_ended_);
DCHECK(!text_renderer_ended_);
+ DCHECK(!weak_pipeline_);
demuxer_ = demuxer;
{
- base::AutoLock auto_lock(media_time_lock_);
- renderer_ = std::move(renderer);
+ base::AutoLock auto_lock(shared_state_lock_);
+ shared_state_.renderer = std::move(renderer);
}
text_renderer_ = std::move(text_renderer);
if (text_renderer_) {
text_renderer_->Initialize(
base::Bind(&RendererWrapper::OnTextRendererEnded, weak_this_));
}
+ weak_pipeline_ = weak_pipeline;
StateTransitionTask(PIPELINE_OK);
}
@@ -741,6 +767,11 @@ void PipelineImpl::RendererWrapper::Stop(const base::Closure& stop_cb) {
SetState(kStopping);
+ if (shared_state_.statistics.video_frames_decoded > 0) {
+ UMA_HISTOGRAM_COUNTS("Media.DroppedFrameCount",
+ shared_state_.statistics.video_frames_dropped);
+ }
+
// If we stop during starting/seeking/suspending/resuming we don't want to
// leave outstanding callbacks around. The callbacks also do not get run if
// the pipeline is stopped before it had a chance to complete outstanding
@@ -779,7 +810,7 @@ void PipelineImpl::RendererWrapper::SetPlaybackRate(double playback_rate) {
playback_rate_ = playback_rate;
if (state_ == kPlaying)
- renderer_->SetPlaybackRate(playback_rate_);
+ shared_state_.renderer->SetPlaybackRate(playback_rate_);
}
void PipelineImpl::RendererWrapper::SetVolume(float volume) {
@@ -787,7 +818,7 @@ void PipelineImpl::RendererWrapper::SetVolume(float volume) {
volume_ = volume;
if (state_ == kPlaying)
- renderer_->SetVolume(volume_);
+ shared_state_.renderer->SetVolume(volume_);
}
void PipelineImpl::RendererWrapper::Seek(base::TimeDelta time) {
@@ -823,18 +854,18 @@ void PipelineImpl::RendererWrapper::Suspend() {
OnPipelineError(PIPELINE_ERROR_INVALID_STATE);
return;
}
- DCHECK(renderer_);
+ DCHECK(shared_state_.renderer);
DCHECK(!pending_callbacks_.get());
SetState(kSuspending);
// Freeze playback and record the media time before flushing. (Flushing clears
// the value.)
- renderer_->SetPlaybackRate(0.0);
+ shared_state_.renderer->SetPlaybackRate(0.0);
{
- base::AutoLock auto_lock(media_time_lock_);
- suspend_timestamp_ = renderer_->GetMediaTime();
- DCHECK(suspend_timestamp_ != kNoTimestamp());
+ base::AutoLock auto_lock(shared_state_lock_);
+ shared_state_.suspend_timestamp = shared_state_.renderer->GetMediaTime();
+ DCHECK(shared_state_.suspend_timestamp != kNoTimestamp());
}
// Queue the asynchronous actions required to stop playback. (Matches setup in
@@ -847,7 +878,8 @@ void PipelineImpl::RendererWrapper::Suspend() {
base::Unretained(text_renderer_.get())));
}
- fns.Push(base::Bind(&Renderer::Flush, base::Unretained(renderer_.get())));
+ fns.Push(base::Bind(&Renderer::Flush,
+ base::Unretained(shared_state_.renderer.get())));
if (text_renderer_) {
fns.Push(base::Bind(&TextRenderer::Flush,
@@ -869,14 +901,14 @@ void PipelineImpl::RendererWrapper::Resume(std::unique_ptr<Renderer> renderer,
OnPipelineError(PIPELINE_ERROR_INVALID_STATE);
return;
}
- DCHECK(!renderer_);
+ DCHECK(!shared_state_.renderer);
DCHECK(!pending_callbacks_.get());
SetState(kResuming);
{
- base::AutoLock auto_lock(media_time_lock_);
- renderer_ = std::move(renderer);
+ base::AutoLock auto_lock(shared_state_lock_);
+ shared_state_.renderer = std::move(renderer);
}
// Set up for a seek. (Matches setup in SeekTask().)
@@ -900,20 +932,44 @@ void PipelineImpl::RendererWrapper::Resume(std::unique_ptr<Renderer> renderer,
fns, base::Bind(&RendererWrapper::StateTransitionTask, weak_this_));
}
+Ranges<base::TimeDelta> PipelineImpl::RendererWrapper::GetBufferedTimeRanges()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+
+ base::AutoLock auto_lock(shared_state_lock_);
+ return shared_state_.buffered_time_ranges;
+}
+
+bool PipelineImpl::RendererWrapper::DidLoadingProgress() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+
+ base::AutoLock auto_lock(shared_state_lock_);
+ bool did_progress = shared_state_.did_loading_progress;
+ shared_state_.did_loading_progress = false;
+ return did_progress;
+}
+
+PipelineStatistics PipelineImpl::RendererWrapper::GetStatistics() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+
+ base::AutoLock auto_lock(shared_state_lock_);
+ return shared_state_.statistics;
+}
+
void PipelineImpl::RendererWrapper::SetCdm(
CdmContext* cdm_context,
const CdmAttachedCB& cdm_attached_cb) {
DCHECK(media_task_runner_->BelongsToCurrentThread());
- if (!renderer_) {
+ if (!shared_state_.renderer) {
cdm_context_ = cdm_context;
cdm_attached_cb.Run(true);
return;
}
- renderer_->SetCdm(cdm_context,
- base::Bind(&RendererWrapper::OnCdmAttached, weak_this_,
- cdm_attached_cb, cdm_context));
+ shared_state_.renderer->SetCdm(
+ cdm_context, base::Bind(&RendererWrapper::OnCdmAttached, weak_this_,
+ cdm_attached_cb, cdm_context));
}
void PipelineImpl::RendererWrapper::OnCdmAttached(
@@ -943,7 +999,7 @@ void PipelineImpl::RendererWrapper::OnTextRendererEnded() {
void PipelineImpl::RendererWrapper::RunEndedCallbackIfNeeded() {
DCHECK(media_task_runner_->BelongsToCurrentThread());
- if (renderer_ && !renderer_ended_)
+ if (shared_state_.renderer && !renderer_ended_)
return;
if (text_renderer_ && text_renderer_->HasTracks() && !text_renderer_ended_)
@@ -991,9 +1047,22 @@ void PipelineImpl::RendererWrapper::InitializeRenderer(
}
if (cdm_context_)
- renderer_->SetCdm(cdm_context_, base::Bind(&IgnoreCdmAttached));
+ shared_state_.renderer->SetCdm(cdm_context_,
+ base::Bind(&IgnoreCdmAttached));
- renderer_->Initialize(demuxer_, this, done_cb);
+ shared_state_.renderer->Initialize(demuxer_, this, done_cb);
+}
+
+void PipelineImpl::RendererWrapper::DestroyRenderer() {
+ DCHECK(media_task_runner_->BelongsToCurrentThread());
+
+ // Destroy the renderer outside the lock scope to avoid holding the lock
+ // while renderer is being destroyed (in case Renderer destructor is costly).
+ std::unique_ptr<Renderer> renderer;
+ {
+ base::AutoLock auto_lock(shared_state_lock_);
+ renderer.swap(shared_state_.renderer);
+ }
}
void PipelineImpl::RendererWrapper::ReportMetadata() {
@@ -1019,9 +1088,7 @@ void PipelineImpl::OnError(PipelineStatus error) {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!";
-
- if (!IsRunning())
- return;
+ DCHECK(IsRunning());
// If the error happens during starting/seeking/suspending/resuming,
// report the error via the completion callback for those tasks.
@@ -1042,137 +1109,100 @@ void PipelineImpl::OnError(PipelineStatus error) {
void PipelineImpl::OnEnded() {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnEnded();
- }
+ DCHECK(client_);
+ client_->OnEnded();
}
void PipelineImpl::OnMetadata(PipelineMetadata metadata) {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnMetadata(metadata);
- }
+ DCHECK(client_);
+ client_->OnMetadata(metadata);
}
void PipelineImpl::OnBufferingStateChange(BufferingState state) {
DVLOG(2) << __FUNCTION__ << "(" << state << ")";
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnBufferingStateChange(state);
- }
+ DCHECK(client_);
+ client_->OnBufferingStateChange(state);
}
void PipelineImpl::OnDurationChange(base::TimeDelta duration) {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
duration_ = duration;
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnDurationChange();
- }
+ DCHECK(client_);
+ client_->OnDurationChange();
}
void PipelineImpl::OnAddTextTrack(const TextTrackConfig& config,
const AddTextTrackDoneCB& done_cb) {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnAddTextTrack(config, done_cb);
- }
+ DCHECK(client_);
+ client_->OnAddTextTrack(config, done_cb);
}
void PipelineImpl::OnWaitingForDecryptionKey() {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnWaitingForDecryptionKey();
- }
+ DCHECK(client_);
+ client_->OnWaitingForDecryptionKey();
}
void PipelineImpl::OnVideoNaturalSizeChange(const gfx::Size& size) {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnVideoNaturalSizeChange(size);
- }
+ DCHECK(client_);
+ client_->OnVideoNaturalSizeChange(size);
}
void PipelineImpl::OnVideoOpacityChange(bool opaque) {
DVLOG(2) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(client_);
- client_->OnVideoOpacityChange(opaque);
- }
-}
-
-void PipelineImpl::OnBufferedTimeRangesChange(
- const Ranges<base::TimeDelta>& ranges) {
- DVLOG(3) << __FUNCTION__;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- buffered_time_ranges_ = ranges;
- did_loading_progress_ = true;
-}
-
-void PipelineImpl::OnStatisticsUpdate(const PipelineStatistics& stats) {
- DVLOG(3) << __FUNCTION__;
- DCHECK(thread_checker_.CalledOnValidThread());
-
- statistics_.audio_bytes_decoded += stats.audio_bytes_decoded;
- statistics_.video_bytes_decoded += stats.video_bytes_decoded;
- statistics_.video_frames_decoded += stats.video_frames_decoded;
- statistics_.video_frames_dropped += stats.video_frames_dropped;
- statistics_.audio_memory_usage += stats.audio_memory_usage;
- statistics_.video_memory_usage += stats.video_memory_usage;
+ DCHECK(client_);
+ client_->OnVideoOpacityChange(opaque);
}
void PipelineImpl::OnSeekDone(base::TimeDelta start_time) {
DVLOG(3) << __FUNCTION__ << "(" << start_time.InMicroseconds() << ")";
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- if (IsRunning()) {
- DCHECK(!seek_cb_.is_null());
- base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
- }
+ DCHECK(!seek_cb_.is_null());
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
}
void PipelineImpl::OnSuspendDone(base::TimeDelta suspend_time) {
DVLOG(3) << __FUNCTION__ << "(" << suspend_time.InMicroseconds() << ")";
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(IsRunning());
- // Reset audio-video memory usage since renderer has been destroyed.
- statistics_.audio_memory_usage = 0;
- statistics_.video_memory_usage = 0;
-
- if (IsRunning()) {
- DCHECK(!suspend_cb_.is_null());
- base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK);
- }
+ DCHECK(!suspend_cb_.is_null());
+ base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK);
}
PipelineImpl::RendererWrapper::RendererWrapper(
- base::WeakPtr<PipelineImpl> weak_pipeline,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
scoped_refptr<MediaLog> media_log)
- : weak_pipeline_(weak_pipeline),
- media_task_runner_(std::move(media_task_runner)),
+ : media_task_runner_(std::move(media_task_runner)),
main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
media_log_(std::move(media_log)),
demuxer_(nullptr),
@@ -1181,7 +1211,6 @@ PipelineImpl::RendererWrapper::RendererWrapper(
cdm_context_(nullptr),
state_(kCreated),
status_(PIPELINE_OK),
- suspend_timestamp_(kNoTimestamp()),
renderer_ended_(false),
text_renderer_ended_(false),
weak_factory_(this) {
@@ -1194,16 +1223,14 @@ PipelineImpl::RendererWrapper::~RendererWrapper() {
DCHECK(state_ == kCreated || state_ == kStopped);
}
-base::TimeDelta PipelineImpl::RendererWrapper::GetMediaTime() {
- // This is the only member function that gets called on the main thread.
- // TODO(alokp): Enforce that Renderer is only called on a single thread,
- // even for accessing media time http://crbug.com/370634.
+base::TimeDelta PipelineImpl::RendererWrapper::GetMediaTime() const {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- base::AutoLock auto_lock(media_time_lock_);
- if (suspend_timestamp_ != kNoTimestamp())
- return suspend_timestamp_;
- return renderer_ ? renderer_->GetMediaTime() : base::TimeDelta();
+ base::AutoLock auto_lock(shared_state_lock_);
+ if (shared_state_.suspend_timestamp != kNoTimestamp())
+ return shared_state_.suspend_timestamp;
+ return shared_state_.renderer ? shared_state_.renderer->GetMediaTime()
+ : base::TimeDelta();
}
} // namespace media
« no previous file with comments | « media/base/pipeline_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698