diff --git a/cobalt/media/base/pipeline.h b/cobalt/media/base/pipeline.h index a6dab31941d7..265743ac2c27 100644 --- a/cobalt/media/base/pipeline.h +++ b/cobalt/media/base/pipeline.h @@ -83,7 +83,6 @@ class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe { enum BufferingState { kHaveMetadata, kPrerollCompleted, - kBufferedRangeChanged, }; typedef base::Callback BufferingStateCB; diff --git a/cobalt/media/base/sbplayer_pipeline.cc b/cobalt/media/base/sbplayer_pipeline.cc index a26f5f575e86..994f7b96c063 100644 --- a/cobalt/media/base/sbplayer_pipeline.cc +++ b/cobalt/media/base/sbplayer_pipeline.cc @@ -682,12 +682,9 @@ void SbPlayerPipeline::SetDurationTask(TimeDelta duration) { void SbPlayerPipeline::OnBufferedTimeRangesChanged( const ::media::Ranges& ranges) { - { - base::AutoLock auto_lock(lock_); - did_loading_progress_ = true; - buffered_time_ranges_ = ranges; - } - buffering_state_cb_.Run(kBufferedRangeChanged); + base::AutoLock auto_lock(lock_); + did_loading_progress_ = true; + buffered_time_ranges_ = ranges; } void SbPlayerPipeline::SetDuration(TimeDelta duration) { diff --git a/cobalt/media/media_module.cc b/cobalt/media/media_module.cc index 1bbf79f3216d..024c660203a0 100644 --- a/cobalt/media/media_module.cc +++ b/cobalt/media/media_module.cc @@ -225,12 +225,8 @@ bool MediaModule::SetConfiguration(const std::string& name, int32 value) { << audio_write_duration_remote_; return true; #endif // SB_API_VERSION >= 15 - } else if (name == "DemuxerUnderflowThreshold" && value >= 0) { - demuxer_underflow_threshold_ = base::TimeDelta::FromMicroseconds(value); - LOG(INFO) << "Set DemuxerUnderflowThreshold to " - << demuxer_underflow_threshold_; - return true; } + return false; } @@ -250,7 +246,7 @@ std::unique_ptr MediaModule::CreateWebMediaPlayer( #if SB_API_VERSION >= 15 audio_write_duration_local_, audio_write_duration_remote_, #endif // SB_API_VERSION >= 15 - demuxer_underflow_threshold_, &media_log_)); + &media_log_)); } void MediaModule::Suspend() { diff --git a/cobalt/media/media_module.h b/cobalt/media/media_module.h index 10757ec2e311..cc5db7122807 100644 --- a/cobalt/media/media_module.h +++ b/cobalt/media/media_module.h @@ -137,11 +137,6 @@ class MediaModule : public WebMediaPlayerFactory, SbTime audio_write_duration_remote_ = kSbPlayerWriteDurationRemote; #endif // SB_API_VERSION >= 15 - // Set default demuxer underflow threshold to 50ms. - constexpr static int64_t kDefaultDemuxerUnderflowThreshold = 50 * 1000; - base::TimeDelta demuxer_underflow_threshold_ = - base::TimeDelta::FromMicroseconds(kDefaultDemuxerUnderflowThreshold); - DecoderBufferAllocator decoder_buffer_allocator_; }; diff --git a/cobalt/media/player/web_media_player_impl.cc b/cobalt/media/player/web_media_player_impl.cc index 34e65e0c26a2..e773474d419b 100644 --- a/cobalt/media/player/web_media_player_impl.cc +++ b/cobalt/media/player/web_media_player_impl.cc @@ -123,7 +123,6 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( #if SB_API_VERSION >= 15 SbTime audio_write_duration_local, SbTime audio_write_duration_remote, #endif // SB_API_VERSION >= 15 - base::TimeDelta demuxer_underflow_threshold, ::media::MediaLog* const media_log) : pipeline_thread_("media_pipeline"), network_state_(WebMediaPlayer::kNetworkStateEmpty), @@ -134,7 +133,6 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( allow_resume_after_suspend_(allow_resume_after_suspend), allow_batched_sample_write_(allow_batched_sample_write), force_punch_out_by_default_(force_punch_out_by_default), - demuxer_underflow_threshold_(demuxer_underflow_threshold), proxy_(new WebMediaPlayerProxy(main_loop_->task_runner(), this)), media_log_(media_log), is_local_source_(false), @@ -245,8 +243,6 @@ void WebMediaPlayerImpl::LoadUrl(const GURL& url) { is_local_source_ = !url.SchemeIs("http") && !url.SchemeIs("https"); - state_.is_url_based = true; - state_.is_demuxer_underflow = false; StartPipeline(url); media_metrics_provider_.Initialize(false); } @@ -328,7 +324,7 @@ void WebMediaPlayerImpl::Play() { DCHECK_EQ(main_loop_, base::MessageLoop::current()); state_.paused = false; - UpdatePlayState(); + pipeline_->SetPlaybackRate(state_.playback_rate); media_log_->AddEvent<::media::MediaLogEvent::kPlay>(); media_metrics_provider_.SetHasPlayed(); @@ -338,7 +334,7 @@ void WebMediaPlayerImpl::Pause() { DCHECK_EQ(main_loop_, base::MessageLoop::current()); state_.paused = true; - UpdatePlayState(); + pipeline_->SetPlaybackRate(0.0f); state_.paused_time = pipeline_->GetMediaTime(); media_log_->AddEvent<::media::MediaLogEvent::kPause>(); @@ -374,9 +370,6 @@ void WebMediaPlayerImpl::Seek(float seconds) { if (state_.paused) state_.paused_time = seek_time; state_.seeking = true; - state_.is_prerolled = false; - state_.is_demuxer_underflow = !state_.is_url_based; - demuxer_underflow_timer_.Stop(); if (chunk_demuxer_) { chunk_demuxer_->StartWaitingForSeek(seek_time); @@ -403,7 +396,9 @@ void WebMediaPlayerImpl::SetRate(float rate) { } state_.playback_rate = rate; - UpdatePlayState(); + if (!state_.paused) { + pipeline_->SetPlaybackRate(rate); + } } void WebMediaPlayerImpl::SetVolume(float volume) { @@ -454,7 +449,8 @@ std::vector WebMediaPlayerImpl::GetAudioConnectors() const { bool WebMediaPlayerImpl::IsPaused() const { DCHECK_EQ(main_loop_, base::MessageLoop::current()); - return state_.paused || state_.playback_rate == 0.0f; + + return pipeline_->GetPlaybackRate() == 0.0f; } bool WebMediaPlayerImpl::IsSeeking() const { @@ -774,7 +770,6 @@ void WebMediaPlayerImpl::OnPipelineError(::media::PipelineStatus error, void WebMediaPlayerImpl::OnPipelineBufferingState( Pipeline::BufferingState buffering_state) { - DCHECK_EQ(main_loop_, base::MessageLoop::current()); DVLOG(1) << "OnPipelineBufferingState(" << buffering_state << ")"; // If |is_resuming_from_background_mode_| is true, we are exiting background @@ -789,20 +784,9 @@ void WebMediaPlayerImpl::OnPipelineBufferingState( SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata); break; case Pipeline::kPrerollCompleted: - // Start underflow checks. - state_.is_prerolled = true; - CheckDemuxerUnderflow(); - SetReadyState(state_.is_demuxer_underflow - ? WebMediaPlayer::kReadyStateHaveCurrentData - : WebMediaPlayer::kReadyStateHaveEnoughData); - // TODO: rename SetHaveEnough(). + SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); media_metrics_provider_.SetHaveEnough(); break; - case Pipeline::kBufferedRangeChanged: - if (state_.is_prerolled && state_.is_demuxer_underflow) { - CheckDemuxerUnderflow(); - } - break; } } @@ -814,80 +798,6 @@ void WebMediaPlayerImpl::OnDemuxerOpened() { GetClient()->SourceOpened(chunk_demuxer_.get()); } -void WebMediaPlayerImpl::CheckDemuxerUnderflow() { - DCHECK_EQ(main_loop_, base::MessageLoop::current()); - DCHECK(pipeline_); - DCHECK(!state_.is_media_source || chunk_demuxer_); - DCHECK(!state_.is_progressive || progressive_demuxer_); - - if (state_.is_url_based) { - return; - } - - if (demuxer_underflow_threshold_.is_zero()) { - // When |demuxer_underflow_threshold_| is set to 0, we don't check demuxer - // underflow. - SetDemuxerUnderflow(false); - return; - } - - if ((state_.is_media_source && chunk_demuxer_->GetIsEndOfStreamReceived()) || - (state_.is_progressive && - progressive_demuxer_->GetIsEndOfStreamReceived())) { - // End of stream has been received, so we don't check underflow. - SetDemuxerUnderflow(false); - return; - } - - base::TimeDelta media_time = pipeline_->GetMediaTime(); - ::media::Ranges buffered_ranges = - pipeline_->GetBufferedTimeRanges(); - base::TimeDelta buffered_duration; - for (size_t i = 0; i < buffered_ranges.size(); i++) { - if (buffered_ranges.end(i) < media_time) { - continue; - } - if (buffered_ranges.start(i) > media_time) { - break; - } - buffered_duration = buffered_ranges.end(i) - media_time; - } - - // Adjust buffered duration for playback rate. - if (state_.playback_rate > 0) { - buffered_duration /= state_.playback_rate; - } - if (buffered_duration > demuxer_underflow_threshold_) { - SetDemuxerUnderflow(false); - // Note that the callback may be delayed if the main module thread is busy. - demuxer_underflow_timer_.Start( - FROM_HERE, buffered_duration - demuxer_underflow_threshold_, this, - &WebMediaPlayerImpl::CheckDemuxerUnderflow); - return; - } - - // The buffered data is not enough to continue the playing. - SetDemuxerUnderflow(true); -} - -void WebMediaPlayerImpl::SetDemuxerUnderflow(bool is_underflow) { - if (state_.is_demuxer_underflow == is_underflow) { - return; - } - - state_.is_demuxer_underflow = is_underflow; - if (state_.is_demuxer_underflow && - ready_state_ > WebMediaPlayer::kReadyStateHaveCurrentData) { - SetReadyState(WebMediaPlayer::kReadyStateHaveCurrentData); - } - if (!state_.is_demuxer_underflow && - ready_state_ == WebMediaPlayer::kReadyStateHaveCurrentData) { - SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); - } - - UpdatePlayState(); -} - void WebMediaPlayerImpl::OnDownloadingStatusChanged(bool is_downloading) { if (!is_downloading && network_state_ == WebMediaPlayer::kNetworkStateLoading) SetNetworkState(WebMediaPlayer::kNetworkStateIdle); @@ -974,17 +884,6 @@ void WebMediaPlayerImpl::SetReadyState(WebMediaPlayer::ReadyState state) { GetClient()->ReadyStateChanged(); } -void WebMediaPlayerImpl::UpdatePlayState() { - bool should_be_paused = - state_.paused || !state_.is_prerolled || state_.is_demuxer_underflow; - float playback_rate = pipeline_->GetPlaybackRate(); - if (!should_be_paused && playback_rate != state_.playback_rate) { - pipeline_->SetPlaybackRate(state_.playback_rate); - } else if (should_be_paused && playback_rate > 0.0f) { - pipeline_->SetPlaybackRate(0.0f); - } -} - void WebMediaPlayerImpl::Destroy() { TRACE_EVENT0("cobalt::media", "WebMediaPlayerImpl::Destroy"); @@ -1077,14 +976,6 @@ WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { void WebMediaPlayerImpl::OnDurationChanged() { if (ready_state_ == WebMediaPlayer::kReadyStateHaveNothing) return; - if (state_.is_prerolled && state_.is_demuxer_underflow) { - // We currently only call CheckDemuxerUnderflow() when demuxer is already - // underflow to reduce the frequency of CheckDemuxerUnderflow() calls. - // Technically, when OnDurationChanged() is triggered by - // MediaSource.remove(), the removed data may lead to underflow. But as it's - // barely used, we currently ignore it. - CheckDemuxerUnderflow(); - } GetClient()->DurationChanged(); } diff --git a/cobalt/media/player/web_media_player_impl.h b/cobalt/media/player/web_media_player_impl.h index 65670cd5ee29..adb7ed2a577b 100644 --- a/cobalt/media/player/web_media_player_impl.h +++ b/cobalt/media/player/web_media_player_impl.h @@ -58,7 +58,6 @@ #include "base/message_loop/message_loop.h" #include "base/threading/thread.h" #include "base/time/time.h" -#include "base/timer/timer.h" #include "cobalt/math/size.h" #include "cobalt/media/base/decode_target_provider.h" #include "cobalt/media/base/metrics_provider.h" @@ -117,7 +116,6 @@ class WebMediaPlayerImpl : public WebMediaPlayer, SbTime audio_write_duration_local, SbTime audio_write_duration_remote, #endif // SB_API_VERSION >= 15 - base::TimeDelta demuxer_underflow_threshold, ::media::MediaLog* const media_log); ~WebMediaPlayerImpl() override; @@ -205,9 +203,6 @@ class WebMediaPlayerImpl : public WebMediaPlayer, void OnPipelineBufferingState(Pipeline::BufferingState buffering_state); void OnDemuxerOpened(); - void SetDemuxerUnderflow(bool is_underflow); - void CheckDemuxerUnderflow(); - private: // Called when the data source is downloading or paused. void OnDownloadingStatusChanged(bool is_downloading); @@ -224,8 +219,6 @@ class WebMediaPlayerImpl : public WebMediaPlayer, void SetNetworkError(NetworkState state, const std::string& message); void SetReadyState(ReadyState state); - void UpdatePlayState(); - // Destroy resources held. void Destroy(); @@ -287,23 +280,20 @@ class WebMediaPlayerImpl : public WebMediaPlayer, // same time we pause and then return that value in currentTime(). // Otherwise our clock can creep forward a little bit while the asynchronous // SetPlaybackRate(0) is being executed. - bool paused = true; - bool seeking = false; - float playback_rate = 0.0f; + bool paused; + bool seeking; + float playback_rate; base::TimeDelta paused_time; // Seek gets pending if another seek is in progress. Only last pending seek // will have effect. - bool pending_seek = false; - double pending_seek_seconds = 0.0; + bool pending_seek; + float pending_seek_seconds; - bool starting = false; - bool is_prerolled = false; - bool is_demuxer_underflow = true; + bool starting; - bool is_progressive = false; - bool is_media_source = false; - bool is_url_based = false; + bool is_progressive; + bool is_media_source; } state_; WebMediaPlayerClient* const client_; @@ -311,7 +301,6 @@ class WebMediaPlayerImpl : public WebMediaPlayer, const bool allow_resume_after_suspend_; const bool allow_batched_sample_write_; const bool force_punch_out_by_default_; - const base::TimeDelta demuxer_underflow_threshold_; scoped_refptr decode_target_provider_; scoped_refptr proxy_; @@ -325,8 +314,6 @@ class WebMediaPlayerImpl : public WebMediaPlayer, std::unique_ptr<::media::Demuxer> progressive_demuxer_; std::unique_ptr<::media::ChunkDemuxer> chunk_demuxer_; - base::OneShotTimer demuxer_underflow_timer_; - // Suppresses calls to OnPipelineError() after destruction / shutdown has been // started; prevents us from spuriously logging errors that are transient or // unimportant. diff --git a/cobalt/media/progressive/demuxer_extension_wrapper.cc b/cobalt/media/progressive/demuxer_extension_wrapper.cc index fb953c26500f..03b8b8ab1e09 100644 --- a/cobalt/media/progressive/demuxer_extension_wrapper.cc +++ b/cobalt/media/progressive/demuxer_extension_wrapper.cc @@ -744,15 +744,13 @@ void DemuxerExtensionWrapper::Request(DemuxerStream::Type type) { return; } - bool eos_status = decoder_buffer->end_of_stream(); - if (type == DemuxerStream::AUDIO) { - audio_reached_eos_ = eos_status; - audio_stream_->EnqueueBuffer(std::move(decoder_buffer)); - } else { - video_reached_eos_ = eos_status; - video_stream_->EnqueueBuffer(std::move(decoder_buffer)); - } + auto& stream = + (type == DemuxerStream::AUDIO) ? *audio_stream_ : *video_stream_; + bool& eos_status = + (type == DemuxerStream::AUDIO) ? audio_reached_eos_ : video_reached_eos_; + eos_status = decoder_buffer->end_of_stream(); + stream.EnqueueBuffer(std::move(decoder_buffer)); if (!eos_status) { host_->OnBufferedTimeRangesChanged(GetBufferedRanges()); } diff --git a/cobalt/media/progressive/demuxer_extension_wrapper.h b/cobalt/media/progressive/demuxer_extension_wrapper.h index 4473a114d4ab..c3f869a34080 100644 --- a/cobalt/media/progressive/demuxer_extension_wrapper.h +++ b/cobalt/media/progressive/demuxer_extension_wrapper.h @@ -18,7 +18,6 @@ #ifndef COBALT_MEDIA_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ #define COBALT_MEDIA_PROGRESSIVE_DEMUXER_EXTENSION_WRAPPER_H_ -#include #include #include #include @@ -190,10 +189,6 @@ class DemuxerExtensionWrapper : public ::media::Demuxer { return absl::nullopt; } - bool GetIsEndOfStreamReceived() const override { - return audio_reached_eos_ || video_reached_eos_; - } - private: // Only a forward declaration here, since the specifics of this class are an // implementation detail. @@ -229,8 +224,8 @@ class DemuxerExtensionWrapper : public ::media::Demuxer { mutable base::Lock lock_for_stopped_; // Indicates whether Stop has been called. bool stopped_ = false; - std::atomic_bool video_reached_eos_ = {false}; - std::atomic_bool audio_reached_eos_ = {false}; + bool video_reached_eos_ = false; + bool audio_reached_eos_ = false; bool flushing_ = false; base::Optional video_stream_; diff --git a/cobalt/media/progressive/progressive_demuxer.h b/cobalt/media/progressive/progressive_demuxer.h index c418d5bcccb4..c79cf018e681 100644 --- a/cobalt/media/progressive/progressive_demuxer.h +++ b/cobalt/media/progressive/progressive_demuxer.h @@ -15,7 +15,6 @@ #ifndef COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ #define COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_ -#include #include #include #include @@ -166,10 +165,6 @@ class MEDIA_EXPORT ProgressiveDemuxer : public ::media::Demuxer { // Provide access to ProgressiveDemuxerStream. bool MessageLoopBelongsToCurrentThread() const; - bool GetIsEndOfStreamReceived() const override { - return audio_reached_eos_ || video_reached_eos_; - } - private: void ParseConfigDone(PipelineStatusCallback status_cb, PipelineStatus status); bool HasStopCalled(); @@ -200,8 +195,8 @@ class MEDIA_EXPORT ProgressiveDemuxer : public ::media::Demuxer { scoped_refptr parser_; scoped_refptr requested_au_; - std::atomic_bool audio_reached_eos_; - std::atomic_bool video_reached_eos_; + bool audio_reached_eos_; + bool video_reached_eos_; }; } // namespace media diff --git a/third_party/chromium/media/base/demuxer.h b/third_party/chromium/media/base/demuxer.h index 161aa12f57c6..27d36ba4addc 100644 --- a/third_party/chromium/media/base/demuxer.h +++ b/third_party/chromium/media/base/demuxer.h @@ -156,10 +156,6 @@ class MEDIA_EXPORT Demuxer : public MediaResource { virtual absl::optional GetContainerForMetrics() const = 0; -#if defined(STARBOARD) - virtual bool GetIsEndOfStreamReceived() const = 0; -#endif // defined(STARBOARD) - // The |track_ids| vector has either 1 track, or is empty, indicating that // all tracks should be disabled. |change_completed_cb| is fired after the // demuxer streams are disabled, however this callback should then notify diff --git a/third_party/chromium/media/filters/chunk_demuxer.cc b/third_party/chromium/media/filters/chunk_demuxer.cc index 6baab83b928d..e24189d7fb41 100644 --- a/third_party/chromium/media/filters/chunk_demuxer.cc +++ b/third_party/chromium/media/filters/chunk_demuxer.cc @@ -1123,11 +1123,6 @@ base::TimeDelta ChunkDemuxer::GetWriteHead(const std::string& id) const { return iter->second[0]->GetWriteHead(); } -bool ChunkDemuxer::GetIsEndOfStreamReceived() const { - base::AutoLock auto_lock(lock_); - return state_ >= ENDED; -} - void ChunkDemuxer::SetSourceBufferStreamMemoryLimit(const std::string& id, size_t limit) { base::AutoLock auto_lock(lock_); diff --git a/third_party/chromium/media/filters/chunk_demuxer.h b/third_party/chromium/media/filters/chunk_demuxer.h index 009d4d9149b2..76a01f414f41 100644 --- a/third_party/chromium/media/filters/chunk_demuxer.h +++ b/third_party/chromium/media/filters/chunk_demuxer.h @@ -394,7 +394,6 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { #if defined(STARBOARD) base::TimeDelta GetWriteHead(const std::string& id) const; - bool GetIsEndOfStreamReceived() const override; void SetSourceBufferStreamMemoryLimit(const std::string& guid, size_t limit); size_t GetSourceBufferStreamMemoryLimit(const std::string& guid);