Commit 51d4d468 authored by Xiaohan Wang's avatar Xiaohan Wang Committed by Commit Bot

media: Simplify Renderer creation in MojoMediaClient

Instead of having MojoMediaClient creating a RendererFactory, ask
MojoMediaClient to create a Renderer directly. This helps us to
eliminate the audio and video renderer sink from the interface, which
isn't interesting to most Renderers hosted by MojoRendererService.

This also helps to simplify how we pass |audio_device_id| into the
Renderer directly (not having to go through the audio sink).

Bug: 586211
Test: All existing tests pass.
Change-Id: Ifcb0708a063da1958ccf495ef08ab8f98902617d
Reviewed-on: https://chromium-review.googlesource.com/1053295Reviewed-by: default avatarStephen Lanham <slan@chromium.org>
Reviewed-by: default avatarThomas Guilbert <tguilbert@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557727}
parent ac37b471
......@@ -7,96 +7,13 @@
#include "chromecast/media/cma/backend/cma_backend_factory.h"
#include "chromecast/media/service/cast_renderer.h"
#include "chromecast/public/media/media_pipeline_backend.h"
#include "media/base/audio_renderer_sink.h"
#include "media/base/cdm_factory.h"
#include "media/base/media_log.h"
#include "media/base/overlay_info.h"
#include "media/base/renderer_factory.h"
namespace chromecast {
namespace media {
namespace {
// CastRenderer does not use a ::media::AudioRendererSink.
// CastAudioRendererSink is only used to hold audio-device-id.
class CastAudioRendererSink : public ::media::AudioRendererSink {
public:
explicit CastAudioRendererSink(const std::string& device_id)
: device_id_(device_id) {}
// ::media::AudioRendererSink implementation.
void Initialize(const ::media::AudioParameters& params,
RenderCallback* callback) final {
NOTREACHED();
}
void Start() final { NOTREACHED(); }
void Stop() final { NOTREACHED(); }
void Pause() final { NOTREACHED(); }
void Play() final { NOTREACHED(); }
bool SetVolume(double volume) final {
NOTREACHED();
return false;
}
::media::OutputDeviceInfo GetOutputDeviceInfo() final {
return ::media::OutputDeviceInfo(device_id_,
::media::OUTPUT_DEVICE_STATUS_OK,
::media::AudioParameters());
}
bool IsOptimizedForHardwareParameters() final {
NOTREACHED();
return true;
}
bool CurrentThreadIsRenderingThread() final {
NOTREACHED();
return false;
}
private:
~CastAudioRendererSink() final {}
std::string device_id_;
DISALLOW_COPY_AND_ASSIGN(CastAudioRendererSink);
};
class CastRendererFactory : public ::media::RendererFactory {
public:
CastRendererFactory(CmaBackendFactory* backend_factory,
VideoModeSwitcher* video_mode_switcher,
VideoResolutionPolicy* video_resolution_policy,
MediaResourceTracker* media_resource_tracker)
: backend_factory_(backend_factory),
video_mode_switcher_(video_mode_switcher),
video_resolution_policy_(video_resolution_policy),
media_resource_tracker_(media_resource_tracker) {}
~CastRendererFactory() final {}
std::unique_ptr<::media::Renderer> CreateRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::TaskRunner>& worker_task_runner,
::media::AudioRendererSink* audio_renderer_sink,
::media::VideoRendererSink* video_renderer_sink,
const ::media::RequestOverlayInfoCB& request_overlay_info_cb,
const gfx::ColorSpace& target_color_space) final {
DCHECK(audio_renderer_sink);
DCHECK(!video_renderer_sink);
return std::make_unique<CastRenderer>(
backend_factory_, media_task_runner,
audio_renderer_sink->GetOutputDeviceInfo().device_id(),
video_mode_switcher_, video_resolution_policy_,
media_resource_tracker_);
}
private:
CmaBackendFactory* const backend_factory_;
VideoModeSwitcher* video_mode_switcher_;
VideoResolutionPolicy* video_resolution_policy_;
MediaResourceTracker* media_resource_tracker_;
DISALLOW_COPY_AND_ASSIGN(CastRendererFactory);
};
} // namespace
CastMojoMediaClient::CastMojoMediaClient(
CmaBackendFactory* backend_factory,
const CreateCdmFactoryCB& create_cdm_factory_cb,
......@@ -120,17 +37,13 @@ void CastMojoMediaClient::Initialize(service_manager::Connector* connector) {
connector_ = connector;
}
scoped_refptr<::media::AudioRendererSink>
CastMojoMediaClient::CreateAudioRendererSink(
std::unique_ptr<::media::Renderer> CastMojoMediaClient::CreateRenderer(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
::media::MediaLog* /* media_log */,
const std::string& audio_device_id) {
return new CastAudioRendererSink(audio_device_id);
}
std::unique_ptr<::media::RendererFactory>
CastMojoMediaClient::CreateRendererFactory(::media::MediaLog* /* media_log */) {
return std::make_unique<CastRendererFactory>(
backend_factory_, video_mode_switcher_, video_resolution_policy_,
media_resource_tracker_);
return std::make_unique<CastRenderer>(
backend_factory_, task_runner, audio_device_id, video_mode_switcher_,
video_resolution_policy_, media_resource_tracker_);
}
std::unique_ptr<::media::CdmFactory> CastMojoMediaClient::CreateCdmFactory(
......
......@@ -32,10 +32,10 @@ class CastMojoMediaClient : public ::media::MojoMediaClient {
// MojoMediaClient overrides.
void Initialize(service_manager::Connector* connector) override;
scoped_refptr<::media::AudioRendererSink> CreateAudioRendererSink(
std::unique_ptr<::media::Renderer> CreateRenderer(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
::media::MediaLog* media_log,
const std::string& audio_device_id) override;
std::unique_ptr<::media::RendererFactory> CreateRendererFactory(
::media::MediaLog* media_log) override;
std::unique_ptr<::media::CdmFactory> CreateCdmFactory(
service_manager::mojom::InterfaceProvider* host_interfaces) override;
......
......@@ -12,13 +12,11 @@
#include "base/threading/platform_thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/elapsed_timer.h"
#include "media/base/audio_renderer_sink.h"
#include "media/base/cdm_config.h"
#include "media/base/cdm_context.h"
#include "media/base/gmock_callback_support.h"
#include "media/base/mock_filters.h"
#include "media/base/test_helpers.h"
#include "media/base/video_renderer_sink.h"
#include "media/cdm/default_cdm_factory.h"
#include "media/mojo/clients/mojo_renderer.h"
#include "media/mojo/common/media_type_converters.h"
......@@ -69,7 +67,7 @@ class MojoRendererTest : public ::testing::Test {
mojom::RendererPtr remote_renderer;
renderer_binding_ = MojoRendererService::Create(
&mojo_cdm_service_context_, nullptr, nullptr, std::move(mock_renderer),
&mojo_cdm_service_context_, std::move(mock_renderer),
MojoRendererService::InitiateSurfaceRequestCB(),
mojo::MakeRequest(&remote_renderer));
......
......@@ -26,9 +26,7 @@
#if BUILDFLAG(ENABLE_MOJO_RENDERER)
#include "base/bind_helpers.h"
#include "media/base/audio_renderer_sink.h"
#include "media/base/renderer_factory.h"
#include "media/base/video_renderer_sink.h"
#include "media/base/renderer.h"
#include "media/mojo/services/mojo_renderer_service.h"
#endif // BUILDFLAG(ENABLE_MOJO_RENDERER)
......@@ -107,10 +105,6 @@ void InterfaceFactoryImpl::CreateRenderer(
mojo::InterfaceRequest<mojom::Renderer> request) {
DVLOG(2) << __func__;
#if BUILDFLAG(ENABLE_MOJO_RENDERER)
RendererFactory* renderer_factory = GetRendererFactory();
if (!renderer_factory)
return;
// Creation requests for non default renderers should have already been
// handled by now, in a different layer.
if (type != media::mojom::HostedRendererType::kDefault) {
......@@ -118,17 +112,11 @@ void InterfaceFactoryImpl::CreateRenderer(
return;
}
scoped_refptr<base::SingleThreadTaskRunner> task_runner(
base::ThreadTaskRunnerHandle::Get());
auto audio_sink =
mojo_media_client_->CreateAudioRendererSink(type_specific_id);
auto video_sink = mojo_media_client_->CreateVideoRendererSink(task_runner);
// TODO(hubbe): Find out if gfx::ColorSpace() is correct for the
// target_color_space.
auto renderer = renderer_factory->CreateRenderer(
task_runner, task_runner, audio_sink.get(), video_sink.get(),
RequestOverlayInfoCB(), gfx::ColorSpace());
// For HostedRendererType::kDefault type, |type_specific_id| represents an
// audio device ID. See interface_factory.mojom.
const std::string& audio_device_id = type_specific_id;
auto renderer = mojo_media_client_->CreateRenderer(
base::ThreadTaskRunnerHandle::Get(), media_log_, audio_device_id);
if (!renderer) {
DLOG(ERROR) << "Renderer creation failed.";
return;
......@@ -136,8 +124,8 @@ void InterfaceFactoryImpl::CreateRenderer(
std::unique_ptr<MojoRendererService> mojo_renderer_service =
std::make_unique<MojoRendererService>(
&cdm_service_context_, std::move(audio_sink), std::move(video_sink),
std::move(renderer), MojoRendererService::InitiateSurfaceRequestCB());
&cdm_service_context_, std::move(renderer),
MojoRendererService::InitiateSurfaceRequestCB());
MojoRendererService* mojo_renderer_service_ptr = mojo_renderer_service.get();
......@@ -280,16 +268,6 @@ void InterfaceFactoryImpl::OnBindingConnectionError() {
std::move(destroy_cb_).Run();
}
#if BUILDFLAG(ENABLE_MOJO_RENDERER)
RendererFactory* InterfaceFactoryImpl::GetRendererFactory() {
if (!renderer_factory_) {
renderer_factory_ = mojo_media_client_->CreateRendererFactory(media_log_);
LOG_IF(ERROR, !renderer_factory_) << "RendererFactory not available.";
}
return renderer_factory_.get();
}
#endif // BUILDFLAG(ENABLE_MOJO_RENDERER)
#if BUILDFLAG(ENABLE_MOJO_CDM)
CdmFactory* InterfaceFactoryImpl::GetCdmFactory() {
if (!cdm_factory_) {
......
......@@ -21,7 +21,6 @@ namespace media {
class CdmFactory;
class MediaLog;
class MojoMediaClient;
class RendererFactory;
class InterfaceFactoryImpl : public DeferredDestroy<mojom::InterfaceFactory> {
public:
......@@ -55,10 +54,6 @@ class InterfaceFactoryImpl : public DeferredDestroy<mojom::InterfaceFactory> {
void SetBindingConnectionErrorHandler();
void OnBindingConnectionError();
#if BUILDFLAG(ENABLE_MOJO_RENDERER)
RendererFactory* GetRendererFactory();
#endif // BUILDFLAG(ENABLE_MOJO_RENDERER)
#if BUILDFLAG(ENABLE_MOJO_CDM)
CdmFactory* GetCdmFactory();
#endif // BUILDFLAG(ENABLE_MOJO_CDM)
......@@ -78,7 +73,6 @@ class InterfaceFactoryImpl : public DeferredDestroy<mojom::InterfaceFactory> {
#if BUILDFLAG(ENABLE_MOJO_RENDERER)
MediaLog* media_log_;
std::unique_ptr<RendererFactory> renderer_factory_;
mojo::StrongBindingSet<mojom::Renderer> renderer_bindings_;
#endif // BUILDFLAG(ENABLE_MOJO_RENDERER)
......
......@@ -6,12 +6,10 @@
#include "base/single_thread_task_runner.h"
#include "media/base/audio_decoder.h"
#include "media/base/audio_renderer_sink.h"
#include "media/base/cdm_factory.h"
#include "media/base/media_log.h"
#include "media/base/renderer_factory.h"
#include "media/base/renderer.h"
#include "media/base/video_decoder.h"
#include "media/base/video_renderer_sink.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_proxy.h"
......@@ -38,21 +36,13 @@ std::unique_ptr<VideoDecoder> MojoMediaClient::CreateVideoDecoder(
return nullptr;
}
scoped_refptr<AudioRendererSink> MojoMediaClient::CreateAudioRendererSink(
std::unique_ptr<Renderer> MojoMediaClient::CreateRenderer(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log,
const std::string& audio_device_id) {
return nullptr;
}
std::unique_ptr<VideoRendererSink> MojoMediaClient::CreateVideoRendererSink(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
return nullptr;
}
std::unique_ptr<RendererFactory> MojoMediaClient::CreateRendererFactory(
MediaLog* media_log) {
return nullptr;
}
std::unique_ptr<CdmFactory> MojoMediaClient::CreateCdmFactory(
service_manager::mojom::InterfaceProvider* host_interfaces) {
return nullptr;
......
......@@ -30,13 +30,11 @@ class InterfaceProvider;
namespace media {
class AudioDecoder;
class AudioRendererSink;
class CdmFactory;
class CdmProxy;
class MediaLog;
class RendererFactory;
class Renderer;
class VideoDecoder;
class VideoRendererSink;
class MEDIA_MOJO_EXPORT MojoMediaClient {
public:
......@@ -58,20 +56,13 @@ class MEDIA_MOJO_EXPORT MojoMediaClient {
mojom::CommandBufferIdPtr command_buffer_id,
RequestOverlayInfoCB request_overlay_info_cb);
// Returns the output sink used for rendering audio on |audio_device_id|.
// May be null if the RendererFactory doesn't need an audio sink.
virtual scoped_refptr<AudioRendererSink> CreateAudioRendererSink(
// Returns the Renderer to be used by MojoRendererService.
// TODO(hubbe): Find out whether we should pass in |target_color_space| here.
virtual std::unique_ptr<Renderer> CreateRenderer(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log,
const std::string& audio_device_id);
// Returns the output sink used for rendering video.
// May be null if the RendererFactory doesn't need a video sink.
virtual std::unique_ptr<VideoRendererSink> CreateVideoRendererSink(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
// Returns the RendererFactory to be used by MojoRendererService.
virtual std::unique_ptr<RendererFactory> CreateRendererFactory(
MediaLog* media_log);
// Returns the CdmFactory to be used by MojoCdmService. |host_interfaces| can
// be used to request interfaces provided remotely by the host. It may be a
// nullptr if the host chose not to bind the InterfacePtr.
......
......@@ -9,11 +9,9 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "media/base/audio_renderer_sink.h"
#include "media/base/cdm_context.h"
#include "media/base/media_url_demuxer.h"
#include "media/base/renderer.h"
#include "media/base/video_renderer_sink.h"
#include "media/mojo/common/media_type_converters.h"
#include "media/mojo/services/media_resource_shim.h"
#include "media/mojo/services/mojo_cdm_service_context.h"
......@@ -36,14 +34,12 @@ const int kTimeUpdateIntervalMs = 50;
// static
mojo::StrongBindingPtr<mojom::Renderer> MojoRendererService::Create(
MojoCdmServiceContext* mojo_cdm_service_context,
scoped_refptr<AudioRendererSink> audio_sink,
std::unique_ptr<VideoRendererSink> video_sink,
std::unique_ptr<media::Renderer> renderer,
const InitiateSurfaceRequestCB& initiate_surface_request_cb,
mojo::InterfaceRequest<mojom::Renderer> request) {
MojoRendererService* service = new MojoRendererService(
mojo_cdm_service_context, std::move(audio_sink), std::move(video_sink),
std::move(renderer), initiate_surface_request_cb);
MojoRendererService* service =
new MojoRendererService(mojo_cdm_service_context, std::move(renderer),
initiate_surface_request_cb);
mojo::StrongBindingPtr<mojom::Renderer> binding =
mojo::MakeStrongBinding<mojom::Renderer>(base::WrapUnique(service),
......@@ -59,22 +55,18 @@ mojo::StrongBindingPtr<mojom::Renderer> MojoRendererService::Create(
std::unique_ptr<media::Renderer> renderer,
const InitiateSurfaceRequestCB& initiate_surface_request_cb,
mojo::InterfaceRequest<mojom::Renderer> request) {
return MojoRendererService::Create(
nullptr, nullptr, nullptr, std::move(renderer),
initiate_surface_request_cb, std::move(request));
return MojoRendererService::Create(nullptr, std::move(renderer),
initiate_surface_request_cb,
std::move(request));
}
MojoRendererService::MojoRendererService(
MojoCdmServiceContext* mojo_cdm_service_context,
scoped_refptr<AudioRendererSink> audio_sink,
std::unique_ptr<VideoRendererSink> video_sink,
std::unique_ptr<media::Renderer> renderer,
InitiateSurfaceRequestCB initiate_surface_request_cb)
: mojo_cdm_service_context_(mojo_cdm_service_context),
state_(STATE_UNINITIALIZED),
playback_rate_(0),
audio_sink_(std::move(audio_sink)),
video_sink_(std::move(video_sink)),
renderer_(std::move(renderer)),
initiate_surface_request_cb_(initiate_surface_request_cb),
weak_factory_(this) {
......@@ -281,9 +273,8 @@ void MojoRendererService::OnFlushCompleted(FlushCallback callback) {
std::move(callback).Run();
}
void MojoRendererService::OnCdmAttached(
base::OnceCallback<void(bool)> callback,
bool success) {
void MojoRendererService::OnCdmAttached(base::OnceCallback<void(bool)> callback,
bool success) {
DVLOG(1) << __func__ << "(" << success << ")";
if (!success)
......
......@@ -25,12 +25,10 @@
namespace media {
class AudioRendererSink;
class CdmContextRef;
class MediaResourceShim;
class MojoCdmServiceContext;
class Renderer;
class VideoRendererSink;
// A mojom::Renderer implementation that use a media::Renderer to render
// media streams.
......@@ -43,20 +41,15 @@ class MEDIA_MOJO_EXPORT MojoRendererService : public mojom::Renderer,
// which is safely accessible via the returned StrongBindingPtr.
static mojo::StrongBindingPtr<mojom::Renderer> Create(
MojoCdmServiceContext* mojo_cdm_service_context,
scoped_refptr<AudioRendererSink> audio_sink,
std::unique_ptr<VideoRendererSink> video_sink,
std::unique_ptr<media::Renderer> renderer,
const InitiateSurfaceRequestCB& initiate_surface_request_cb,
mojo::InterfaceRequest<mojom::Renderer> request);
// Helper function to bind MojoRendererService with a StrongBinding,
// which is safely accessible via the returned StrongBindingPtr.
// NOTE: Some media::Renderers don't need Audio/VideoRendererSinks, and don't
// support encrypted content. For example, MediaPlayerRenderer instead uses a
// StreamTextureWrapper, and FlingingRenderer does not need to render any
// video on the local device. This function serves the same purpose as the one
// above, but without forcing classes to define the forward declared
// AudioRendererSink, VideoRendererSink and MojoCdmServiceContext.
// NOTE: Some media::Renderers don't support encrypted content. This function
// serves the same purpose as the one above, but without forcing classes to
// define the forward declared MojoCdmServiceContext.
static mojo::StrongBindingPtr<mojom::Renderer> Create(
std::unique_ptr<media::Renderer> renderer,
const InitiateSurfaceRequestCB& initiate_surface_request_cb,
......@@ -65,8 +58,6 @@ class MEDIA_MOJO_EXPORT MojoRendererService : public mojom::Renderer,
// |mojo_cdm_service_context| can be used to find the CDM to support
// encrypted media. If null, encrypted media is not supported.
MojoRendererService(MojoCdmServiceContext* mojo_cdm_service_context,
scoped_refptr<AudioRendererSink> audio_sink,
std::unique_ptr<VideoRendererSink> video_sink,
std::unique_ptr<media::Renderer> renderer,
InitiateSurfaceRequestCB initiate_surface_request_cb);
......@@ -150,14 +141,8 @@ class MEDIA_MOJO_EXPORT MojoRendererService : public mojom::Renderer,
// the |renderer_|.
std::unique_ptr<CdmContextRef> cdm_context_ref_;
// Audio and Video sinks.
// May be null if underlying |renderer_| does not use them.
scoped_refptr<AudioRendererSink> audio_sink_;
std::unique_ptr<VideoRendererSink> video_sink_;
// Note: Destroy |renderer_| first to avoid access violation into other
// members, e.g. |media_resource_|, |cdm_|, |audio_sink_|, and
// |video_sink_|.
// members, e.g. |media_resource_| and |cdm_|.
// Must use "media::" because "Renderer" is ambiguous.
std::unique_ptr<media::Renderer> renderer_;
......
......@@ -55,23 +55,35 @@ void TestMojoMediaClient::Initialize(
}
}
scoped_refptr<AudioRendererSink> TestMojoMediaClient::CreateAudioRendererSink(
std::unique_ptr<Renderer> TestMojoMediaClient::CreateRenderer(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log,
const std::string& /* audio_device_id */) {
return new AudioOutputStreamSink();
}
// If called the first time, do one time initialization.
if (!renderer_factory_) {
renderer_factory_ = std::make_unique<DefaultRendererFactory>(
media_log, nullptr, DefaultRendererFactory::GetGpuFactoriesCB());
}
std::unique_ptr<VideoRendererSink> TestMojoMediaClient::CreateVideoRendererSink(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
return std::make_unique<NullVideoSink>(
// We cannot share AudioOutputStreamSink or NullVideoSink among different
// RendererImpls. Thus create one for each Renderer creation.
auto audio_sink = base::MakeRefCounted<AudioOutputStreamSink>();
auto video_sink = std::make_unique<NullVideoSink>(
false, base::TimeDelta::FromSecondsD(1.0 / 60),
NullVideoSink::NewFrameCB(), task_runner);
}
auto* video_sink_ptr = video_sink.get();
std::unique_ptr<RendererFactory> TestMojoMediaClient::CreateRendererFactory(
MediaLog* media_log) {
return std::make_unique<DefaultRendererFactory>(
media_log, nullptr, DefaultRendererFactory::GetGpuFactoriesCB());
}
// Hold created sinks since DefaultRendererFactory only takes raw pointers to
// the sinks. We are not cleaning up them even after a created Renderer is
// destroyed. But this is fine since this class is only used for tests.
audio_sinks_.push_back(audio_sink);
video_sinks_.push_back(std::move(video_sink));
return renderer_factory_->CreateRenderer(
task_runner, task_runner, audio_sink.get(), video_sink_ptr,
RequestOverlayInfoCB(), gfx::ColorSpace());
} // namespace media
std::unique_ptr<CdmFactory> TestMojoMediaClient::CreateCdmFactory(
service_manager::mojom::InterfaceProvider* /* host_interfaces */) {
......
......@@ -6,25 +6,21 @@
#define MEDIA_MOJO_SERVICES_TEST_MOJO_MEDIA_CLIENT_H_
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/media_buildflags.h"
#include "media/mojo/services/mojo_media_client.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace media {
class AudioManager;
class AudioRendererSink;
class MediaLog;
class RendererFactory;
class VideoRendererSink;
// Default MojoMediaClient for MediaService.
// Test MojoMediaClient for MediaService.
class TestMojoMediaClient : public MojoMediaClient {
public:
TestMojoMediaClient();
......@@ -32,12 +28,10 @@ class TestMojoMediaClient : public MojoMediaClient {
// MojoMediaClient implementation.
void Initialize(service_manager::Connector* connector) final;
scoped_refptr<AudioRendererSink> CreateAudioRendererSink(
std::unique_ptr<Renderer> CreateRenderer(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
MediaLog* media_log,
const std::string& audio_device_id) final;
std::unique_ptr<VideoRendererSink> CreateVideoRendererSink(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) final;
std::unique_ptr<RendererFactory> CreateRendererFactory(
MediaLog* media_log) final;
std::unique_ptr<CdmFactory> CreateCdmFactory(
service_manager::mojom::InterfaceProvider* /* host_interfaces */) final;
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
......@@ -46,6 +40,9 @@ class TestMojoMediaClient : public MojoMediaClient {
private:
std::unique_ptr<AudioManager> audio_manager_;
std::unique_ptr<RendererFactory> renderer_factory_;
std::vector<scoped_refptr<AudioRendererSink>> audio_sinks_;
std::vector<std::unique_ptr<VideoRendererSink>> video_sinks_;
DISALLOW_COPY_AND_ASSIGN(TestMojoMediaClient);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment