Skip to content

Commit

Permalink
Revert "Cherry pick PR #2075: Pause player when demuxer is underflow" (
Browse files Browse the repository at this point in the history
…#2471)

Reverts #2355

b/307362589
  • Loading branch information
jasonzhangxx authored Feb 23, 2024
1 parent 9c94ba5 commit 6948e53
Show file tree
Hide file tree
Showing 12 changed files with 31 additions and 188 deletions.
1 change: 0 additions & 1 deletion cobalt/media/base/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe<Pipeline> {
enum BufferingState {
kHaveMetadata,
kPrerollCompleted,
kBufferedRangeChanged,
};

typedef base::Callback<void(BufferingState)> BufferingStateCB;
Expand Down
9 changes: 3 additions & 6 deletions cobalt/media/base/sbplayer_pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -682,12 +682,9 @@ void SbPlayerPipeline::SetDurationTask(TimeDelta duration) {

void SbPlayerPipeline::OnBufferedTimeRangesChanged(
const ::media::Ranges<base::TimeDelta>& 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) {
Expand Down
8 changes: 2 additions & 6 deletions cobalt/media/media_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -250,7 +246,7 @@ std::unique_ptr<WebMediaPlayer> 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() {
Expand Down
5 changes: 0 additions & 5 deletions cobalt/media/media_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
};

Expand Down
125 changes: 8 additions & 117 deletions cobalt/media/player/web_media_player_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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),
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
Expand All @@ -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>();
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -454,7 +449,8 @@ std::vector<std::string> 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 {
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
}

Expand All @@ -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<base::TimeDelta> 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);
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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();
}

Expand Down
29 changes: 8 additions & 21 deletions cobalt/media/player/web_media_player_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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();

Expand Down Expand Up @@ -287,31 +280,27 @@ 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_;
WebMediaPlayerDelegate* const delegate_;
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<DecodeTargetProvider> decode_target_provider_;

scoped_refptr<WebMediaPlayerProxy> proxy_;
Expand All @@ -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.
Expand Down
14 changes: 6 additions & 8 deletions cobalt/media/progressive/demuxer_extension_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
Loading

0 comments on commit 6948e53

Please sign in to comment.