summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-26 00:05:16 +0000
committererikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-26 00:05:16 +0000
commit0b3bf8a498bf255197f21ddba0f645a2a3a9e3bc (patch)
treeb24da4514899327a1a9870464cb7076389edc39a
parent923c7ad68f067f57afcb4edec224ac346f792ad3 (diff)
downloadchromium_src-0b3bf8a498bf255197f21ddba0f645a2a3a9e3bc.zip
chromium_src-0b3bf8a498bf255197f21ddba0f645a2a3a9e3bc.tar.gz
chromium_src-0b3bf8a498bf255197f21ddba0f645a2a3a9e3bc.tar.bz2
Revert of Remove Has{Audio,Video}(), GetInitialNaturalSize() from media::Pipeline. (https://codereview.chromium.org/211313004/)
Reason for revert: This CL breaks Linux Clang (dbg) Build http://build.chromium.org/p/chromium.linux/builders/Linux%20Clang%20%28dbg%29/builds/57597 http://build.chromium.org/p/chromium.linux/builders/Linux%20Clang%20%28dbg%29/builds/57598 from thakis: the problem is probably that ffmpeg_regression_tests doesn't link in gfx_geometry and you're missing a dep on that Original issue's description: > Remove Has{Audio,Video}(), GetInitialNaturalSize() from media::Pipeline. > > This splits PipelineBufferingStateCB in two: PipelineMetadataCB, which > includes the available tracks and natural size in a PipelineMetadata > struct; and PipelinePrerollCompleted, with no parameters. Now > WebMediaPlayerImpl can cache the metadata and the accessors are not > required. > > This was previously committed as r259154. > > BUG=148541 > > Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=259385 TBR=scherkus@chromium.org,dalecurtis@chromium.org,sandersd@chromium.org NOTREECHECKS=true NOTRY=true BUG=148541 Review URL: https://codereview.chromium.org/209043005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@259402 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/renderer/media/webmediaplayer_impl.cc66
-rw-r--r--content/renderer/media/webmediaplayer_impl.h8
-rw-r--r--media/base/pipeline.cc99
-rw-r--r--media/base/pipeline.h73
-rw-r--r--media/base/pipeline_unittest.cc68
-rw-r--r--media/filters/pipeline_integration_test.cc21
-rw-r--r--media/filters/pipeline_integration_test_base.cc23
-rw-r--r--media/filters/pipeline_integration_test_base.h3
-rw-r--r--media/tools/player_x11/player_x11.cc22
9 files changed, 214 insertions, 169 deletions
diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc
index 952f644..7dbe239 100644
--- a/content/renderer/media/webmediaplayer_impl.cc
+++ b/content/renderer/media/webmediaplayer_impl.cc
@@ -436,19 +436,19 @@ void WebMediaPlayerImpl::setPreload(WebMediaPlayer::Preload preload) {
bool WebMediaPlayerImpl::hasVideo() const {
DCHECK(main_loop_->BelongsToCurrentThread());
- return pipeline_metadata_.has_video;
+ return pipeline_.HasVideo();
}
bool WebMediaPlayerImpl::hasAudio() const {
DCHECK(main_loop_->BelongsToCurrentThread());
- return pipeline_metadata_.has_audio;
+ return pipeline_.HasAudio();
}
blink::WebSize WebMediaPlayerImpl::naturalSize() const {
DCHECK(main_loop_->BelongsToCurrentThread());
- return blink::WebSize(pipeline_metadata_.natural_size);
+ return blink::WebSize(natural_size_);
}
bool WebMediaPlayerImpl::paused() const {
@@ -958,19 +958,33 @@ void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) {
InvalidateOnMainThread();
}
-void WebMediaPlayerImpl::OnPipelineMetadata(
- media::PipelineMetadata metadata) {
- DVLOG(1) << "OnPipelineMetadata";
-
- pipeline_metadata_ = metadata;
-
- SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
-
- if (hasVideo()) {
- DCHECK(!video_weblayer_);
- video_weblayer_.reset(new webkit::WebLayerImpl(
- cc::VideoLayer::Create(compositor_.GetVideoFrameProvider())));
- client_->setWebLayer(video_weblayer_.get());
+void WebMediaPlayerImpl::OnPipelineBufferingState(
+ media::Pipeline::BufferingState buffering_state) {
+ DVLOG(1) << "OnPipelineBufferingState(" << buffering_state << ")";
+
+ switch (buffering_state) {
+ case media::Pipeline::kHaveMetadata:
+ // TODO(scherkus): Would be better to have a metadata changed callback
+ // that contained the size information as well whether audio/video is
+ // present. Doing so would let us remove more methods off Pipeline.
+ natural_size_ = pipeline_.GetInitialNaturalSize();
+
+ SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
+
+ if (hasVideo()) {
+ DCHECK(!video_weblayer_);
+ video_weblayer_.reset(new webkit::WebLayerImpl(
+ cc::VideoLayer::Create(compositor_.GetVideoFrameProvider())));
+ client_->setWebLayer(video_weblayer_.get());
+ }
+ break;
+ case media::Pipeline::kPrerollCompleted:
+ // Only transition to ReadyStateHaveEnoughData if we don't have
+ // any pending seeks because the transition can cause Blink to
+ // report that the most recent seek has completed.
+ if (!pending_seek_)
+ SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
+ break;
}
// TODO(scherkus): This should be handled by HTMLMediaElement and controls
@@ -978,21 +992,6 @@ void WebMediaPlayerImpl::OnPipelineMetadata(
InvalidateOnMainThread();
}
-void WebMediaPlayerImpl::OnPipelinePrerollCompleted() {
- DVLOG(1) << "OnPipelinePrerollCompleted";
-
- // Only transition to ReadyStateHaveEnoughData if we don't have
- // any pending seeks because the transition can cause Blink to
- // report that the most recent seek has completed.
- if (!pending_seek_) {
- SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
-
- // TODO(scherkus): This should be handled by HTMLMediaElement and controls
- // should know when to invalidate themselves http://crbug.com/337015
- InvalidateOnMainThread();
- }
-}
-
void WebMediaPlayerImpl::OnDemuxerOpened() {
DCHECK(main_loop_->BelongsToCurrentThread());
client_->mediaSourceOpened(new WebMediaSourceImpl(
@@ -1211,8 +1210,7 @@ void WebMediaPlayerImpl::StartPipeline() {
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek),
- BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata),
- BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelinePrerollCompleted),
+ BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingState),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChange));
}
@@ -1274,7 +1272,7 @@ void WebMediaPlayerImpl::OnNaturalSizeChange(gfx::Size size) {
media_log_->AddEvent(
media_log_->CreateVideoSizeSetEvent(size.width(), size.height()));
- pipeline_metadata_.natural_size = size;
+ natural_size_ = size;
client_->sizeChanged();
}
diff --git a/content/renderer/media/webmediaplayer_impl.h b/content/renderer/media/webmediaplayer_impl.h
index cdbeae9..b3516c5 100644
--- a/content/renderer/media/webmediaplayer_impl.h
+++ b/content/renderer/media/webmediaplayer_impl.h
@@ -166,8 +166,8 @@ class WebMediaPlayerImpl
void OnPipelineSeek(media::PipelineStatus status);
void OnPipelineEnded();
void OnPipelineError(media::PipelineStatus error);
- void OnPipelineMetadata(media::PipelineMetadata metadata);
- void OnPipelinePrerollCompleted();
+ void OnPipelineBufferingState(
+ media::Pipeline::BufferingState buffering_state);
void OnDemuxerOpened();
void OnKeyAdded(const std::string& session_id);
void OnKeyError(const std::string& session_id,
@@ -261,9 +261,6 @@ class WebMediaPlayerImpl
// The LoadType passed in the |load_type| parameter of the load() call.
LoadType load_type_;
- // Cache of metadata for answering hasAudio(), hasVideo(), and naturalSize().
- media::PipelineMetadata pipeline_metadata_;
-
// Playback state.
//
// TODO(scherkus): we have these because Pipeline favours the simplicity of a
@@ -326,6 +323,7 @@ class WebMediaPlayerImpl
// Video rendering members.
VideoFrameCompositor compositor_;
media::SkCanvasVideoRenderer skcanvas_video_renderer_;
+ gfx::Size natural_size_;
// The compositor layer for displaying the video content when using composited
// playback.
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index 8c0ca54..824585f 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -45,6 +45,8 @@ Pipeline::Pipeline(
clock_(new Clock(&default_tick_clock_)),
waiting_for_clock_update_(false),
status_(PIPELINE_OK),
+ has_audio_(false),
+ has_video_(false),
state_(kCreated),
audio_ended_(false),
video_ended_(false),
@@ -72,29 +74,16 @@ void Pipeline::Start(scoped_ptr<FilterCollection> collection,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
const PipelineStatusCB& seek_cb,
- const PipelineMetadataCB& metadata_cb,
- const base::Closure& preroll_completed_cb,
+ const BufferingStateCB& buffering_state_cb,
const base::Closure& duration_change_cb) {
- DCHECK(!ended_cb.is_null());
- DCHECK(!error_cb.is_null());
- DCHECK(!seek_cb.is_null());
- DCHECK(!metadata_cb.is_null());
- DCHECK(!preroll_completed_cb.is_null());
-
base::AutoLock auto_lock(lock_);
CHECK(!running_) << "Media pipeline is already running";
- running_ = true;
-
- filter_collection_ = collection.Pass();
- ended_cb_ = ended_cb;
- error_cb_ = error_cb;
- seek_cb_ = seek_cb;
- metadata_cb_ = metadata_cb;
- preroll_completed_cb_ = preroll_completed_cb;
- duration_change_cb_ = duration_change_cb;
+ DCHECK(!buffering_state_cb.is_null());
- task_runner_->PostTask(
- FROM_HERE, base::Bind(&Pipeline::StartTask, base::Unretained(this)));
+ running_ = true;
+ task_runner_->PostTask(FROM_HERE, base::Bind(
+ &Pipeline::StartTask, base::Unretained(this), base::Passed(&collection),
+ ended_cb, error_cb, seek_cb, buffering_state_cb, duration_change_cb));
}
void Pipeline::Stop(const base::Closure& stop_cb) {
@@ -119,6 +108,16 @@ bool Pipeline::IsRunning() const {
return running_;
}
+bool Pipeline::HasAudio() const {
+ base::AutoLock auto_lock(lock_);
+ return has_audio_;
+}
+
+bool Pipeline::HasVideo() const {
+ base::AutoLock auto_lock(lock_);
+ return has_video_;
+}
+
float Pipeline::GetPlaybackRate() const {
base::AutoLock auto_lock(lock_);
return playback_rate_;
@@ -189,6 +188,11 @@ int64 Pipeline::GetTotalBytes() const {
return total_bytes_;
}
+gfx::Size Pipeline::GetInitialNaturalSize() const {
+ base::AutoLock auto_lock(lock_);
+ return initial_natural_size_;
+}
+
bool Pipeline::DidLoadingProgress() const {
base::AutoLock auto_lock(lock_);
bool ret = did_loading_progress_;
@@ -329,9 +333,8 @@ void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) {
DCHECK(IsRunning());
base::AutoLock auto_lock(lock_);
- if (audio_disabled_)
+ if (!has_audio_)
return;
-
if (waiting_for_clock_update_ && time < clock_->Elapsed())
return;
@@ -348,7 +351,7 @@ void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) {
DCHECK(IsRunning());
base::AutoLock auto_lock(lock_);
- if (audio_renderer_ && !audio_disabled_)
+ if (has_audio_)
return;
// TODO(scherkus): |state_| should only be accessed on pipeline thread, see
@@ -459,21 +462,20 @@ void Pipeline::StateTransitionTask(PipelineStatus status) {
// We do not want to start the clock running. We only want to set the
// base media time so our timestamp calculations will be correct.
clock_->SetTime(demuxer_->GetStartTime(), demuxer_->GetStartTime());
+
+ // TODO(scherkus): |has_audio_| should be true no matter what --
+ // otherwise people with muted/disabled sound cards will make our
+ // default controls look as if every video doesn't contain an audio
+ // track.
+ has_audio_ = audio_renderer_ != NULL && !audio_disabled_;
+ has_video_ = video_renderer_ != NULL;
}
if (!audio_renderer_ && !video_renderer_) {
done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER);
return;
}
- {
- PipelineMetadata metadata;
- metadata.has_audio = audio_renderer_;
- metadata.has_video = video_renderer_;
- DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
- if (stream)
- metadata.natural_size = stream->video_decoder_config().natural_size();
- metadata_cb_.Run(metadata);
- }
+ buffering_state_cb_.Run(kHaveMetadata);
return DoInitialPreroll(done_cb);
@@ -486,7 +488,7 @@ void Pipeline::StateTransitionTask(PipelineStatus status) {
// We use audio stream to update the clock. So if there is such a
// stream, we pause the clock until we receive a valid timestamp.
waiting_for_clock_update_ = true;
- if (!audio_renderer_ || audio_disabled_) {
+ if (!has_audio_) {
clock_->SetMaxTime(clock_->Duration());
StartClockIfWaitingForTimeUpdate_Locked();
}
@@ -498,7 +500,7 @@ void Pipeline::StateTransitionTask(PipelineStatus status) {
// Fire canplaythrough immediately after playback begins because of
// crbug.com/106480.
// TODO(vrk): set ready state to HaveFutureData when bug above is fixed.
- preroll_completed_cb_.Run();
+ buffering_state_cb_.Run(kPrerollCompleted);
return base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
case kStopping:
@@ -729,11 +731,23 @@ void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) {
statistics_.video_frames_dropped += stats.video_frames_dropped;
}
-void Pipeline::StartTask() {
+void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const PipelineStatusCB& seek_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const base::Closure& duration_change_cb) {
DCHECK(task_runner_->BelongsToCurrentThread());
CHECK_EQ(kCreated, state_)
<< "Media pipeline cannot be started more than once";
+ filter_collection_ = filter_collection.Pass();
+ ended_cb_ = ended_cb;
+ error_cb_ = error_cb;
+ seek_cb_ = seek_cb;
+ buffering_state_cb_ = buffering_state_cb;
+ duration_change_cb_ = duration_change_cb;
+
text_renderer_ = filter_collection_->GetTextRenderer();
if (text_renderer_) {
@@ -911,6 +925,7 @@ void Pipeline::AudioDisabledTask() {
DCHECK(task_runner_->BelongsToCurrentThread());
base::AutoLock auto_lock(lock_);
+ has_audio_ = false;
audio_disabled_ = true;
// Notify our demuxer that we're no longer rendering audio.
@@ -959,9 +974,23 @@ void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) {
void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) {
DCHECK(task_runner_->BelongsToCurrentThread());
+ // Get an initial natural size so we have something when we signal
+ // the kHaveMetadata buffering state.
+ //
+ // TODO(acolwell): We have to query demuxer outside of the lock to prevent a
+ // deadlock between ChunkDemuxer and Pipeline. See http://crbug.com/334325 for
+ // ideas on removing locking from ChunkDemuxer.
+ DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
+ gfx::Size initial_natural_size =
+ stream->video_decoder_config().natural_size();
+ {
+ base::AutoLock l(lock_);
+ initial_natural_size_ = initial_natural_size;
+ }
+
video_renderer_ = filter_collection_->GetVideoRenderer();
video_renderer_->Initialize(
- demuxer_->GetStream(DemuxerStream::VIDEO),
+ stream,
done_cb,
base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)),
base::Bind(&Pipeline::OnVideoTimeUpdate, base::Unretained(this)),
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 4b78eb7..9b0ebdf 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -34,17 +34,6 @@ class TextRenderer;
class TextTrackConfig;
class VideoRenderer;
-// Metadata describing a pipeline once it has been initialized.
-struct PipelineMetadata {
- PipelineMetadata() : has_audio(false), has_video(false) {}
-
- bool has_audio;
- bool has_video;
- gfx::Size natural_size;
-};
-
-typedef base::Callback<void(PipelineMetadata)> PipelineMetadataCB;
-
// Pipeline runs the media pipeline. Filters are created and called on the
// task runner injected into this object. Pipeline works like a state
// machine to perform asynchronous initialization, pausing, seeking and playing.
@@ -78,6 +67,21 @@ typedef base::Callback<void(PipelineMetadata)> PipelineMetadataCB;
// "Stopped" state.
class MEDIA_EXPORT Pipeline : public DemuxerHost {
public:
+ // Buffering states the pipeline transitions between during playback.
+ // kHaveMetadata:
+ // Indicates that the following things are known:
+ // content duration, container video size, start time, and whether the
+ // content has audio and/or video in supported formats.
+ // kPrerollCompleted:
+ // All renderers have buffered enough data to satisfy preroll and are ready
+ // to start playback.
+ enum BufferingState {
+ kHaveMetadata,
+ kPrerollCompleted,
+ };
+
+ typedef base::Callback<void(BufferingState)> BufferingStateCB;
+
// Constructs a media pipeline that will execute on |task_runner|.
Pipeline(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
MediaLog* media_log);
@@ -93,23 +97,18 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// The following permanent callbacks will be executed as follows up until
// Stop() has completed:
// |ended_cb| will be executed whenever the media reaches the end.
- // |error_cb| will be executed whenever an error occurs but hasn't been
- // reported already through another callback.
- // |metadata_cb| will be executed when the content duration, container video
- // size, start time, and whether the content has audio and/or
- // video in supported formats are known.
- // |preroll_completed_cb| will be executed when all renderers have buffered
- // enough data to satisfy preroll and are ready to
- // start playback.
- // |duration_change_cb| optional callback that will be executed whenever the
+ // |error_cb| will be executed whenever an error occurs but hasn't
+ // been reported already through another callback.
+ // |buffering_state_cb| Optional callback that will be executed whenever the
+ // pipeline's buffering state changes.
+ // |duration_change_cb| Optional callback that will be executed whenever the
// presentation duration changes.
// It is an error to call this method after the pipeline has already started.
void Start(scoped_ptr<FilterCollection> filter_collection,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
const PipelineStatusCB& seek_cb,
- const PipelineMetadataCB& metadata_cb,
- const base::Closure& preroll_completed_cb,
+ const BufferingStateCB& buffering_state_cb,
const base::Closure& duration_change_cb);
// Asynchronously stops the pipeline, executing |stop_cb| when the pipeline
@@ -135,6 +134,12 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// the pipeline.
bool IsRunning() const;
+ // Returns true if the media has audio.
+ bool HasAudio() const;
+
+ // Returns true if the media has video.
+ bool HasVideo() const;
+
// Gets the current playback rate of the pipeline. When the pipeline is
// started, the playback rate will be 0.0f. A rate of 1.0f indicates
// that the pipeline is rendering the media at the standard rate. Valid
@@ -173,6 +178,10 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// determined or can not be determined, this value is 0.
int64 GetTotalBytes() const;
+ // Get the video's initial natural size as reported by the container. Note
+ // that the natural size can change during playback.
+ gfx::Size GetInitialNaturalSize() const;
+
// Return true if loading progress has been made since the last time this
// method was called.
bool DidLoadingProgress() const;
@@ -253,7 +262,12 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// The following "task" methods correspond to the public methods, but these
// methods are run as the result of posting a task to the Pipeline's
// task runner.
- void StartTask();
+ void StartTask(scoped_ptr<FilterCollection> filter_collection,
+ const base::Closure& ended_cb,
+ const PipelineStatusCB& error_cb,
+ const PipelineStatusCB& seek_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const base::Closure& duration_change_cb);
// Stops and destroys all filters, placing the pipeline in the kStopped state.
void StopTask(const base::Closure& stop_cb);
@@ -356,6 +370,9 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// Total size of the media. Set by filters.
int64 total_bytes_;
+ // The initial natural size of the video as reported by the container.
+ gfx::Size initial_natural_size_;
+
// Current volume level (from 0.0f to 1.0f). This value is set immediately
// via SetVolume() and a task is dispatched on the task runner to notify the
// filters.
@@ -385,6 +402,13 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// reset the pipeline state, and restore this to PIPELINE_OK.
PipelineStatus status_;
+ // Whether the media contains rendered audio or video streams.
+ // TODO(fischman,scherkus): replace these with checks for
+ // {audio,video}_decoder_ once extraction of {Audio,Video}Decoder from the
+ // Filter heirarchy is done.
+ bool has_audio_;
+ bool has_video_;
+
// The following data members are only accessed by tasks posted to
// |task_runner_|.
@@ -408,8 +432,7 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
// Permanent callbacks passed in via Start().
base::Closure ended_cb_;
PipelineStatusCB error_cb_;
- PipelineMetadataCB metadata_cb_;
- base::Closure preroll_completed_cb_;
+ BufferingStateCB buffering_state_cb_;
base::Closure duration_change_cb_;
// Contains the demuxer and renderers to use when initializing.
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 6e51802..3264226 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -66,8 +66,7 @@ class CallbackHelper {
MOCK_METHOD0(OnStop, void());
MOCK_METHOD0(OnEnded, void());
MOCK_METHOD1(OnError, void(PipelineStatus));
- MOCK_METHOD1(OnMetadata, void(PipelineMetadata));
- MOCK_METHOD0(OnPrerollCompleted, void());
+ MOCK_METHOD1(OnBufferingState, void(Pipeline::BufferingState));
MOCK_METHOD0(OnDurationChange, void());
private:
@@ -204,7 +203,7 @@ class PipelineTest : public ::testing::Test {
EXPECT_CALL(callbacks_, OnStart(start_status));
if (start_status == PIPELINE_OK) {
- EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_));
+ EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kHaveMetadata));
if (audio_stream_) {
EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));
@@ -216,7 +215,7 @@ class PipelineTest : public ::testing::Test {
EXPECT_CALL(*audio_renderer_, Play(_))
.WillOnce(RunClosure<0>());
}
- EXPECT_CALL(callbacks_, OnPrerollCompleted());
+ EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
}
pipeline_->Start(
@@ -224,8 +223,7 @@ class PipelineTest : public ::testing::Test {
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnPrerollCompleted,
+ base::Bind(&CallbackHelper::OnBufferingState,
base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnDurationChange,
base::Unretained(&callbacks_)));
@@ -288,7 +286,7 @@ class PipelineTest : public ::testing::Test {
.WillOnce(RunClosure<0>());
}
- EXPECT_CALL(callbacks_, OnPrerollCompleted());
+ EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
// We expect a successful seek callback.
EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
@@ -342,7 +340,6 @@ class PipelineTest : public ::testing::Test {
scoped_ptr<FakeTextTrackStream> text_stream_;
AudioRenderer::TimeCB audio_time_cb_;
VideoDecoderConfig video_decoder_config_;
- PipelineMetadata metadata_;
private:
DISALLOW_COPY_AND_ASSIGN(PipelineTest);
@@ -354,6 +351,8 @@ TEST_F(PipelineTest, NotStarted) {
const base::TimeDelta kZero;
EXPECT_FALSE(pipeline_->IsRunning());
+ EXPECT_FALSE(pipeline_->HasAudio());
+ EXPECT_FALSE(pipeline_->HasVideo());
// Setting should still work.
EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate());
@@ -374,6 +373,11 @@ TEST_F(PipelineTest, NotStarted) {
EXPECT_TRUE(kZero == pipeline_->GetMediaDuration());
EXPECT_EQ(0, pipeline_->GetTotalBytes());
+
+ // Should always be zero.
+ gfx::Size size = pipeline_->GetInitialNaturalSize();
+ EXPECT_EQ(0, size.width());
+ EXPECT_EQ(0, size.height());
}
TEST_F(PipelineTest, NeverInitializes) {
@@ -388,8 +392,7 @@ TEST_F(PipelineTest, NeverInitializes) {
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnPrerollCompleted,
+ base::Bind(&CallbackHelper::OnBufferingState,
base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnDurationChange,
base::Unretained(&callbacks_)));
@@ -430,8 +433,8 @@ TEST_F(PipelineTest, AudioStream) {
InitializeAudioRenderer(audio_stream(), false);
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(metadata_.has_audio);
- EXPECT_FALSE(metadata_.has_video);
+ EXPECT_TRUE(pipeline_->HasAudio());
+ EXPECT_FALSE(pipeline_->HasVideo());
}
TEST_F(PipelineTest, VideoStream) {
@@ -443,8 +446,8 @@ TEST_F(PipelineTest, VideoStream) {
InitializeVideoRenderer(video_stream());
InitializePipeline(PIPELINE_OK);
- EXPECT_FALSE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_FALSE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
}
TEST_F(PipelineTest, AudioVideoStream) {
@@ -459,8 +462,8 @@ TEST_F(PipelineTest, AudioVideoStream) {
InitializeVideoRenderer(video_stream());
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_TRUE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
}
TEST_F(PipelineTest, VideoTextStream) {
@@ -473,8 +476,8 @@ TEST_F(PipelineTest, VideoTextStream) {
InitializeVideoRenderer(video_stream());
InitializePipeline(PIPELINE_OK);
- EXPECT_FALSE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_FALSE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
AddTextStream();
message_loop_.RunUntilIdle();
@@ -493,8 +496,8 @@ TEST_F(PipelineTest, VideoAudioTextStream) {
InitializeAudioRenderer(audio_stream(), false);
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_TRUE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
AddTextStream();
message_loop_.RunUntilIdle();
@@ -620,8 +623,8 @@ TEST_F(PipelineTest, DisableAudioRenderer) {
InitializeVideoRenderer(video_stream());
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_TRUE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
EXPECT_CALL(*demuxer_, OnAudioRendererDisabled());
pipeline_->OnAudioDisabled();
@@ -645,8 +648,8 @@ TEST_F(PipelineTest, DisableAudioRendererDuringInit) {
EXPECT_CALL(*demuxer_, OnAudioRendererDisabled());
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_FALSE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
// Verify that ended event is fired when video ends.
EXPECT_CALL(callbacks_, OnEnded());
@@ -828,8 +831,8 @@ TEST_F(PipelineTest, StartTimeIsZero) {
InitializeVideoRenderer(video_stream());
InitializePipeline(PIPELINE_OK);
- EXPECT_FALSE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_FALSE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
EXPECT_EQ(base::TimeDelta(), pipeline_->GetMediaTime());
}
@@ -849,8 +852,8 @@ TEST_F(PipelineTest, StartTimeIsNonZero) {
InitializeVideoRenderer(video_stream());
InitializePipeline(PIPELINE_OK);
- EXPECT_FALSE(metadata_.has_audio);
- EXPECT_TRUE(metadata_.has_video);
+ EXPECT_FALSE(pipeline_->HasAudio());
+ EXPECT_TRUE(pipeline_->HasVideo());
EXPECT_EQ(kStartTime, pipeline_->GetMediaTime());
}
@@ -902,7 +905,7 @@ TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
EXPECT_CALL(*audio_renderer_, Play(_))
.WillOnce(RunClosure<0>());
- EXPECT_CALL(callbacks_, OnPrerollCompleted());
+ EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
DoSeek(seek_time);
@@ -996,8 +999,7 @@ class PipelineTeardownTest : public PipelineTest {
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnPrerollCompleted,
+ base::Bind(&CallbackHelper::OnBufferingState,
base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnDurationChange,
base::Unretained(&callbacks_)));
@@ -1074,7 +1076,7 @@ class PipelineTeardownTest : public PipelineTest {
EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
- EXPECT_CALL(callbacks_, OnMetadata(_));
+ EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kHaveMetadata));
// If we get here it's a successful initialization.
EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _))
@@ -1092,7 +1094,7 @@ class PipelineTeardownTest : public PipelineTest {
.WillOnce(RunClosure<0>());
if (status == PIPELINE_OK)
- EXPECT_CALL(callbacks_, OnPrerollCompleted());
+ EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
return status;
}
diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc
index 569cebc..05ba993 100644
--- a/media/filters/pipeline_integration_test.cc
+++ b/media/filters/pipeline_integration_test.cc
@@ -17,7 +17,6 @@
#include "media/cdm/json_web_key.h"
#include "media/filters/chunk_demuxer.h"
-using testing::_;
using testing::AnyNumber;
using testing::AtMost;
@@ -394,16 +393,16 @@ class PipelineIntegrationTest
public PipelineIntegrationTestBase {
public:
void StartPipelineWithMediaSource(MockMediaSource* source) {
- EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1));
- EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
+ .Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
+ .Times(AtMost(1));
pipeline_->Start(
CreateFilterCollection(source->GetDemuxer(), NULL),
base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
QuitOnStatusCB(PIPELINE_OK),
- base::Bind(&PipelineIntegrationTest::OnMetadata,
- base::Unretained(this)),
- base::Bind(&PipelineIntegrationTest::OnPrerollCompleted,
+ base::Bind(&PipelineIntegrationTest::OnBufferingState,
base::Unretained(this)),
base::Closure());
@@ -418,17 +417,17 @@ class PipelineIntegrationTest
void StartPipelineWithEncryptedMedia(
MockMediaSource* source,
FakeEncryptedMedia* encrypted_media) {
- EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1));
- EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
+ .Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
+ .Times(AtMost(1));
pipeline_->Start(
CreateFilterCollection(source->GetDemuxer(),
encrypted_media->decryptor()),
base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
QuitOnStatusCB(PIPELINE_OK),
- base::Bind(&PipelineIntegrationTest::OnMetadata,
- base::Unretained(this)),
- base::Bind(&PipelineIntegrationTest::OnPrerollCompleted,
+ base::Bind(&PipelineIntegrationTest::OnBufferingState,
base::Unretained(this)),
base::Closure());
diff --git a/media/filters/pipeline_integration_test_base.cc b/media/filters/pipeline_integration_test_base.cc
index a11ce50..8dce18c 100644
--- a/media/filters/pipeline_integration_test_base.cc
+++ b/media/filters/pipeline_integration_test_base.cc
@@ -17,7 +17,6 @@
#include "media/filters/opus_audio_decoder.h"
#include "media/filters/vpx_video_decoder.h"
-using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtMost;
@@ -103,16 +102,16 @@ void PipelineIntegrationTestBase::OnError(PipelineStatus status) {
bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path,
PipelineStatus expected_status) {
- EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1));
- EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
+ .Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
+ .Times(AtMost(1));
pipeline_->Start(
CreateFilterCollection(file_path, NULL),
base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)),
QuitOnStatusCB(expected_status),
- base::Bind(&PipelineIntegrationTestBase::OnMetadata,
- base::Unretained(this)),
- base::Bind(&PipelineIntegrationTestBase::OnPrerollCompleted,
+ base::Bind(&PipelineIntegrationTestBase::OnBufferingState,
base::Unretained(this)),
base::Closure());
message_loop_.Run();
@@ -136,17 +135,17 @@ bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path) {
bool PipelineIntegrationTestBase::Start(const base::FilePath& file_path,
Decryptor* decryptor) {
- EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1));
- EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata))
+ .Times(AtMost(1));
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
+ .Times(AtMost(1));
pipeline_->Start(
CreateFilterCollection(file_path, decryptor),
base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnStatusCallback,
base::Unretained(this)),
- base::Bind(&PipelineIntegrationTestBase::OnMetadata,
- base::Unretained(this)),
- base::Bind(&PipelineIntegrationTestBase::OnPrerollCompleted,
+ base::Bind(&PipelineIntegrationTestBase::OnBufferingState,
base::Unretained(this)),
base::Closure());
message_loop_.Run();
@@ -164,7 +163,7 @@ void PipelineIntegrationTestBase::Pause() {
bool PipelineIntegrationTestBase::Seek(base::TimeDelta seek_time) {
ended_ = false;
- EXPECT_CALL(*this, OnPrerollCompleted());
+ EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted));
pipeline_->Seek(seek_time, QuitOnStatusCB(PIPELINE_OK));
message_loop_.Run();
return (pipeline_status_ == PIPELINE_OK);
diff --git a/media/filters/pipeline_integration_test_base.h b/media/filters/pipeline_integration_test_base.h
index 39d2e2c..d162d0b 100644
--- a/media/filters/pipeline_integration_test_base.h
+++ b/media/filters/pipeline_integration_test_base.h
@@ -131,8 +131,7 @@ class PipelineIntegrationTestBase {
void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame);
MOCK_METHOD1(OnSetOpaque, void(bool));
- MOCK_METHOD1(OnMetadata, void(PipelineMetadata));
- MOCK_METHOD0(OnPrerollCompleted, void());
+ MOCK_METHOD1(OnBufferingState, void(Pipeline::BufferingState));
};
} // namespace media
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index 26834ea..32e5019 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -93,11 +93,7 @@ void Paint(base::MessageLoop* message_loop, const PaintCB& paint_cb,
paint_cb.Run(video_frame.get());
}
-static void DoNothing() {}
-
-static void OnStatus(media::PipelineStatus status) {}
-
-static void OnMetadata(media::PipelineMetadata metadata) {}
+static void OnBufferingState(media::Pipeline::BufferingState buffering_state) {}
static void NeedKey(const std::string& type,
const std::vector<uint8>& init_data) {
@@ -148,10 +144,9 @@ void InitPipeline(
media::PipelineStatus status;
pipeline->Start(
- collection.Pass(), base::Bind(&DoNothing), base::Bind(&OnStatus),
+ collection.Pass(), base::Closure(), media::PipelineStatusCB(),
base::Bind(&SaveStatusAndSignal, &event, &status),
- base::Bind(&OnMetadata), base::Bind(&DoNothing),
- base::Bind(&DoNothing));
+ base::Bind(&OnBufferingState), base::Closure());
// Wait until the pipeline is fully initialized.
event.Wait();
@@ -167,7 +162,8 @@ void TerminateHandler(int signal) {
void PeriodicalUpdate(
media::Pipeline* pipeline,
- base::MessageLoop* message_loop) {
+ base::MessageLoop* message_loop,
+ bool audio_only) {
if (!g_running) {
// interrupt signal was received during last time period.
// Quit message_loop only when pipeline is fully stopped.
@@ -195,7 +191,7 @@ void PeriodicalUpdate(
&border_width,
&depth);
base::TimeDelta time = pipeline->GetMediaDuration();
- pipeline->Seek(time*e.xbutton.x/width, base::Bind(&OnStatus));
+ pipeline->Seek(time*e.xbutton.x/width, media::PipelineStatusCB());
}
break;
case KeyPress:
@@ -223,7 +219,8 @@ void PeriodicalUpdate(
FROM_HERE,
base::Bind(&PeriodicalUpdate,
base::Unretained(pipeline),
- message_loop),
+ message_loop,
+ audio_only),
base::TimeDelta::FromMilliseconds(10));
}
@@ -294,7 +291,8 @@ int main(int argc, char** argv) {
g_running = true;
message_loop.PostTask(FROM_HERE, base::Bind(
- &PeriodicalUpdate, base::Unretained(&pipeline), &message_loop));
+ &PeriodicalUpdate, base::Unretained(&pipeline), &message_loop,
+ !pipeline.HasVideo()));
message_loop.Run();
// Cleanup tasks.