summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralokp <alokp@chromium.org>2016-02-18 17:30:00 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-19 01:31:14 +0000
commit2ac89b3d8c3acc46b44e8f593220f5114047f210 (patch)
treed63e1a684909edb9fe3300ef0e8db2ecc91f0040
parent91c73e42354a73e8c651b9d8e811644799d2e354 (diff)
downloadchromium_src-2ac89b3d8c3acc46b44e8f593220f5114047f210.zip
chromium_src-2ac89b3d8c3acc46b44e8f593220f5114047f210.tar.gz
chromium_src-2ac89b3d8c3acc46b44e8f593220f5114047f210.tar.bz2
Refactors backend state management in MediaPipelineImpl.
Also moves the workaround for crbug.com/144683 from CmaRenderer to MediaPipelineImpl so that it can be shared by both CMA and mojo media pipeline. BUG=571155 Review URL: https://codereview.chromium.org/1709823002 Cr-Commit-Position: refs/heads/master@{#376334}
-rw-r--r--chromecast/media/cma/pipeline/media_pipeline_impl.cc71
-rw-r--r--chromecast/media/cma/pipeline/media_pipeline_impl.h18
-rw-r--r--chromecast/renderer/media/cma_renderer.cc11
3 files changed, 48 insertions, 52 deletions
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.cc b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
index 2ad1da0..2ae9c51 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.cc
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
@@ -61,12 +61,10 @@ struct MediaPipelineImpl::FlushTask {
MediaPipelineImpl::MediaPipelineImpl()
: cdm_(nullptr),
+ backend_state_(BACKEND_STATE_UNINITIALIZED),
+ playback_rate_(1.0f),
audio_decoder_(nullptr),
video_decoder_(nullptr),
- backend_initialized_(false),
- paused_(false),
- target_playback_rate_(1.0f),
- backend_started_(false),
pending_time_update_task_(false),
statistics_rolling_counter_(0),
weak_factory_(this) {
@@ -184,16 +182,14 @@ void MediaPipelineImpl::StartPlayingFrom(base::TimeDelta time) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(audio_pipeline_ || video_pipeline_);
DCHECK(!pending_flush_task_);
- // When starting, we always enter the "playing" state (not paused).
- paused_ = false;
- // Lazy initialise
- if (!backend_initialized_) {
- backend_initialized_ = media_pipeline_backend_->Initialize();
- if (!backend_initialized_) {
+ // Lazy initialize.
+ if (backend_state_ == BACKEND_STATE_UNINITIALIZED) {
+ if (!media_pipeline_backend_->Initialize()) {
OnError(::media::PIPELINE_ERROR_ABORT);
return;
}
+ backend_state_ = BACKEND_STATE_INITIALIZED;
}
// Start the backend.
@@ -201,9 +197,9 @@ void MediaPipelineImpl::StartPlayingFrom(base::TimeDelta time) {
OnError(::media::PIPELINE_ERROR_ABORT);
return;
}
+ backend_state_ = BACKEND_STATE_PLAYING;
// Enable time updates.
- backend_started_ = true;
statistics_rolling_counter_ = 0;
if (!pending_time_update_task_) {
pending_time_update_task_ = true;
@@ -235,10 +231,11 @@ void MediaPipelineImpl::StartPlayingFrom(base::TimeDelta time) {
void MediaPipelineImpl::Flush(const base::Closure& flush_cb) {
CMALOG(kLogControl) << __FUNCTION__;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK((backend_state_ == BACKEND_STATE_PLAYING) ||
+ (backend_state_ == BACKEND_STATE_PAUSED));
DCHECK(audio_pipeline_ || video_pipeline_);
DCHECK(!pending_flush_task_);
- backend_started_ = false;
buffering_controller_->Reset();
// 1. Stop both the audio and video pipeline so that they stop feeding
@@ -251,6 +248,7 @@ void MediaPipelineImpl::Flush(const base::Closure& flush_cb) {
// 2. Stop the backend, so that the backend won't push their pending buffer,
// which may be invalidated later, to hardware. (b/25342604)
CHECK(media_pipeline_backend_->Stop());
+ backend_state_ = BACKEND_STATE_INITIALIZED;
// 3. Flush both the audio and video pipeline. This will flush the frame
// provider and invalidate all the unreleased buffers.
@@ -277,7 +275,6 @@ void MediaPipelineImpl::Stop() {
// audio/video pipelines. This will ensure A/V Flush won't happen in
// stopped state.
pending_flush_task_.reset();
- backend_started_ = false;
// Stop both the audio and video pipeline.
if (audio_pipeline_)
@@ -290,26 +287,28 @@ void MediaPipelineImpl::Stop() {
video_pipeline_ = nullptr;
audio_decoder_.reset();
media_pipeline_backend_.reset();
+ backend_state_ = BACKEND_STATE_UNINITIALIZED;
}
void MediaPipelineImpl::SetPlaybackRate(double rate) {
CMALOG(kLogControl) << __FUNCTION__ << " rate=" << rate;
DCHECK(thread_checker_.CalledOnValidThread());
- target_playback_rate_ = rate;
- if (!backend_started_)
- return;
+ DCHECK((backend_state_ == BACKEND_STATE_PLAYING) ||
+ (backend_state_ == BACKEND_STATE_PAUSED));
+
+ playback_rate_ = rate;
if (buffering_controller_ && buffering_controller_->IsBuffering())
return;
if (rate != 0.0f) {
media_pipeline_backend_->SetPlaybackRate(rate);
- if (paused_) {
- paused_ = false;
+ if (backend_state_ == BACKEND_STATE_PAUSED) {
media_pipeline_backend_->Resume();
+ backend_state_ = BACKEND_STATE_PLAYING;
}
- } else if (!paused_) {
- paused_ = true;
+ } else if (backend_state_ == BACKEND_STATE_PLAYING) {
media_pipeline_backend_->Pause();
+ backend_state_ = BACKEND_STATE_PAUSED;
}
}
@@ -359,33 +358,37 @@ void MediaPipelineImpl::OnFlushDone(bool is_audio_stream) {
void MediaPipelineImpl::OnBufferingNotification(bool is_buffering) {
CMALOG(kLogControl) << __FUNCTION__ << " is_buffering=" << is_buffering;
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK((backend_state_ == BACKEND_STATE_PLAYING) ||
+ (backend_state_ == BACKEND_STATE_PAUSED));
DCHECK(buffering_controller_);
+ DCHECK_EQ(is_buffering, buffering_controller_->IsBuffering());
if (!client_.buffering_state_cb.is_null()) {
- ::media::BufferingState buffering_state =
- is_buffering ? ::media::BUFFERING_HAVE_NOTHING
- : ::media::BUFFERING_HAVE_ENOUGH;
- client_.buffering_state_cb.Run(buffering_state);
+ if (is_buffering) {
+ // TODO(alokp): WebMediaPlayerImpl currently only handles HAVE_ENOUGH.
+ // See WebMediaPlayerImpl::OnPipelineBufferingStateChanged,
+ // http://crbug.com/144683.
+ LOG(WARNING) << "Ignoring buffering notification.";
+ } else {
+ client_.buffering_state_cb.Run(::media::BUFFERING_HAVE_ENOUGH);
+ }
}
- if (!is_buffering) {
- DCHECK(!buffering_controller_->IsBuffering());
+ if (is_buffering && (backend_state_ == BACKEND_STATE_PLAYING)) {
+ media_pipeline_backend_->Pause();
+ backend_state_ = BACKEND_STATE_PAUSED;
+ } else if (!is_buffering && (backend_state_ == BACKEND_STATE_PAUSED)) {
// Once we finish buffering, we need to honour the desired playback rate
// (rather than just resuming). This way, if playback was paused while
// buffering, it will remain paused rather than incorrectly resuming.
- SetPlaybackRate(target_playback_rate_);
- return;
- }
- // Do not consume data in a rebuffering phase.
- if (!paused_) {
- paused_ = true;
- media_pipeline_backend_->Pause();
+ SetPlaybackRate(playback_rate_);
}
}
void MediaPipelineImpl::UpdateMediaTime() {
pending_time_update_task_ = false;
- if (!backend_started_)
+ if ((backend_state_ != BACKEND_STATE_PLAYING) &&
+ (backend_state_ != BACKEND_STATE_PAUSED))
return;
if (statistics_rolling_counter_ == 0) {
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.h b/chromecast/media/cma/pipeline/media_pipeline_impl.h
index 6f6c8d6..6773643 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.h
@@ -66,6 +66,12 @@ class MediaPipelineImpl {
void SetCdm(BrowserCdmCast* cdm);
private:
+ enum BackendState {
+ BACKEND_STATE_UNINITIALIZED,
+ BACKEND_STATE_INITIALIZED,
+ BACKEND_STATE_PLAYING,
+ BACKEND_STATE_PAUSED
+ };
struct FlushTask;
void OnFlushDone(bool is_audio_stream);
@@ -82,22 +88,20 @@ class MediaPipelineImpl {
BrowserCdmCast* cdm_;
// Interface with the underlying hardware media pipeline.
+ BackendState backend_state_;
+ // Playback rate set by the upper layer.
+ // Cached here because CMA pipeline backend does not support rate == 0,
+ // which is emulated by pausing the backend.
+ float playback_rate_;
scoped_ptr<MediaPipelineBackend> media_pipeline_backend_;
scoped_ptr<AudioDecoderSoftwareWrapper> audio_decoder_;
MediaPipelineBackend::VideoDecoder* video_decoder_;
- bool backend_initialized_;
scoped_ptr<AudioPipelineImpl> audio_pipeline_;
scoped_ptr<VideoPipelineImpl> video_pipeline_;
scoped_ptr<FlushTask> pending_flush_task_;
- // Whether or not the backend is currently paused.
- bool paused_;
- // Playback rate set by the upper layer.
- float target_playback_rate_;
-
// The media time is retrieved at regular intervals.
- bool backend_started_; // Whether or not the backend is playing/paused.
bool pending_time_update_task_;
base::TimeDelta last_media_time_;
diff --git a/chromecast/renderer/media/cma_renderer.cc b/chromecast/renderer/media/cma_renderer.cc
index 088ebb8..41ef271 100644
--- a/chromecast/renderer/media/cma_renderer.cc
+++ b/chromecast/renderer/media/cma_renderer.cc
@@ -431,17 +431,6 @@ void CmaRenderer::OnBufferingNotification(
::media::BufferingState buffering_state) {
CMALOG(kLogControl) << __FUNCTION__ << ": state=" << state_
<< ", buffering=" << buffering_state;
- // TODO(gunsch): WebMediaPlayerImpl currently only handles HAVE_ENOUGH while
- // playing. See OnPipelineBufferingStateChanged, http://crbug.com/144683.
- if (state_ != kPlaying) {
- LOG(WARNING) << "Ignoring buffering notification in state: " << state_;
- return;
- }
- if (buffering_state != ::media::BUFFERING_HAVE_ENOUGH) {
- LOG(WARNING) << "Ignoring buffering notification during playing: "
- << buffering_state;
- return;
- }
buffering_state_cb_.Run(buffering_state);
}