summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxhwang <xhwang@chromium.org>2016-02-22 16:52:44 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-23 00:54:53 +0000
commit409e5355ae1269cde51dc5b73b4592bad4e8c2ea (patch)
treefcb18200e016245e50ac64833c12ac6031649a82
parentfa8b941eb242bc26430d1053d771c624bb45ea10 (diff)
downloadchromium_src-409e5355ae1269cde51dc5b73b4592bad4e8c2ea.zip
chromium_src-409e5355ae1269cde51dc5b73b4592bad4e8c2ea.tar.gz
chromium_src-409e5355ae1269cde51dc5b73b4592bad4e8c2ea.tar.bz2
media: Support MojoAudioDecoder.
Details: - Support mojo audio decoder in gn args. - Add DecoderFactory to help create external decoders. - Add MojoDecoderFactory that can create MojoAudioDecoder. - When mojo audio decoder is enabled, enable MojoDecoderFactory. In the next CL we'll add mojo audio decoder interface and services. We'll also add real implementation of MojoAudioDecoder. To test this on Desktop, set the following gn arguments: enable_mojo_media = true mojo_media_services = [ "audio_decoder" ] Then in DecoderSelector, manually disable DecryptingAudioDecoder and DecryptingDemuxerStream. Now try to play an encrypted audio, MojoAudioDecoder should be selected. But it'll fail immediately in the first Decode() call. BUG=542910 TEST=See above. Review URL: https://codereview.chromium.org/1717933002 Cr-Commit-Position: refs/heads/master@{#376878}
-rw-r--r--content/renderer/render_frame_impl.cc17
-rw-r--r--content/renderer/render_frame_impl.h5
-rw-r--r--media/base/BUILD.gn2
-rw-r--r--media/base/decoder_factory.cc19
-rw-r--r--media/base/decoder_factory.h35
-rw-r--r--media/media.gyp2
-rw-r--r--media/media_options.gni9
-rw-r--r--media/mojo/services/BUILD.gn6
-rw-r--r--media/mojo/services/mojo_audio_decoder.cc60
-rw-r--r--media/mojo/services/mojo_audio_decoder.h43
-rw-r--r--media/mojo/services/mojo_decoder_factory.cc26
-rw-r--r--media/mojo/services/mojo_decoder_factory.h34
-rw-r--r--media/mojo/services/test_mojo_media_client.cc4
-rw-r--r--media/renderers/default_renderer_factory.cc47
-rw-r--r--media/renderers/default_renderer_factory.h15
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_;