[Chromecast] Support blocking some video resolutions
This allows playback to be blocked based on certain conditions including video resolution (see linked bug + internal CL). BUG=internal b/31055542 Review-Url: https://codereview.chromium.org/2277853002 Cr-Commit-Position: refs/heads/master@{#415218}
This commit is contained in:
@ -82,7 +82,8 @@ static std::unique_ptr<::shell::Service> CreateMojoMediaApplication(
|
||||
base::Bind(&CastContentBrowserClient::CreateMediaPipelineBackend,
|
||||
base::Unretained(browser_client)),
|
||||
base::Bind(&CastContentBrowserClient::CreateCdmFactory,
|
||||
base::Unretained(browser_client))));
|
||||
base::Unretained(browser_client)),
|
||||
browser_client->GetVideoResolutionPolicy()));
|
||||
return std::unique_ptr<::shell::Service>(
|
||||
new ::media::MojoMediaApplication(std::move(mojo_media_client),
|
||||
quit_closure));
|
||||
@ -132,6 +133,11 @@ std::unique_ptr<CastService> CastContentBrowserClient::CreateCastService(
|
||||
}
|
||||
|
||||
#if !defined(OS_ANDROID)
|
||||
media::VideoResolutionPolicy*
|
||||
CastContentBrowserClient::GetVideoResolutionPolicy() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner>
|
||||
CastContentBrowserClient::GetMediaTaskRunner() {
|
||||
DCHECK(cast_browser_main_parts_);
|
||||
|
@ -43,6 +43,7 @@ class MediaPipelineBackendManager;
|
||||
struct MediaPipelineDeviceParams;
|
||||
class MediaResourceTracker;
|
||||
class VideoPlaneController;
|
||||
class VideoResolutionPolicy;
|
||||
}
|
||||
|
||||
namespace shell {
|
||||
@ -74,6 +75,9 @@ class CastContentBrowserClient : public content::ContentBrowserClient {
|
||||
media::VideoPlaneController* video_plane_controller);
|
||||
|
||||
#if !defined(OS_ANDROID)
|
||||
// Gets object for enforcing video resolution policy restrictions.
|
||||
virtual media::VideoResolutionPolicy* GetVideoResolutionPolicy();
|
||||
|
||||
// Returns the task runner that must be used for media IO.
|
||||
scoped_refptr<base::SingleThreadTaskRunner> GetMediaTaskRunner();
|
||||
|
||||
|
@ -47,6 +47,8 @@ source_set("media") {
|
||||
sources += [
|
||||
"cma_message_filter_host.cc",
|
||||
"cma_message_filter_host.h",
|
||||
"video_resolution_policy.cc",
|
||||
"video_resolution_policy.h",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,11 @@ namespace media {
|
||||
|
||||
CastMojoMediaClient::CastMojoMediaClient(
|
||||
const CreateMediaPipelineBackendCB& create_backend_cb,
|
||||
const CreateCdmFactoryCB& create_cdm_factory_cb)
|
||||
const CreateCdmFactoryCB& create_cdm_factory_cb,
|
||||
VideoResolutionPolicy* video_resolution_policy)
|
||||
: create_backend_cb_(create_backend_cb),
|
||||
create_cdm_factory_cb_(create_cdm_factory_cb) {}
|
||||
create_cdm_factory_cb_(create_cdm_factory_cb),
|
||||
video_resolution_policy_(video_resolution_policy) {}
|
||||
|
||||
CastMojoMediaClient::~CastMojoMediaClient() {}
|
||||
|
||||
@ -26,7 +28,8 @@ std::unique_ptr<::media::Renderer> CastMojoMediaClient::CreateRenderer(
|
||||
scoped_refptr<::media::MediaLog> media_log,
|
||||
const std::string& audio_device_id) {
|
||||
return base::MakeUnique<chromecast::media::CastRenderer>(
|
||||
create_backend_cb_, std::move(media_task_runner), audio_device_id);
|
||||
create_backend_cb_, std::move(media_task_runner), audio_device_id,
|
||||
video_resolution_policy_);
|
||||
}
|
||||
|
||||
std::unique_ptr<::media::CdmFactory> CastMojoMediaClient::CreateCdmFactory(
|
||||
|
@ -11,13 +11,16 @@
|
||||
namespace chromecast {
|
||||
namespace media {
|
||||
|
||||
class VideoResolutionPolicy;
|
||||
|
||||
class CastMojoMediaClient : public ::media::MojoMediaClient {
|
||||
public:
|
||||
using CreateCdmFactoryCB =
|
||||
base::Callback<std::unique_ptr<::media::CdmFactory>()>;
|
||||
|
||||
CastMojoMediaClient(const CreateMediaPipelineBackendCB& create_backend_cb,
|
||||
const CreateCdmFactoryCB& create_cdm_factory_cb);
|
||||
const CreateCdmFactoryCB& create_cdm_factory_cb,
|
||||
VideoResolutionPolicy* video_resolution_policy);
|
||||
~CastMojoMediaClient() override;
|
||||
|
||||
// MojoMediaClient overrides.
|
||||
@ -31,6 +34,7 @@ class CastMojoMediaClient : public ::media::MojoMediaClient {
|
||||
private:
|
||||
const CreateMediaPipelineBackendCB create_backend_cb_;
|
||||
const CreateCdmFactoryCB create_cdm_factory_cb_;
|
||||
VideoResolutionPolicy* video_resolution_policy_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CastMojoMediaClient);
|
||||
};
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "chromecast/base/task_runner_impl.h"
|
||||
#include "chromecast/browser/media/video_resolution_policy.h"
|
||||
#include "chromecast/media/cdm/cast_cdm_context.h"
|
||||
#include "chromecast/media/cma/base/balanced_media_task_runner_factory.h"
|
||||
#include "chromecast/media/cma/base/cma_logging.h"
|
||||
@ -33,21 +34,29 @@ const base::TimeDelta kMaxDeltaFetcher(base::TimeDelta::FromMilliseconds(2000));
|
||||
CastRenderer::CastRenderer(
|
||||
const CreateMediaPipelineBackendCB& create_backend_cb,
|
||||
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
||||
const std::string& audio_device_id)
|
||||
const std::string& audio_device_id,
|
||||
VideoResolutionPolicy* video_resolution_policy)
|
||||
: create_backend_cb_(create_backend_cb),
|
||||
task_runner_(task_runner),
|
||||
audio_device_id_(audio_device_id),
|
||||
video_resolution_policy_(video_resolution_policy),
|
||||
client_(nullptr),
|
||||
cast_cdm_context_(nullptr),
|
||||
media_task_runner_factory_(
|
||||
new BalancedMediaTaskRunnerFactory(kMaxDeltaFetcher)),
|
||||
weak_factory_(this) {
|
||||
CMALOG(kLogControl) << __FUNCTION__ << ": " << this;
|
||||
|
||||
if (video_resolution_policy_)
|
||||
video_resolution_policy_->AddObserver(this);
|
||||
}
|
||||
|
||||
CastRenderer::~CastRenderer() {
|
||||
CMALOG(kLogControl) << __FUNCTION__ << ": " << this;
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
|
||||
if (video_resolution_policy_)
|
||||
video_resolution_policy_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void CastRenderer::Initialize(
|
||||
@ -206,6 +215,15 @@ bool CastRenderer::HasVideo() {
|
||||
return pipeline_->HasVideo();
|
||||
}
|
||||
|
||||
void CastRenderer::OnVideoResolutionPolicyChanged() {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
if (!video_resolution_policy_)
|
||||
return;
|
||||
|
||||
if (video_resolution_policy_->ShouldBlock(video_res_))
|
||||
OnError(::media::PIPELINE_ERROR_DECODE);
|
||||
}
|
||||
|
||||
void CastRenderer::OnError(::media::PipelineStatus status) {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
client_->OnError(status);
|
||||
@ -240,6 +258,9 @@ void CastRenderer::OnWaitingForDecryptionKey() {
|
||||
void CastRenderer::OnVideoNaturalSizeChange(const gfx::Size& size) {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
client_->OnVideoNaturalSizeChange(size);
|
||||
|
||||
video_res_ = size;
|
||||
OnVideoResolutionPolicyChanged();
|
||||
}
|
||||
|
||||
void CastRenderer::OnVideoOpacityChange(bool opaque) {
|
||||
|
@ -2,8 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROMECAST_BROWSER_MEDIA_CAST_RENDERER_H_
|
||||
#define CHROMECAST_BROWSER_MEDIA_CAST_RENDERER_H_
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "chromecast/browser/media/media_pipeline_backend_factory.h"
|
||||
#include "chromecast/browser/media/video_resolution_policy.h"
|
||||
#include "media/base/renderer.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
|
||||
@ -23,11 +27,13 @@ class BalancedMediaTaskRunnerFactory;
|
||||
class CastCdmContext;
|
||||
class MediaPipelineImpl;
|
||||
|
||||
class CastRenderer : public ::media::Renderer {
|
||||
class CastRenderer : public ::media::Renderer,
|
||||
public VideoResolutionPolicy::Observer {
|
||||
public:
|
||||
CastRenderer(const CreateMediaPipelineBackendCB& create_backend_cb,
|
||||
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
||||
const std::string& audio_device_id);
|
||||
const std::string& audio_device_id,
|
||||
VideoResolutionPolicy* video_resolution_policy);
|
||||
~CastRenderer() final;
|
||||
|
||||
// ::media::Renderer implementation.
|
||||
@ -44,6 +50,9 @@ class CastRenderer : public ::media::Renderer {
|
||||
bool HasAudio() final;
|
||||
bool HasVideo() final;
|
||||
|
||||
// VideoResolutionPolicy::Observer implementation.
|
||||
void OnVideoResolutionPolicyChanged() override;
|
||||
|
||||
private:
|
||||
enum Stream { STREAM_AUDIO, STREAM_VIDEO };
|
||||
void OnError(::media::PipelineStatus status);
|
||||
@ -53,16 +62,19 @@ class CastRenderer : public ::media::Renderer {
|
||||
void OnWaitingForDecryptionKey();
|
||||
void OnVideoNaturalSizeChange(const gfx::Size& size);
|
||||
void OnVideoOpacityChange(bool opaque);
|
||||
void CheckVideoResolutionPolicy();
|
||||
|
||||
const CreateMediaPipelineBackendCB create_backend_cb_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
||||
std::string audio_device_id_;
|
||||
VideoResolutionPolicy* video_resolution_policy_;
|
||||
::media::RendererClient* client_;
|
||||
CastCdmContext* cast_cdm_context_;
|
||||
scoped_refptr<BalancedMediaTaskRunnerFactory> media_task_runner_factory_;
|
||||
std::unique_ptr<TaskRunnerImpl> backend_task_runner_;
|
||||
std::unique_ptr<MediaPipelineImpl> pipeline_;
|
||||
bool eos_[2];
|
||||
gfx::Size video_res_;
|
||||
base::WeakPtrFactory<CastRenderer> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CastRenderer);
|
||||
@ -70,3 +82,5 @@ class CastRenderer : public ::media::Renderer {
|
||||
|
||||
} // namespace media
|
||||
} // namespace chromecast
|
||||
|
||||
#endif // CHROMECAST_BROWSER_MEDIA_CAST_RENDERER_H_
|
||||
|
13
chromecast/browser/media/video_resolution_policy.cc
Normal file
13
chromecast/browser/media/video_resolution_policy.cc
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chromecast/browser/media/video_resolution_policy.h"
|
||||
|
||||
namespace chromecast {
|
||||
namespace media {
|
||||
|
||||
VideoResolutionPolicy::~VideoResolutionPolicy() {}
|
||||
|
||||
} // namespace media
|
||||
} // namespace chromecast
|
44
chromecast/browser/media/video_resolution_policy.h
Normal file
44
chromecast/browser/media/video_resolution_policy.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROMECAST_BROWSER_MEDIA_VIDEO_RESOLUTION_POLICY_H_
|
||||
#define CHROMECAST_BROWSER_MEDIA_VIDEO_RESOLUTION_POLICY_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
|
||||
namespace gfx {
|
||||
class Size;
|
||||
} // namespace gfx
|
||||
|
||||
namespace chromecast {
|
||||
namespace media {
|
||||
|
||||
// Interface allowing renderer to check for whether certain video resolutions
|
||||
// should have playback blocked.
|
||||
// TODO(halliwell): remove this mechanism once we have PR3.
|
||||
class VideoResolutionPolicy {
|
||||
public:
|
||||
// Observer allows policy subclass to notify renderer when some
|
||||
// conditions have changed. Renderer should re-check current
|
||||
// resolution.
|
||||
class Observer {
|
||||
public:
|
||||
virtual void OnVideoResolutionPolicyChanged() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Observer() {}
|
||||
};
|
||||
|
||||
virtual ~VideoResolutionPolicy();
|
||||
|
||||
virtual void AddObserver(Observer* observer) = 0;
|
||||
virtual void RemoveObserver(Observer* observer) = 0;
|
||||
|
||||
virtual bool ShouldBlock(const gfx::Size& size) = 0;
|
||||
};
|
||||
|
||||
} // namespace media
|
||||
} // namespace chromecast
|
||||
|
||||
#endif // CHROMECAST_BROWSER_MEDIA_VIDEO_RESOLUTION_POLICY_H_
|
Reference in New Issue
Block a user