diff options
-rw-r--r-- | content/renderer/render_frame_impl.cc | 17 | ||||
-rw-r--r-- | content/renderer/render_frame_impl.h | 5 | ||||
-rw-r--r-- | media/base/BUILD.gn | 2 | ||||
-rw-r--r-- | media/base/decoder_factory.cc | 19 | ||||
-rw-r--r-- | media/base/decoder_factory.h | 35 | ||||
-rw-r--r-- | media/media.gyp | 2 | ||||
-rw-r--r-- | media/media_options.gni | 9 | ||||
-rw-r--r-- | media/mojo/services/BUILD.gn | 6 | ||||
-rw-r--r-- | media/mojo/services/mojo_audio_decoder.cc | 60 | ||||
-rw-r--r-- | media/mojo/services/mojo_audio_decoder.h | 43 | ||||
-rw-r--r-- | media/mojo/services/mojo_decoder_factory.cc | 26 | ||||
-rw-r--r-- | media/mojo/services/mojo_decoder_factory.h | 34 | ||||
-rw-r--r-- | media/mojo/services/test_mojo_media_client.cc | 4 | ||||
-rw-r--r-- | media/renderers/default_renderer_factory.cc | 47 | ||||
-rw-r--r-- | media/renderers/default_renderer_factory.h | 15 |
15 files changed, 305 insertions, 19 deletions
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index a15f395..07b3293 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -131,6 +131,7 @@ #include "gin/modules/module_registry.h" #include "media/audio/audio_output_device.h" #include "media/base/audio_renderer_mixer_input.h" +#include "media/base/decoder_factory.h" #include "media/base/media.h" #include "media/base/media_log.h" #include "media/base/media_switches.h" @@ -234,6 +235,10 @@ #include "media/renderers/default_renderer_factory.h" #endif +#if defined(ENABLE_MOJO_AUDIO_DECODER) +#include "media/mojo/services/mojo_decoder_factory.h" // nogncheck +#endif + #if defined(ENABLE_WEBVR) #include "content/renderer/vr/vr_dispatcher.h" #endif @@ -2506,7 +2511,7 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer( if (!media_renderer_factory.get()) { media_renderer_factory.reset(new media::DefaultRendererFactory( - media_log, render_thread->GetGpuFactories(), + media_log, GetDecoderFactory(), render_thread->GetGpuFactories(), *render_thread->GetAudioHardwareConfig())); } #endif // defined(ENABLE_MOJO_RENDERER) @@ -6033,6 +6038,16 @@ media::CdmFactory* RenderFrameImpl::GetCdmFactory() { return cdm_factory_.get(); } +media::DecoderFactory* RenderFrameImpl::GetDecoderFactory() { +#if defined(ENABLE_MOJO_AUDIO_DECODER) + if (!decoder_factory_) { + decoder_factory_.reset( + new media::MojoDecoderFactory(GetMediaServiceFactory())); + } +#endif + return decoder_factory_.get(); +} + void RenderFrameImpl::RegisterMojoServices() { // Only main frame have ImageDownloader service. if (!frame_->parent()) { diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 05beb6d..bf873ed 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -93,6 +93,7 @@ class Rect; namespace media { class CdmFactory; +class DecoderFactory; class MediaPermission; class MediaServiceProvider; class RendererWebMediaPlayerDelegate; @@ -949,6 +950,7 @@ class CONTENT_EXPORT RenderFrameImpl #endif media::CdmFactory* GetCdmFactory(); + media::DecoderFactory* GetDecoderFactory(); void RegisterMojoServices(); @@ -1126,8 +1128,9 @@ class CONTENT_EXPORT RenderFrameImpl RendererCdmManager* cdm_manager_; #endif - // The CDM factory attached to this frame, lazily initialized. + // The CDM and decoder factory attached to this frame, lazily initialized. scoped_ptr<media::CdmFactory> cdm_factory_; + scoped_ptr<media::DecoderFactory> decoder_factory_; // Media resource cache, lazily initialized. linked_ptr<media::UrlIndex> url_index_; diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index f841957..ae207e1 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn @@ -89,6 +89,8 @@ source_set("base") { "decoder_buffer.h", "decoder_buffer_queue.cc", "decoder_buffer_queue.h", + "decoder_factory.cc", + "decoder_factory.h", "decrypt_config.cc", "decrypt_config.h", "decryptor.cc", diff --git a/media/base/decoder_factory.cc b/media/base/decoder_factory.cc new file mode 100644 index 0000000..8fa99ae --- /dev/null +++ b/media/base/decoder_factory.cc @@ -0,0 +1,19 @@ +// 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 "media/base/decoder_factory.h" + +namespace media { + +DecoderFactory::DecoderFactory() {} + +DecoderFactory::~DecoderFactory() {} + +void DecoderFactory::CreateAudioDecoders( + ScopedVector<AudioDecoder>* audio_decoders) {} + +void DecoderFactory::CreateVideoDecoders( + ScopedVector<VideoDecoder>* video_decoders) {} + +} // namespace media diff --git a/media/base/decoder_factory.h b/media/base/decoder_factory.h new file mode 100644 index 0000000..21d66d2 --- /dev/null +++ b/media/base/decoder_factory.h @@ -0,0 +1,35 @@ +// 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 MEDIA_BASE_DECODER_FACTORY_H_ +#define MEDIA_BASE_DECODER_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "media/base/media_export.h" + +namespace media { + +class AudioDecoder; +class VideoDecoder; + +// A factory class for creating audio and video decoders. +class MEDIA_EXPORT DecoderFactory { + public: + DecoderFactory(); + virtual ~DecoderFactory(); + + // Creates audio decoders and append them to the end of |audio_decoders|. + virtual void CreateAudioDecoders(ScopedVector<AudioDecoder>* audio_decoders); + + // Creates video decoders and append them to the end of |video_decoders|. + virtual void CreateVideoDecoders(ScopedVector<VideoDecoder>* video_decoders); + + private: + DISALLOW_COPY_AND_ASSIGN(DecoderFactory); +}; + +} // namespace media + +#endif // MEDIA_BASE_DECODER_FACTORY_H_ diff --git a/media/media.gyp b/media/media.gyp index b6f34aa..ef51a58 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -305,6 +305,8 @@ 'base/decoder_buffer.h', 'base/decoder_buffer_queue.cc', 'base/decoder_buffer_queue.h', + 'base/decoder_factory.cc', + 'base/decoder_factory.h', 'base/decrypt_config.cc', 'base/decrypt_config.h', 'base/decryptor.cc', diff --git a/media/media_options.gni b/media/media_options.gni index 2e91d75..40bfc89 100644 --- a/media/media_options.gni +++ b/media/media_options.gni @@ -87,7 +87,9 @@ declare_args() { # Valid entries in the list are: # - "renderer": Use mojo based media Renderer service. # - "cdm": Use mojo based Content Decryption Module. - # TODO(xhwang): Support mojo base audio/video decoders here. + # - "audio_decoder": Use mojo based audio decoder in the default media + # Renderer. Cannot be used with the mojo Renderer above. + # TODO(xhwang): Support mojo base video decoders here. # See http://crbug.com/542910 and http://crbug.com/522298 mojo_media_services = [] @@ -104,7 +106,10 @@ declare_args() { # for local testing. if (enable_mojo_media) { if (is_android) { - mojo_media_services = [ "cdm" ] + mojo_media_services = [ + "cdm", + "audio_decoder", + ] mojo_media_host = "gpu" } else if (is_chromecast) { mojo_media_services = [ diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn index 7736ff37..7df7098 100644 --- a/media/mojo/services/BUILD.gn +++ b/media/mojo/services/BUILD.gn @@ -26,6 +26,8 @@ config("mojo_media_config") { defines += [ "ENABLE_MOJO_RENDERER" ] } else if (service == "cdm") { defines += [ "ENABLE_MOJO_CDM" ] + } else if (service == "audio_decoder") { + defines += [ "ENABLE_MOJO_AUDIO_DECODER" ] } else { assert(false, "Invalid mojo media service: $service") } @@ -64,10 +66,14 @@ source_set("converters") { # Implementations of media C++ interfaces using corresponding mojo services. source_set("proxy") { sources = [ + "mojo_audio_decoder.cc", + "mojo_audio_decoder.h", "mojo_cdm.cc", "mojo_cdm.h", "mojo_cdm_factory.cc", "mojo_cdm_factory.h", + "mojo_decoder_factory.cc", + "mojo_decoder_factory.h", "mojo_decryptor.cc", "mojo_decryptor.h", "mojo_demuxer_stream_impl.cc", diff --git a/media/mojo/services/mojo_audio_decoder.cc b/media/mojo/services/mojo_audio_decoder.cc new file mode 100644 index 0000000..14a7a00 --- /dev/null +++ b/media/mojo/services/mojo_audio_decoder.cc @@ -0,0 +1,60 @@ +// 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 "media/mojo/services/mojo_audio_decoder.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" + +namespace media { + +MojoAudioDecoder::MojoAudioDecoder() { + DVLOG(1) << __FUNCTION__; +} + +MojoAudioDecoder::~MojoAudioDecoder() { + DVLOG(1) << __FUNCTION__; +} + +std::string MojoAudioDecoder::GetDisplayName() const { + return "MojoAudioDecoder"; +} + +void MojoAudioDecoder::Initialize(const AudioDecoderConfig& config, + CdmContext* cdm_context, + const InitCB& init_cb, + const OutputCB& output_cb) { + DVLOG(1) << __FUNCTION__; + task_runner_ = base::ThreadTaskRunnerHandle::Get(); + + NOTIMPLEMENTED(); + + // Pretend to be able to decode anything. + task_runner_->PostTask(FROM_HERE, base::Bind(init_cb, true)); +} + +void MojoAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb) { + DVLOG(3) << __FUNCTION__; + NOTIMPLEMENTED(); + + // Actually we can't decode anything. + task_runner_->PostTask(FROM_HERE, base::Bind(decode_cb, kDecodeError)); +} + +void MojoAudioDecoder::Reset(const base::Closure& closure) { + DVLOG(2) << __FUNCTION__; + NOTIMPLEMENTED(); +} + +bool MojoAudioDecoder::NeedsBitstreamConversion() const { + DVLOG(1) << __FUNCTION__; + NOTIMPLEMENTED(); + return false; +} + +} // namespace media diff --git a/media/mojo/services/mojo_audio_decoder.h b/media/mojo/services/mojo_audio_decoder.h new file mode 100644 index 0000000..041bee89 --- /dev/null +++ b/media/mojo/services/mojo_audio_decoder.h @@ -0,0 +1,43 @@ +// 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 MEDIA_MOJO_SERVICES_MOJO_AUDIO_DECODER_H_ +#define MEDIA_MOJO_SERVICES_MOJO_AUDIO_DECODER_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "media/base/audio_decoder.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace media { + +// An AudioDecoder that proxies to a interfaces::AudioDecoder. +class MojoAudioDecoder : public AudioDecoder { + public: + MojoAudioDecoder(); + ~MojoAudioDecoder() final; + + // AudioDecoder implementation. + std::string GetDisplayName() const final; + void Initialize(const AudioDecoderConfig& config, + CdmContext* cdm_context, + const InitCB& init_cb, + const OutputCB& output_cb) final; + void Decode(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb) final; + void Reset(const base::Closure& closure) final; + bool NeedsBitstreamConversion() const final; + + private: + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + DISALLOW_COPY_AND_ASSIGN(MojoAudioDecoder); +}; + +} // namespace media + +#endif // MEDIA_MOJO_SERVICES_MOJO_AUDIO_DECODER_H_ diff --git a/media/mojo/services/mojo_decoder_factory.cc b/media/mojo/services/mojo_decoder_factory.cc new file mode 100644 index 0000000..c23534d --- /dev/null +++ b/media/mojo/services/mojo_decoder_factory.cc @@ -0,0 +1,26 @@ +// 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 "media/mojo/services/mojo_decoder_factory.h" + +#include "media/mojo/interfaces/service_factory.mojom.h" +#include "media/mojo/services/mojo_audio_decoder.h" + +namespace media { + +MojoDecoderFactory::MojoDecoderFactory( + interfaces::ServiceFactory* service_factory) + : service_factory_(service_factory) { + DCHECK(service_factory_); +} + +MojoDecoderFactory::~MojoDecoderFactory() {} + +void MojoDecoderFactory::CreateAudioDecoders( + ScopedVector<AudioDecoder>* audio_decoders) { + // TODO(xhwang): Connect to mojo audio decoder service and pass it here. + audio_decoders->push_back(new media::MojoAudioDecoder()); +} + +} // namespace media diff --git a/media/mojo/services/mojo_decoder_factory.h b/media/mojo/services/mojo_decoder_factory.h new file mode 100644 index 0000000..e45bbe7 --- /dev/null +++ b/media/mojo/services/mojo_decoder_factory.h @@ -0,0 +1,34 @@ +// 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 MEDIA_MOJO_SERVICES_MOJO_DECODER_FACTORY_H_ +#define MEDIA_MOJO_SERVICES_MOJO_DECODER_FACTORY_H_ + +#include "base/macros.h" +#include "media/base/decoder_factory.h" + +namespace media { + +namespace interfaces { +class ServiceFactory; +} + +class MojoDecoderFactory : public DecoderFactory { + public: + explicit MojoDecoderFactory(interfaces::ServiceFactory* service_factory); + ~MojoDecoderFactory() final; + + void CreateAudioDecoders(ScopedVector<AudioDecoder>* audio_decoders) final; + + // TODO(xhwang): Add video decoder support if needed. + + private: + interfaces::ServiceFactory* service_factory_; + + DISALLOW_COPY_AND_ASSIGN(MojoDecoderFactory); +}; + +} // namespace media + +#endif // MEDIA_MOJO_SERVICES_MOJO_DECODER_FACTORY_H_ diff --git a/media/mojo/services/test_mojo_media_client.cc b/media/mojo/services/test_mojo_media_client.cc index b1ea14d..994bc7e 100644 --- a/media/mojo/services/test_mojo_media_client.cc +++ b/media/mojo/services/test_mojo_media_client.cc @@ -40,8 +40,8 @@ void TestMojoMediaClient::Initialize() { scoped_ptr<RendererFactory> TestMojoMediaClient::CreateRendererFactory( const scoped_refptr<MediaLog>& media_log) { DVLOG(1) << __FUNCTION__; - return make_scoped_ptr( - new DefaultRendererFactory(media_log, nullptr, *audio_hardware_config_)); + return make_scoped_ptr(new DefaultRendererFactory(media_log, nullptr, nullptr, + *audio_hardware_config_)); } AudioRendererSink* TestMojoMediaClient::CreateAudioRendererSink() { diff --git a/media/renderers/default_renderer_factory.cc b/media/renderers/default_renderer_factory.cc index ff5956e..d63b232 100644 --- a/media/renderers/default_renderer_factory.cc +++ b/media/renderers/default_renderer_factory.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/single_thread_task_runner.h" #include "build/build_config.h" +#include "media/base/decoder_factory.h" #include "media/base/media_log.h" #include "media/filters/gpu_video_decoder.h" #include "media/filters/opus_audio_decoder.h" @@ -32,23 +33,19 @@ namespace media { DefaultRendererFactory::DefaultRendererFactory( const scoped_refptr<MediaLog>& media_log, + DecoderFactory* decoder_factory, GpuVideoAcceleratorFactories* gpu_factories, const AudioHardwareConfig& audio_hardware_config) : media_log_(media_log), + decoder_factory_(decoder_factory), gpu_factories_(gpu_factories), audio_hardware_config_(audio_hardware_config) {} DefaultRendererFactory::~DefaultRendererFactory() { } -scoped_ptr<Renderer> DefaultRendererFactory::CreateRenderer( - const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, - const scoped_refptr<base::TaskRunner>& worker_task_runner, - AudioRendererSink* audio_renderer_sink, - VideoRendererSink* video_renderer_sink, - const RequestSurfaceCB& request_surface_cb) { - DCHECK(audio_renderer_sink); - +ScopedVector<AudioDecoder> DefaultRendererFactory::CreateAudioDecoders( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner) { // Create our audio decoders and renderer. ScopedVector<AudioDecoder> audio_decoders; @@ -59,10 +56,15 @@ scoped_ptr<Renderer> DefaultRendererFactory::CreateRenderer( audio_decoders.push_back(new OpusAudioDecoder(media_task_runner)); - scoped_ptr<AudioRenderer> audio_renderer(new AudioRendererImpl( - media_task_runner, audio_renderer_sink, std::move(audio_decoders), - audio_hardware_config_, media_log_)); + if (decoder_factory_) + decoder_factory_->CreateAudioDecoders(&audio_decoders); + + return audio_decoders; +} +ScopedVector<VideoDecoder> DefaultRendererFactory::CreateVideoDecoders( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, + const RequestSurfaceCB& request_surface_cb) { // Create our video decoders and renderer. ScopedVector<VideoDecoder> video_decoders; @@ -84,11 +86,30 @@ scoped_ptr<Renderer> DefaultRendererFactory::CreateRenderer( video_decoders.push_back(new FFmpegVideoDecoder()); #endif + if (decoder_factory_) + decoder_factory_->CreateVideoDecoders(&video_decoders); + + return video_decoders; +} + +scoped_ptr<Renderer> DefaultRendererFactory::CreateRenderer( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, + const scoped_refptr<base::TaskRunner>& worker_task_runner, + AudioRendererSink* audio_renderer_sink, + VideoRendererSink* video_renderer_sink, + const RequestSurfaceCB& request_surface_cb) { + DCHECK(audio_renderer_sink); + + scoped_ptr<AudioRenderer> audio_renderer( + new AudioRendererImpl(media_task_runner, audio_renderer_sink, + CreateAudioDecoders(media_task_runner), + audio_hardware_config_, media_log_)); + scoped_ptr<VideoRenderer> video_renderer(new VideoRendererImpl( media_task_runner, worker_task_runner, video_renderer_sink, - std::move(video_decoders), true, gpu_factories_, media_log_)); + CreateVideoDecoders(media_task_runner, request_surface_cb), true, + gpu_factories_, media_log_)); - // Create renderer. return scoped_ptr<Renderer>(new RendererImpl( media_task_runner, std::move(audio_renderer), std::move(video_renderer))); } diff --git a/media/renderers/default_renderer_factory.h b/media/renderers/default_renderer_factory.h index 4a56c5d..4412316 100644 --- a/media/renderers/default_renderer_factory.h +++ b/media/renderers/default_renderer_factory.h @@ -7,21 +7,26 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/scoped_vector.h" #include "media/base/media_export.h" #include "media/base/renderer_factory.h" namespace media { +class AudioDecoder; class AudioHardwareConfig; class AudioRendererSink; +class DecoderFactory; class GpuVideoAcceleratorFactories; class MediaLog; +class VideoDecoder; class VideoRendererSink; // The default factory class for creating RendererImpl. class MEDIA_EXPORT DefaultRendererFactory : public RendererFactory { public: DefaultRendererFactory(const scoped_refptr<MediaLog>& media_log, + DecoderFactory* decoder_factory, GpuVideoAcceleratorFactories* gpu_factories, const AudioHardwareConfig& audio_hardware_config); ~DefaultRendererFactory() final; @@ -34,8 +39,18 @@ class MEDIA_EXPORT DefaultRendererFactory : public RendererFactory { const RequestSurfaceCB& request_surface_cb) final; private: + ScopedVector<AudioDecoder> CreateAudioDecoders( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner); + ScopedVector<VideoDecoder> CreateVideoDecoders( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, + const RequestSurfaceCB& request_surface_cb); + scoped_refptr<MediaLog> media_log_; + // Factory to create extra audio and video decoders. + // Could be nullptr if not extra decoders are available. + DecoderFactory* decoder_factory_; + // Factories for supporting video accelerators. May be null. GpuVideoAcceleratorFactories* gpu_factories_; |