virtual bool SetWallClock(const std::string& wallclock_url) = 0;
virtual double GetStartDate() = 0;
virtual void DestroyPlayerSync(base::OnceClosure cb) = 0;
+ virtual void Activate() = 0;
+ virtual void Deactivate() = 0;
+ virtual void Show() = 0;
+ virtual void Hide() = 0;
#endif
};
double GetStartDate();
void DestroyPlayerSync(base::OnceClosure cb);
void OnUpdatePlayerID(int player_id);
+ void Activate();
+ void Deactivate();
+ void Show();
+ void Hide();
#endif
// |enabled_track_ids| contains track ids of enabled audio tracks.
SetState(kSuspending);
#if defined(TIZEN_MULTIMEDIA)
+ if (!shared_state_.renderer) {
+ LOG(WARNING) << __func__ << " renderer is not created yet, not do suspend. ";
+ return;
+ }
+
if (request_suspend_task_handle_.IsValid()) {
LOG(INFO) << " Cancel posted request suspend task if pended.";
request_suspend_task_handle_.CancelTask();
}
DCHECK(!pending_callbacks_.get());
- if (!default_renderer) {
- OnPipelineError({PIPELINE_ERROR_INITIALIZATION_FAILED,
- "Media Renderer creation failed during resume!"});
- return;
- }
-
SetState(kResuming);
{
// signal
std::move(player_destroy_cb_).Run();
}
+
+void PipelineImpl::RendererWrapper::Activate() {
+ DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ if (shared_state_.renderer)
+ shared_state_.renderer->Activate();
+}
+
+void PipelineImpl::RendererWrapper::Deactivate() {
+ DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ if (shared_state_.renderer)
+ shared_state_.renderer->Deactivate();
+}
+
+void PipelineImpl::RendererWrapper::Show() {
+ DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ if (shared_state_.renderer)
+ shared_state_.renderer->Show();
+}
+
+void PipelineImpl::RendererWrapper::Hide() {
+ DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ if (shared_state_.renderer)
+ shared_state_.renderer->Hide();
+}
#endif
void PipelineImpl::RendererWrapper::CreateRendererInternal(
DCHECK(thread_checker_.CalledOnValidThread());
return renderer_wrapper_->SetWallClock(wallclock_url);
}
+
+void PipelineImpl::Activate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ media_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RendererWrapper::Activate,
+ base::Unretained(renderer_wrapper_.get())));
+}
+
+void PipelineImpl::Deactivate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ media_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RendererWrapper::Deactivate,
+ base::Unretained(renderer_wrapper_.get())));
+}
+
+void PipelineImpl::Show() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ media_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RendererWrapper::Show,
+ base::Unretained(renderer_wrapper_.get())));
+}
+
+void PipelineImpl::Hide() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+ media_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RendererWrapper::Hide,
+ base::Unretained(renderer_wrapper_.get())));
+}
#endif
#if defined(TIZEN_MULTIMEDIA)
DCHECK(IsRunning());
DCHECK(!suspend_cb_);
suspend_cb_ = std::move(suspend_cb);
-
media_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&RendererWrapper::Suspend,
base::Unretained(renderer_wrapper_.get())));
void OnExternalVideoFrameRequest() override;
+#if BUILDFLAG(IS_TIZEN_TV)
+ void Activate() override;
+ void Deactivate() override;
+ void Show() override;
+ void Hide() override;
+#endif
+
private:
friend class MediaLog;
class RendererWrapper;
SetWallClockCB cb) {}
virtual void GetStartDate(StartDateCB cb) {}
virtual void DestroyPlayerSync(base::OnceClosure cb) {}
+ virtual void Activate() {}
+ virtual void Deactivate() {}
+ virtual void Show() {}
+ virtual void Hide() {}
#endif
// Starts rendering from |time|.
}
State old_state = state_;
- state_ = expected_state;
+
+#if BUILDFLAG(IS_TIZEN_TV)
+ if ((old_state == State::RESUMING) && (expected_state == State::SUSPENDED))
+ state_ = State::RESUMING;
+ else
+#endif
+ state_ = expected_state;
// Resolve ambiguity of the current state if we may have suspended in startup.
if (state_ == State::PLAYING_OR_SUSPENDED) {
// are wasted, and seeks after can be merged into the resume operation.
if (pending_suspend_ && state_ == State::PLAYING) {
pending_suspend_ = false;
+
+// During suspend sequence, pipeline_impl suspended status post task will be
+// done after resume excuted. suspend_cb_ always return OK except pipeline
+// error, so here can set suspended directly once suspend called.
+#if BUILDFLAG(IS_TIZEN_TV)
+ state_ = State::SUSPENDED;
+#else
state_ = State::SUSPENDING;
- LOG(INFO) << "Dispatch Suspend: " << this;
+#endif
+
+ LOG(INFO) << __func__ << " this : " << (void*)this << " state_: "
+ << static_cast<typename std::underlying_type<State>::type>(state_);
pipeline_->Suspend(base::BindOnce(&PipelineController::OnPipelineStatus,
weak_factory_.GetWeakPtr(),
State::SUSPENDED));
state_ = State::RESUMING;
before_resume_cb_.Run();
- LOG(INFO) << "Dispatch Resume: " << this;
+ LOG(INFO) << "Dispatch Resume: " << this << " state_: "
+ << static_cast<typename std::underlying_type<State>::type>(state_);
pipeline_->Resume(
seek_time_, base::BindOnce(&PipelineController::OnPipelineStatus,
weak_factory_.GetWeakPtr(), State::PLAYING));
std::move(cb).Run();
}
}
+
+void PipelineController::Activate() {
+ if (pipeline_) {
+ pipeline_->Activate();
+ }
+ else {
+ LOG(ERROR) << "pipeline_ is null";
+ }
+}
+
+void PipelineController::Deactivate() {
+ if (pipeline_) {
+ pipeline_->Deactivate();
+ }
+ else {
+ LOG(ERROR) << "pipeline_ is null";
+ }
+}
+
+void PipelineController::Show() {
+ if (pipeline_) {
+ pipeline_->Show();
+ }
+ else {
+ LOG(ERROR) << "pipeline_ is null";
+ }
+}
+
+void PipelineController::Hide() {
+ if (pipeline_) {
+ pipeline_->Hide();
+ }
+ else {
+ LOG(ERROR) << "pipeline_ is null";
+ }
+}
#endif
} // namespace media
bool SetWallClock(const std::string& wallclock_url);
double GetStartDate() const;
void DestroyPlayerSync(base::OnceClosure cb);
+ void Activate();
+ void Deactivate();
+ void Show();
+ void Hide();
#endif
private:
// Attempts to make progress from the current state to the target state.
<< " player_id " << player_id;
client_->OnUpdatePlayerID(player_id);
}
+
+void MojoRenderer::Activate() {
+ DVLOG(2) << "(" << static_cast<void*>(this) << ") " << __func__;
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ if (remote_renderer_.is_bound())
+ remote_renderer_->Activate();
+}
+
+void MojoRenderer::Deactivate() {
+ DVLOG(2) << "(" << static_cast<void*>(this) << ") " << __func__;
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ if (remote_renderer_.is_bound())
+ remote_renderer_->Deactivate();
+}
+
+void MojoRenderer::Show() {
+ DVLOG(2) << "(" << static_cast<void*>(this) << ") " << __func__;
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ if (remote_renderer_.is_bound())
+ remote_renderer_->Show();
+}
+
+void MojoRenderer::Hide() {
+ DVLOG(2) << "(" << static_cast<void*>(this) << ") " << __func__;
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ if (remote_renderer_.is_bound())
+ remote_renderer_->Hide();
+}
#endif
void MojoRenderer::OnWaiting(WaitingReason reason) {
void GetStartDate(StartDateCB cb) override;
void DestroyPlayerSync(base::OnceClosure cb) override;
void OnUpdatePlayerID(int player_id) override;
+ void Activate() override;
+ void Deactivate() override;
+ void Show() override;
+ void Hide() override;
#endif
private:
std::move(cb).Run();
}
}
+
+void MojoRendererWrapper::Activate() {
+ if (mojo_renderer_) {
+ mojo_renderer_->Activate();
+ } else {
+ LOG(ERROR) << "mojo_renderer_ is null";
+ }
+}
+
+void MojoRendererWrapper::Deactivate() {
+ if (mojo_renderer_) {
+ mojo_renderer_->Deactivate();
+ } else {
+ LOG(ERROR) << "mojo_renderer_ is null";
+ }
+}
+
+void MojoRendererWrapper::Show() {
+ if (mojo_renderer_) {
+ mojo_renderer_->Show();
+ } else {
+ LOG(ERROR) << "mojo_renderer_ is null";
+ }
+}
+
+void MojoRendererWrapper::Hide() {
+ if (mojo_renderer_) {
+ mojo_renderer_->Hide();
+ } else {
+ LOG(ERROR) << "mojo_renderer_ is null";
+ }
+}
#endif
} // namespace media
SetWallClockCB cb) override;
void GetStartDate(StartDateCB cb) override;
void DestroyPlayerSync(base::OnceClosure cb) override;
+
+ void Activate() override;
+ void Deactivate() override;
+ void Show() override;
+ void Hide() override;
#endif
base::TimeDelta GetMediaTime() override;
[EnableIf=is_tizen_tv]
DestroyPlayerSync() => ();
+
+ [EnableIf=is_tizen_tv]
+ Activate();
+
+ [EnableIf=is_tizen_tv]
+ Deactivate();
+
+ [EnableIf=is_tizen_tv]
+ Show();
+
+ [EnableIf=is_tizen_tv]
+ Hide();
};
// A Mojo equivalent of media::RendererClient. See media/mojo/README.md
DVLOG(2) << __func__ << "(" << player_id << ")";
client_->OnUpdatePlayerID(player_id);
}
+
+void MojoRendererService::Activate() {
+ DVLOG(2) << __func__;
+
+ if (renderer_) {
+ renderer_->Activate();
+ } else {
+ LOG(ERROR) << "renderer_ is null";
+ }
+}
+
+void MojoRendererService::Deactivate() {
+ DVLOG(2) << __func__;
+
+ if (renderer_){
+ renderer_->Deactivate();
+ } else {
+ LOG(ERROR) << "renderer_ is null";
+ }
+}
+
+void MojoRendererService::Show() {
+ DVLOG(2) << __func__;
+
+ if (renderer_) {
+ renderer_->Show();
+ } else {
+ LOG(ERROR) << "renderer_ is null";
+ }
+}
+
+void MojoRendererService::Hide() {
+ DVLOG(2) << __func__;
+
+ if (renderer_){
+ renderer_->Hide();
+ } else {
+ LOG(ERROR) << "renderer_ is null";
+ }
+}
#endif
void MojoRendererService::OnBufferingStateChange(
void GetStartDate(GetStartDateCallback cb) final;
void DestroyPlayerSync(base::OnceClosure destroy_cb) final;
void OnUpdatePlayerID(int player_id) final;
+
+ void Activate() final;
+ void Deactivate() final;
+ void Show() final;
+ void Hide() final;
#endif
private:
virtual double GetStartDate() const {
return std::numeric_limits<double>::quiet_NaN();
}
+
+ virtual void Activate() {};
+ virtual void Deactivate() {};
+ virtual void Show() {};
+ virtual void Hide() {};
+ virtual bool IsSuspendByInternal() {return false;};
#endif
};
DVLOG(3) << "ScheduleEvent(" << (void*)this << ")"
<< " - scheduling '" << event->type() << "'";
#endif
+ if (event_type_names::kTimeupdate != event->type())
+ LOG(INFO) << "ScheduleEvent(" << (void*)this << ")"
+ << " - scheduling '" << event->type() << "'";
async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
autoplay_policy_->RequestPlay();
#if BUILDFLAG(IS_TIZEN_TV)
is_deactivate_ = false;
+ if (GetWebMediaPlayer() && GetWebMediaPlayer()->IsSuspendByInternal()) {
+ LOG(INFO) << "play(" << *this << ") Resume play due to requestsuspend!";
+ GetWebMediaPlayer()->Activate();
+ GetWebMediaPlayer()->Resume();
+ }
#endif
if (exception_code == DOMExceptionCode::kNotAllowedError) {
LOG(INFO) << "Already suspend by WRT, return directly.";
return;
}
+ suspend_media_by_wrt_ = true;
#endif
// Suspend if a browser tab is switched.
if (GetWebMediaPlayer())
LOG(INFO) << "Already resume by WRT, return directly.";
return;
}
+ resume_media_by_wrt_ = false;
#endif
// Do not resume if suspended by player except the resource conflict case.
void HTMLMediaElement::WRTMediaSuspend(bool suspend) {
LOG(INFO) << "WRTMediaSuspend:" << suspend << ",this:" << (void*)this;
if (suspend) {
+ resume_media_by_wrt_ = false;
+ if (suspend_media_by_wrt_) {
+ LOG(INFO) << "Already suspend, return directly.";
+ return;
+ }
suspend_media_by_wrt_ = true;
#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
pause();
}
} else {
+ suspend_media_by_wrt_ = false;
+ if (resume_media_by_wrt_) {
+ LOG(INFO) << "Already resume, return directly.";
+ return;
+ }
resume_media_by_wrt_ = true;
#if defined(SAMSUNG_ELEMENTARY_MEDIA_STREAM_SOURCE)
#include "media/base/demuxer.h"
#include "media/base/encryption_scheme.h"
#include "media/base/limits.h"
+#include "media/base/logging_override_if_enabled.h"
#include "media/base/media_content_type.h"
#include "media/base/media_log.h"
#include "media/base/media_player_logging_id.h"
&base::WaitableEvent::Signal, base::Unretained(&waiter)));
waiter.Wait();
}
+
+ is_paused_by_internal_ = false;
+ is_suspend_by_upper_ = false;
#endif
// The underlying Pipeline must be stopped before it is destroyed.
}
void WebMediaPlayerImpl::Play() {
- DVLOG(1) << __func__;
+ DVLOG(1) << __func__ << ", this : " << (void*)this;
DCHECK(main_task_runner_->BelongsToCurrentThread());
// User initiated play unlocks background video playback.
paused_ = false;
pipeline_controller_->SetPlaybackRate(playback_rate_);
background_pause_timer_.Stop();
-#if defined(TIZEN_MULTIMEDIA)
- was_suspended_by_player_ = false;
+#if BUILDFLAG(IS_TIZEN_TV)
+ is_paused_by_internal_ = false;
#endif
if (observer_)
return true;
return false;
}
+
+void WebMediaPlayerImpl::Activate() {
+ is_paused_by_internal_ = false;
+ if (pipeline_controller_)
+ pipeline_controller_->Activate();
+}
+
+void WebMediaPlayerImpl::Deactivate() {
+ if (pipeline_controller_)
+ pipeline_controller_->Deactivate();
+}
+
+void WebMediaPlayerImpl::Show() {
+ is_suspend_by_upper_ = false;
+ if (pipeline_controller_)
+ pipeline_controller_->Show();
+}
+
+void WebMediaPlayerImpl::Hide() {
+ if (pipeline_controller_)
+ pipeline_controller_->Hide();
+}
#endif
bool WebMediaPlayerImpl::CanPlayThrough() {
// It shouldn't be possible to underflow if we've not advanced past
// HAVE_CURRENT_DATA.
- DCHECK_GT(highest_ready_state_, WebMediaPlayer::kReadyStateHaveCurrentData);
- SetReadyState(WebMediaPlayer::kReadyStateHaveCurrentData);
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (is_paused_by_internal_) {
+ LOG(INFO) << "Suspended by internal, just report kReadyStateHaveMetadata.";
+ DCHECK_GT(highest_ready_state_, WebMediaPlayer::kReadyStateHaveMetadata);
+ SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata);
+ } else {
+#endif
+ DCHECK_GT(highest_ready_state_, WebMediaPlayer::kReadyStateHaveCurrentData);
+ SetReadyState(WebMediaPlayer::kReadyStateHaveCurrentData);
+#if BUILDFLAG(IS_TIZEN_TV)
+ }
+#endif
}
// If this is an NNR, then notify the smoothness helper about it. Note that
}
#if defined(TIZEN_MULTIMEDIA)
+// Only Tab switch or APP suspend called
void WebMediaPlayerImpl::Suspend() {
LOG(INFO) << __func__ << " this " << this;
SetSuspendState(true);
+#if BUILDFLAG(IS_TIZEN_TV)
+ is_suspend_by_upper_ = true;
+ Hide();
+#endif
}
void WebMediaPlayerImpl::Resume() {
LOG(INFO) << __func__ << " this " << this;
SetSuspendState(false);
+#if BUILDFLAG(IS_TIZEN_TV)
+ is_suspend_by_upper_ = false;
+ Show();
+#endif
}
void WebMediaPlayerImpl::OnSeekableTimeChange(base::TimeDelta min_time,
}
void WebMediaPlayerImpl::OnRequestSuspend(bool resource_conflicted) {
- if (pipeline_controller_->IsSuspended()) {
- LOG(INFO) << __func__ << " Already suspended.";
- return;
- }
+ LOG(INFO) << __func__ << " resource_conflicted : " << resource_conflicted;
#if BUILDFLAG(IS_TIZEN_TV)
if (suspend_by_multi_reload_) {
}
#endif
+ if (pipeline_controller_->IsSuspended()) {
+ LOG(INFO) << __func__ << " Already suspended."
+ << ", this : " << (void*)this;
+ return;
+ }
+
+#if BUILDFLAG(IS_TIZEN_TV)
+ is_paused_by_internal_ = true;
+#endif
+
// Check if suspended by the resource conflict or not.
// If resource is conflicted by other process, it can be resumed.
- was_suspended_by_player_ = !resource_conflicted;
+ // fixup! in resource_conflict scenario
+ // was_suspended_by_player_ = !resource_conflicted;
- client_->PausePlayback(WebMediaPlayerClient::PauseReason::kUnknown);
client_->SuspendPlayer();
SetSuspendState(true);
}
void WebMediaPlayerImpl::SetSuspendState(bool is_suspended) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- LOG(INFO) << __func__ << "(" << is_suspended << ")";
+ LOG(INFO) << __func__ << "(" << is_suspended << ") ; this : " << (void*)this;
// Do not change the state after an error has occurred.
// TODO(sandersd): Update PipelineController to remove the need for this.
- if (IsNetworkStateError(network_state_))
+ if (IsNetworkStateError(network_state_)) {
+ LOG(ERROR) << __func__
+ << " network_state_: " << static_cast<int>(network_state_)
+ << " ; this : " << (void*)this;
return;
+ }
if (is_suspended) {
// If we were not resumed for long enough to satisfy the preroll attempt,
// Combined suspend state.
result.is_suspended = must_suspend || idle_suspended ||
-#if defined(TIZEN_MULTIMEDIA)
- was_suspended_by_player_ ||
+#if BUILDFLAG(IS_TIZEN_TV)
+ is_paused_by_internal_ ||
+ is_suspend_by_upper_ ||
#endif
background_suspended || can_stay_suspended;
<< ", can_stay_suspended=" << can_stay_suspended
<< ", is_stale=" << is_stale
<< ", have_future_data=" << have_future_data
- << ", paused_=" << paused_ << ", seeking_=" << seeking_;
+ << ", paused_=" << paused_ << ", seeking_=" << seeking_
+#if BUILDFLAG(IS_TIZEN_TV)
+ << ", is_paused_by_internal_ =" << is_paused_by_internal_
+ << ", is_suspend_by_upper_ = " << is_suspend_by_upper_
+#endif
+ << ", result.is_suspended=" << result.is_suspended
+ << ", this : " << (void*)this;
// We do not treat `playback_rate_` == 0 as paused. For the media session,
// being paused implies displaying a play button, which is incorrect in this
#if defined(TIZEN_MULTIMEDIA)
void Suspend() override;
void Resume() override;
-
- bool SuspendedByPlayer() override { return was_suspended_by_player_; }
#endif
void OnFrozen() override;
media::register_timeline_cb_info_s info) override;
void OnMrsUrlChange(const std::string& url) override;
void OnContentIdChange(const std::string& id) override;
+
+ void Activate() override;
+ void Deactivate() override;
+ void Show() override;
+ void Hide() override;
#endif
// Shared between the WebMediaPlayer and DemuxerManager::Client interfaces.
#if BUILDFLAG(IS_TIZEN_TV)
double GetStartDate() const override;
+ bool IsSuspendByInternal() override { return is_paused_by_internal_; }
#endif
// Distinct states that |delegate_| can be in. (Public for testing.)
base::TimeDelta max_seekable_time_;
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+ bool is_paused_by_internal_ = false;
+ bool is_suspend_by_upper_ = false;
+#endif
+
// Request pipeline to suspend. It should not block other signals after
// suspended.
bool pending_oneshot_suspend_ = false;
media_player_->SetTaskRunner(task_runner_.get());
if (!media::MediaPlayerRegistry::GetInstance()->ActivateMediaPlayer(
- player_id_, !resource_conflicted_)) {
+ player_id_, !is_suspended_by_resource_conflicted_)) {
LOG_ID(INFO, player_id_)
<< "(" << static_cast<void*>(this) << ") " << __func__
<< " Can not initialize the player id: " << player_id_;
return;
}
- is_suspended_ = false;
- resource_conflicted_ = false;
+ is_suspended_by_resource_conflicted_ = false;
+ is_suspended_by_upper_ = false;
+ is_suspended_by_internal_ = false;
+ LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
+ << __func__ << " is_suspended_by_upper_: "
+ << is_suspended_by_upper_
+ << " is_suspended_by_internal_: "
+ << is_suspended_by_internal_
+ << " is_suspended_by_resource_conflicted_ : "
+ << is_suspended_by_resource_conflicted_;
// Initialize and Prepare early when resource type is URL.
if (media_resource_->GetType() == media::MediaResource::Type::KUrl) {
RenderFrameHost::FromID(render_process_id_, routing_id_));
}
+// upper suspend
void TizenRendererImpl::Suspend() {
LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
<< __func__;
- if (is_suspended_)
+ if (is_suspended_by_upper_)
return;
if (!media_player_) {
return;
}
- media::MediaPlayerRegistry::GetInstance()->DeactivateMediaPlayer(
- player_id_, !resource_conflicted_);
media_player_->Release();
- is_suspended_ = true;
+ is_suspended_by_upper_ = true;
}
void TizenRendererImpl::EnableLowLatencyMode() {
TRACE_EVENT1("media", "TizenRendererImpl::StartPlayingFrom", "time_us",
time.InMicroseconds());
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (!is_player_can_start_) {
+ LOG_ID(WARNING, player_id_)
+ << "(" << static_cast<void*>(this) << ") " << __func__
+ << " , player state not match. Can not initialize the player id: " << player_id_;
+ return;
+ }
+#endif
+
SetPlayerInitialize();
SetPlayerPrepare();
void TizenRendererImpl::DestroyPlayerSync(base::OnceClosure destroy_cb) {
if (media_player_) {
media::MediaPlayerRegistry::GetInstance()->DeactivateMediaPlayer(
- player_id_, !resource_conflicted_);
+ player_id_, !is_suspended_by_resource_conflicted_);
media_player_->DestroyPlayerSync(std::move(destroy_cb));
} else {
LOG_ID(INFO, player_id_) << "media_player_ is nullptr";
}
media_player_->SetCallBackFrameSize(size);
}
+
+void TizenRendererImpl::Activate() {
+ is_suspended_by_internal_ = false;
+ is_player_can_start_ = media::MediaPlayerRegistry::GetInstance()->ActivateMediaPlayer(
+ player_id_, false);
+ LOG_ID(INFO, player_id_) << __func__ << " ; is_player_can_start_ : " << is_player_can_start_;
+}
+
+void TizenRendererImpl::Deactivate() {
+ LOG_ID(INFO, player_id_) << __func__;
+ media::MediaPlayerRegistry::GetInstance()->DeactivateMediaPlayer(
+ player_id_, false);
+}
+
+void TizenRendererImpl::Show() {
+ if(!is_suspended_by_upper_) {
+ LOG_ID(INFO, player_id_) << __func__ << " ; no suspend, not need to resume.";
+ return;
+ }
+
+ is_suspended_by_upper_ = false;
+ is_player_can_start_ = media::MediaPlayerRegistry::GetInstance()->ActivateMediaPlayer(
+ player_id_, true);
+ LOG_ID(INFO, player_id_) << __func__ << " ; is_player_can_start_ : " << is_player_can_start_;
+}
+
+void TizenRendererImpl::Hide() {
+ LOG_ID(INFO, player_id_) << __func__;
+ media::MediaPlayerRegistry::GetInstance()->DeactivateMediaPlayer(
+ player_id_, true);
+}
#endif // BUILDFLAG(IS_TIZEN_TV)
void TizenRendererImpl::OnSeekableTimeChange(base::TimeDelta min_time,
client_->OnRequestSeek(time);
}
+// Two scenarios: (both need set inactive)
+// 1) capability exceed, will call OnRequestSuspend(false)
+// 2) resource confict, will call OnRequestSuspend(false)
void TizenRendererImpl::OnRequestSuspend(bool resource_conflicted) {
LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
<< __func__
<< " ; resource_conflicted: " << resource_conflicted;
- if (is_suspended_) {
- LOG_ID(INFO, player_id_) << " Media is already suspended.";
+ if (is_suspended_by_internal_) {
+ LOG_ID(INFO, player_id_) << " Media is already suspended by internal.";
return;
}
- resource_conflicted_ = resource_conflicted;
- media::MediaPlayerRegistry::GetInstance()->DeactivateMediaPlayer(
- player_id_, !resource_conflicted_);
- is_suspended_ = true;
+ // Keep same logic with 23TV
+ // capability exceed, player state will set player state &= ~State::ACTIVE in
+ // other place resource conflict will set inactive here.
+ if (is_suspended_by_resource_conflicted_) {
+ media::MediaPlayerRegistry::GetInstance()->DeactivateMediaPlayer(
+ player_id_, !is_suspended_by_resource_conflicted_);
+ }
+ is_suspended_by_internal_ = true;
client_->OnRequestSuspend(resource_conflicted);
}
void GetVideoId(GetVideoIdCB cb) override;
void SetCallBackFrameSize(const gfx::Size& size) override;
void EnableTbmBufferCallback(bool enable) override;
+
+ void Activate() override;
+ void Deactivate() override;
+ void Show() override;
+ void Hide() override;
#endif
#if defined(TIZEN_TBM_SUPPORT)
// Indicates if a serious error has been encountered by the |media_player_|.
bool has_error_ = false;
- bool resource_conflicted_ = true;
- bool is_suspended_ = false;
+ bool is_suspended_by_resource_conflicted_ = true;
+ bool is_suspended_by_internal_ = false;
+ bool is_suspended_by_upper_ = false;
#if defined(TIZEN_VIDEO_HOLE)
bool use_subsurface_controller_ = false;
// content, so that we can set it to the media_player_ before calling
// initialize / prepare.
std::string mime_type_;
+ bool is_player_can_start_ = true;
#endif
WebContents* web_contents_ = nullptr;
void LongestConflictStrategy::OnDeactivated(MediaPlayerTizen* player) {
auto it = find(player);
- if (it != info_.end())
+ if (it != info_.end()) {
info_.erase(it);
- LOG(INFO) << "Deactivating " << player << Info();
+ LOG(INFO) << "Deactivating " << player << Info();
+ }
}
LongestConflictStrategy::Resolution LongestConflictStrategy::Resolve(
// is called. As a matter of fact, they
// are done in MoveTowardsRunning via
// MovedFromBarred
+ template <State which_transition>
std::vector<MediaPlayerTizen*> MarkRunning(MediaPlayerTizen* player);
// Once the MarkRunning finds enough empty slots,
while (!players.empty()) {
auto front = players.front();
players.pop();
- auto conflicts = MarkRunning(front);
+ auto conflicts = MarkRunning<which_transition>(front);
for (auto ptr : conflicts) {
if (ptr == player)
succeeded = false;
// here: RUNNING and the other one
// of the single-bit |PlayerState|s
- if ((it->second.state & ~which_transition) != State::NONE)
+ if ((it->second.state & ~which_transition) != State::NONE) {
+ LOG(WARNING) << __func__ << " player: " << it->first << " ,state: " << it->second.state;
return false;
+ }
// either BARRED -> which_transition, or
// which_transition -> which_transition
}
template <typename ConflictStrategy>
+template <State which_transition>
std::vector<MediaPlayerTizen*>
MediaCapabilityManager<ConflictStrategy>::MarkRunning(
MediaPlayerTizen* player) {
LOG(INFO) << "Resolved for " << descriptor << " with:";
evicted.reserve(removed.size());
for (auto& item : removed) {
- LOG(INFO) << " " << item->first << " " << item->second.descriptor;
+ // only mark active player need deactive conflict player.
+ // Fix issue: Tab1 RUNNING player-> change to Tab2 --> Tab2 visible player
+ // --> Tab1 deactive player --> Tab1 player state not match
+ if (which_transition == State::ACTIVE) {
+ LOG(INFO) << "Mark inactive: " << item->first << " " << item->second.descriptor;
- evicted.push_back(item->first);
- item->second.state &= ~State::ACTIVE;
- detail::RemovePlayer{}(slots_, item->first);
- ConflictStrategy::OnDeactivated(item->first);
+ evicted.push_back(item->first);
+ item->second.state &= ~State::ACTIVE;
+
+ detail::RemovePlayer{}(slots_, item->first);
+ ConflictStrategy::OnDeactivated(item->first);
+ }
}
RunPlayer(descriptor, player);
buffer_observer_->ResetBufferStatus();
buffer_observer_->ResetBufferStatusCallbacks();
+ ReportBufferingStateIfNeeded(BUFFERING_HAVE_NOTHING,
+ BUFFERING_CHANGE_REASON_UNKNOWN);
reported_buffering_state_ = BUFFERING_HAVE_NOTHING;
volume_ = 1.0;
if (!result) {
LOG_ID(ERROR, player_id_) << "OnPrepareComplete prepare_async failed.";
- GetMediaPlayerClient()->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
return;
}
bool MediaPlayerRegistry::ActivateMediaPlayer(int player_id,
bool is_suspended) {
- LOG(INFO) << __func__ << " player id: " << player_id;
- if (is_suspended)
+ if (is_suspended) {
+ LOG(INFO) << __func__ << " MarkVisible player id: " << player_id;
return media_capability_manager_.MarkVisible(GetMediaPlayer(player_id));
+ }
+ LOG(INFO) << __func__ << " MarkActive player id: " << player_id;
return media_capability_manager_.MarkActive(GetMediaPlayer(player_id));
}
bool MediaPlayerRegistry::DeactivateMediaPlayer(int player_id,
bool is_suspended) {
- LOG(INFO) << __func__ << " player id: " << player_id;
- if (is_suspended)
+ if (is_suspended) {
+ LOG(INFO) << __func__ << " MarkHidden player id: " << player_id;
return media_capability_manager_.MarkHidden(GetMediaPlayer(player_id));
+ }
+ LOG(INFO) << __func__ << " MarkInactive player id: " << player_id;
return media_capability_manager_.MarkInactive(GetMediaPlayer(player_id));
}