diff options
author | erikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-26 00:05:16 +0000 |
---|---|---|
committer | erikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-26 00:05:16 +0000 |
commit | 0b3bf8a498bf255197f21ddba0f645a2a3a9e3bc (patch) | |
tree | b24da4514899327a1a9870464cb7076389edc39a | |
parent | 923c7ad68f067f57afcb4edec224ac346f792ad3 (diff) | |
download | chromium_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.cc | 66 | ||||
-rw-r--r-- | content/renderer/media/webmediaplayer_impl.h | 8 | ||||
-rw-r--r-- | media/base/pipeline.cc | 99 | ||||
-rw-r--r-- | media/base/pipeline.h | 73 | ||||
-rw-r--r-- | media/base/pipeline_unittest.cc | 68 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test.cc | 21 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test_base.cc | 23 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test_base.h | 3 | ||||
-rw-r--r-- | media/tools/player_x11/player_x11.cc | 22 |
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. |