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

Unified Diff: media/base/pipeline.cc

Issue 10854151: Allow transitioning to HAVE_METADATA before pipeline initialization completes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments and fix tests. Created 8 years, 4 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
Index: media/base/pipeline.cc
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index 55f8a408f3d392aca5e1065a93954fad5fd49c53..5e62868bcbb430c6b82c51d68a42b8d6ccd3c9cb 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -22,6 +22,7 @@
#include "media/base/filter_collection.h"
#include "media/base/media_log.h"
#include "media/base/video_decoder.h"
+#include "media/base/video_decoder_config.h"
#include "media/base/video_renderer.h"
using base::TimeDelta;
@@ -108,14 +109,15 @@ Pipeline::~Pipeline() {
void Pipeline::Start(scoped_ptr<FilterCollection> collection,
const PipelineStatusCB& ended_cb,
const PipelineStatusCB& error_cb,
- const PipelineStatusCB& start_cb) {
+ const PipelineStatusCB& seek_cb,
+ const ReadyStateCB& ready_state_cb) {
base::AutoLock auto_lock(lock_);
CHECK(!running_) << "Media pipeline is already running";
running_ = true;
message_loop_->PostTask(FROM_HERE, base::Bind(
&Pipeline::StartTask, this, base::Passed(&collection),
- ended_cb, error_cb, start_cb));
+ ended_cb, error_cb, seek_cb, ready_state_cb));
}
void Pipeline::Stop(const base::Closure& stop_cb) {
@@ -281,12 +283,14 @@ void Pipeline::ReportStatus(const PipelineStatusCB& cb, PipelineStatus status) {
error_cb_.Reset();
}
-void Pipeline::FinishInitialization() {
+void Pipeline::FinishSeek() {
DCHECK(message_loop_->BelongsToCurrentThread());
+ seek_timestamp_ = kNoTimestamp();
+ seek_pending_ = false;
+
// Execute the seek callback, if present. Note that this might be the
// initial callback passed into Start().
ReportStatus(seek_cb_, status_);
- seek_timestamp_ = kNoTimestamp();
seek_cb_.Reset();
}
@@ -551,7 +555,8 @@ void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) {
void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection,
const PipelineStatusCB& ended_cb,
const PipelineStatusCB& error_cb,
- const PipelineStatusCB& start_cb) {
+ const PipelineStatusCB& seek_cb,
+ const ReadyStateCB& ready_state_cb) {
DCHECK(message_loop_->BelongsToCurrentThread());
CHECK_EQ(kCreated, state_)
<< "Media pipeline cannot be started more than once";
@@ -559,7 +564,8 @@ void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection,
filter_collection_ = filter_collection.Pass();
ended_cb_ = ended_cb;
error_cb_ = error_cb;
- seek_cb_ = start_cb;
+ seek_cb_ = seek_cb;
+ ready_state_cb_ = ready_state_cb;
// Kick off initialization.
pipeline_init_state_.reset(new PipelineInitState());
@@ -625,9 +631,15 @@ void Pipeline::InitializeTask(PipelineStatus last_stage_status) {
// Assuming audio renderer was created, create video renderer.
if (state_ == kInitAudioRenderer) {
SetState(kInitVideoRenderer);
- if (InitializeVideoRenderer(demuxer_->GetStream(DemuxerStream::VIDEO))) {
+ scoped_refptr<DemuxerStream> video_stream =
+ demuxer_->GetStream(DemuxerStream::VIDEO);
+ if (InitializeVideoRenderer(video_stream)) {
base::AutoLock auto_lock(lock_);
has_video_ = true;
+
+ // Get an initial natural size so we have something when we signal
+ // the kHaveMetadata ready state.
+ natural_size_ = video_stream->video_decoder_config().natural_size();
return;
}
}
@@ -647,6 +659,9 @@ void Pipeline::InitializeTask(PipelineStatus last_stage_status) {
PlaybackRateChangedTask(GetPlaybackRate());
VolumeChangedTask(GetVolume());
+ if (!ready_state_cb_.is_null())
+ ready_state_cb_.Run(kHaveMetadata);
+
// Fire a seek request to get the renderers to preroll. We can skip a seek
// here as the demuxer should be at the start of the stream.
seek_pending_ = true;
@@ -904,10 +919,14 @@ void Pipeline::FilterStateTransitionTask() {
NOTREACHED() << "Unexpected state: " << state_;
}
} else if (state_ == kStarted) {
- FinishInitialization();
- // Finally, complete the seek.
- seek_pending_ = false;
+ // Fire canplaythrough immediately after playback begins because of
+ // crbug.com/106480.
+ // TODO(vrk): set ready state to HaveFutureData when bug above is fixed.
+ if (!ready_state_cb_.is_null() && status_ == PIPELINE_OK)
+ ready_state_cb_.Run(kHaveEnoughData);
+
+ FinishSeek();
// If a playback rate change was requested during a seek, do it now that
// the seek has compelted.
@@ -1143,7 +1162,7 @@ void Pipeline::TearDownPipeline() {
SetState(kStopping);
DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this));
- FinishInitialization();
+ FinishSeek();
break;
case kPausing:
@@ -1153,10 +1172,8 @@ void Pipeline::TearDownPipeline() {
SetState(kStopping);
DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this));
- if (seek_pending_) {
- seek_pending_ = false;
- FinishInitialization();
- }
+ if (seek_pending_)
+ FinishSeek();
break;

Powered by Google App Engine
This is Rietveld 408576698