diff options
-rw-r--r-- | chromecast/base/cast_resource.cc | 4 | ||||
-rw-r--r-- | chromecast/base/cast_resource.h | 39 | ||||
-rw-r--r-- | chromecast/browser/media/cma_media_pipeline_client.cc | 4 | ||||
-rw-r--r-- | chromecast/browser/media/cma_media_pipeline_client.h | 1 | ||||
-rw-r--r-- | chromecast/media/base/video_plane_controller.cc | 30 | ||||
-rw-r--r-- | chromecast/media/base/video_plane_controller.h | 16 |
6 files changed, 84 insertions, 10 deletions
diff --git a/chromecast/base/cast_resource.cc b/chromecast/base/cast_resource.cc index cbe9b51..7978d86 100644 --- a/chromecast/base/cast_resource.cc +++ b/chromecast/base/cast_resource.cc @@ -10,9 +10,9 @@ void CastResource::SetCastResourceClient(Client* client) { client_ = client; } -void CastResource::NotifyResourceAcquired() { +void CastResource::RegisterWithClient() { if (client_) - client_->OnResourceAcquired(this); + client_->RegisterCastResource(this); } void CastResource::NotifyResourceReleased(Resource remain) { diff --git a/chromecast/base/cast_resource.h b/chromecast/base/cast_resource.h index cd248d7..67315ec 100644 --- a/chromecast/base/cast_resource.h +++ b/chromecast/base/cast_resource.h @@ -9,7 +9,13 @@ namespace chromecast { -// Interface for resources needed to run application. +// A CastResource is a user of 1 or more Resources (primary screen, audio, +// etc). As a user, it is responsible for doing any cast-specific component +// initialization when the Resources it uses are granted. This initialization +// is referred to as "acquiring" the Resources. Conversely, when the Resources +// it uses are revoked, it must deinitialize these cast-specific components. +// This deinitialization is referred to as "releasing" the Resources. +// TODO(maclellant): RENAME/DESIGN THIS CLASS IN COMING REFACTOR. class CastResource { public: // Resources necessary to run cast apps. CastResource may contain union of the @@ -33,11 +39,22 @@ class CastResource { (kResourceAudio | kResourceScreenPrimary | kResourceScreenSecondary), }; + // A Client is responsible for notifying all registered CastResource's when + // Resources are granted/revoked so that they can acquire/release those + // Resources. When a CastResource is done acquiring/releasing, it responds + // to the Client that it has completed. A Client can have multiple registered + // CastResource's, but each CastResouce has 1 Client that it responds to. class Client { public: - // Called when resource is created. CastResource should not be owned by - // Client. It can be called from any thread. - virtual void OnResourceAcquired(CastResource* cast_resource) = 0; + // Called to register a CastResource with a Client. After registering, a + // CastResource will start getting notified when to acquire/release + // Resources. The Client does not take ownership of |cast_resource|. It can + // be called from any thread. + virtual void RegisterCastResource(CastResource* cast_resource) = 0; + + // TODO(esum): Add OnResourceAcquired() here once AcquireResource is + // allowed to be asynchronous. + // Called when part or all resources are released. It can be called from any // thread. // |cast_resource| the CastResource that is released. The pointer may be @@ -52,7 +69,17 @@ class CastResource { virtual ~Client() {} }; + // Sets the Client for the CastResource to respond to when it is done with + // Acquire/ReleaseResource. void SetCastResourceClient(Client* client); + // Called to acquire resources after OEM has granted them, and before + // they start getting used by consumers. Implementation must be synchronous + // since consumers will start using the resource immediately afterwards. + // TODO(esum): We should allow this method to be asynchronous in case an + // implementer needs to make expensive calls and doesn't want to block the + // UI thread (b/26239576). For now, don't do anything expensive in your + // implementation; if you really need to, then this bug has to be resolved. + virtual void AcquireResource(Resource resource) = 0; // Called to release resources. Implementation should call // Client::OnResourceReleased when resource is released on its side. virtual void ReleaseResource(Resource resource) = 0; @@ -61,7 +88,9 @@ class CastResource { CastResource() : client_(nullptr) {} virtual ~CastResource() {} - void NotifyResourceAcquired(); + // For derived classes to register themselves with their Client through + // Client::RegisterCastResource. + void RegisterWithClient(); void NotifyResourceReleased(Resource remain); private: diff --git a/chromecast/browser/media/cma_media_pipeline_client.cc b/chromecast/browser/media/cma_media_pipeline_client.cc index 0507d87..a62e1ec 100644 --- a/chromecast/browser/media/cma_media_pipeline_client.cc +++ b/chromecast/browser/media/cma_media_pipeline_client.cc @@ -25,7 +25,7 @@ void CmaMediaPipelineClient::OnMediaPipelineBackendCreated() { media_pipeline_count_++; if (media_pipeline_count_ == 1) - NotifyResourceAcquired(); + CastResource::RegisterWithClient(); } void CmaMediaPipelineClient::OnMediaPipelineBackendDestroyed() { @@ -36,6 +36,8 @@ void CmaMediaPipelineClient::OnMediaPipelineBackendDestroyed() { NotifyResourceReleased(CastResource::kResourceNone); } +void CmaMediaPipelineClient::AcquireResource(CastResource::Resource resource) {} + void CmaMediaPipelineClient::ReleaseResource(CastResource::Resource resource) { CastResource::Resource audio_video_resource = static_cast<CastResource::Resource>(CastResource::kResourceAudio | diff --git a/chromecast/browser/media/cma_media_pipeline_client.h b/chromecast/browser/media/cma_media_pipeline_client.h index 7c8ce00..0dcf8ba 100644 --- a/chromecast/browser/media/cma_media_pipeline_client.h +++ b/chromecast/browser/media/cma_media_pipeline_client.h @@ -32,6 +32,7 @@ class CmaMediaPipelineClient : public base::RefCounted<CmaMediaPipelineClient>, virtual void OnMediaPipelineBackendDestroyed(); // cast::CastResource implementation: + void AcquireResource(CastResource::Resource resource) override; void ReleaseResource(CastResource::Resource resource) override; protected: diff --git a/chromecast/media/base/video_plane_controller.cc b/chromecast/media/base/video_plane_controller.cc index 7202b00..e6496f4 100644 --- a/chromecast/media/base/video_plane_controller.cc +++ b/chromecast/media/base/video_plane_controller.cc @@ -206,8 +206,27 @@ void VideoPlaneController::SetGraphicsPlaneResolution(const Size& resolution) { MaybeRunSetGeometry(); } +void VideoPlaneController::Pause() { + DCHECK(thread_checker_.CalledOnValidThread()); + VLOG(1) << "Pausing controller. No more VideoPlane SetGeometry calls."; + is_paused_ = true; +} + +void VideoPlaneController::Resume() { + DCHECK(thread_checker_.CalledOnValidThread()); + VLOG(1) << "Resuming controller. VideoPlane SetGeometry calls are active."; + is_paused_ = false; + MaybeRunSetGeometry(); +} + +bool VideoPlaneController::is_paused() const { + DCHECK(thread_checker_.CalledOnValidThread()); + return is_paused_; +} + VideoPlaneController::VideoPlaneController() - : have_output_res_(false), + : is_paused_(false), + have_output_res_(false), have_graphics_res_(false), output_res_(0, 0), graphics_res_(0, 0), @@ -222,8 +241,15 @@ VideoPlaneController::~VideoPlaneController() {} void VideoPlaneController::MaybeRunSetGeometry() { DCHECK(thread_checker_.CalledOnValidThread()); - if (!HaveDataForSetGeometry()) + if (is_paused_) { + VLOG(2) << "All VideoPlane SetGeometry calls are paused. Ignoring request."; return; + } + + if (!HaveDataForSetGeometry()) { + VLOG(2) << "Don't have all VideoPlane SetGeometry data. Ignoring request."; + return; + } DCHECK(graphics_res_.width != 0 && graphics_res_.height != 0); diff --git a/chromecast/media/base/video_plane_controller.h b/chromecast/media/base/video_plane_controller.h index 74f91eb..c14ae95 100644 --- a/chromecast/media/base/video_plane_controller.h +++ b/chromecast/media/base/video_plane_controller.h @@ -59,6 +59,20 @@ class VideoPlaneController { // no-op. void SetGraphicsPlaneResolution(const Size& resolution); + // After Pause is called, no further calls to VideoPlane::SetGeometry will be + // made except for any pending calls already scheduled on the media thread. + // The Set methods will however update cached parameters that will take + // effect once the class is resumed. Safe to call multiple times. + // TODO(esum): Handle the case where there are pending calls already on the + // media thread. When this returns, the caller needs to know that absolutely + // no more SetGeometry calls will be made. + void Pause(); + // Makes class active again. Also resets the video plane by posting a call to + // VideoPlane::SetGeometry with most recent resolution and geometry parameters + // (assuming they are all set). Safe to call multiple times. + void Resume(); + bool is_paused() const; + private: class RateLimitedSetVideoPlaneGeometry; friend struct base::DefaultSingletonTraits<VideoPlaneController>; @@ -74,6 +88,8 @@ class VideoPlaneController { // VideoPlane::SetGeometry. bool HaveDataForSetGeometry() const; + bool is_paused_; + // Current resolutions bool have_output_res_; bool have_graphics_res_; |