Skip to content

Commit

Permalink
media: Support MojoRendererService in the browser process.
Browse files Browse the repository at this point in the history
On some platforms, we run part of the media pipeline in the browser process. For example, on ChromeCast and on Android,  audio/video buffers are decoded in the browser process. Currently, there are some ad-hoc IPC mechanism implemented for these platforms to support hosting  the decoders in the browser process. This CL aims at providing a common mojo based path to support this scenario.

This CL makes it possible to host a mojo::MeidaRenderer service in the browser process. By default, it's using media::RendererImpl and some default audio/video decoders. In later CLs, I'll update this so that we can support embedder specific media::Renderer implementation in MojoRendererService.

Note that media playback is NOT working yet due to DataPipe is not working out-of-process.

Test steps:
1, Change "enable_media_mojo_renderer" to true in media/media_options.gni.
2, Build a GN build of Chrome.
3, Play <video> in Chrome.

BUG=431776
TEST=See above test steps.

Review URL: https://codereview.chromium.org/712463004

Cr-Commit-Position: refs/heads/master@{#313463}
  • Loading branch information
xhwang-chromium authored and Commit bot committed Jan 28, 2015
1 parent df01d14 commit e611733
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 7 deletions.
4 changes: 4 additions & 0 deletions content/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -442,4 +442,8 @@ source_set("browser") {
if (is_linux && use_openssl) {
deps += [ "//third_party/boringssl" ]
}

if (enable_media_mojo_renderer) {
deps += [ "//media/mojo/services:renderer_service" ]
}
}
1 change: 1 addition & 0 deletions content/browser/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ include_rules = [
"+media/base", # For Android JNI registration.
"+media/filters", # For reporting GPU decoding UMA.
"+media/midi", # For Web MIDI API
"+media/mojo", # For mojo media services.
"+media/video", # For Video Device monitoring in Mac.
"+mojo",
"+sql",
Expand Down
18 changes: 18 additions & 0 deletions content/browser/frame_host/render_frame_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@
#include "content/browser/frame_host/popup_menu_helper_mac.h"
#endif

#if defined(ENABLE_MEDIA_MOJO_RENDERER)
#include "media/mojo/interfaces/media_renderer.mojom.h"
#include "media/mojo/services/mojo_renderer_service.h"
#endif

using base::TimeDelta;

namespace content {
Expand Down Expand Up @@ -1274,6 +1279,14 @@ void RenderFrameHostImpl::OnHidePopup() {
}
#endif

#if defined(ENABLE_MEDIA_MOJO_RENDERER)
static void CreateMediaRendererService(
mojo::InterfaceRequest<mojo::MediaRenderer> request) {
media::MojoRendererService* service = new media::MojoRendererService();
mojo::BindToRequest(service, &request);
}
#endif

void RenderFrameHostImpl::RegisterMojoServices() {
GeolocationServiceContext* geolocation_service_context =
delegate_ ? delegate_->GetGeolocationServiceContext() : NULL;
Expand All @@ -1294,6 +1307,11 @@ void RenderFrameHostImpl::RegisterMojoServices() {
GetServiceRegistry()->AddService<PermissionService>(
base::Bind(&PermissionServiceContext::CreateService,
base::Unretained(permission_service_context_.get())));

#if defined(ENABLE_MEDIA_MOJO_RENDERER)
GetServiceRegistry()->AddService<mojo::MediaRenderer>(
base::Bind(&CreateMediaRendererService));
#endif
}

void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) {
Expand Down
8 changes: 8 additions & 0 deletions content/renderer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,12 @@ source_set("renderer") {
"media/crypto/renderer_cdm_manager.h",
]
}

if (enable_media_mojo_renderer) {
sources += [
"media/media_renderer_service_provider.cc",
"media/media_renderer_service_provider.h",
]
deps += [ "//media/mojo/services:renderer_proxy" ]
}
}
23 changes: 23 additions & 0 deletions content/renderer/media/media_renderer_service_provider.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2014 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 "content/public/common/service_registry.h"
#include "content/renderer/media/media_renderer_service_provider.h"

namespace content {

MediaRendererServiceProvider::MediaRendererServiceProvider(
ServiceRegistry* service_registry)
: service_registry_(service_registry) {
}

MediaRendererServiceProvider::~MediaRendererServiceProvider() {
}

void MediaRendererServiceProvider::ConnectToService(
mojo::InterfacePtr<mojo::MediaRenderer>* media_renderer_ptr) {
service_registry_->ConnectToRemoteService(media_renderer_ptr);
}

} // namespace content
35 changes: 35 additions & 0 deletions content/renderer/media/media_renderer_service_provider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2014 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 CONTENT_RENDERER_MEDIA_MEDIA_RENDERER_SERVICE_PROVIDER_H_
#define CONTENT_RENDERER_MEDIA_MEDIA_RENDERER_SERVICE_PROVIDER_H_

#include "base/macros.h"
#include "content/common/content_export.h"
#include "media/mojo/services/mojo_renderer_factory.h"

namespace content {

class ServiceRegistry;

// ServiceRegistry based media::MojoRendererFactory::ServiceProvider
// implementation.
class CONTENT_EXPORT MediaRendererServiceProvider
: public media::MojoRendererFactory::ServiceProvider {
public:
explicit MediaRendererServiceProvider(ServiceRegistry* service_registry);
~MediaRendererServiceProvider() final;

void ConnectToService(
mojo::InterfacePtr<mojo::MediaRenderer>* media_renderer_ptr) final;

private:
ServiceRegistry* service_registry_;

DISALLOW_COPY_AND_ASSIGN(MediaRendererServiceProvider);
};

} // namespace content

#endif // CONTENT_RENDERER_MEDIA_MEDIA_RENDERER_SERVICE_PROVIDER_H_
16 changes: 14 additions & 2 deletions content/renderer/render_frame_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
#include "media/blink/webencryptedmediaclient_impl.h"
#include "media/blink/webmediaplayer_impl.h"
#include "media/blink/webmediaplayer_params.h"
#include "media/filters/default_renderer_factory.h"
#include "media/filters/gpu_video_accelerator_factories.h"
#include "net/base/data_url.h"
#include "net/base/net_errors.h"
Expand Down Expand Up @@ -166,6 +165,13 @@
#include "content/renderer/media/crypto/renderer_cdm_manager.h"
#endif

#if defined(ENABLE_MEDIA_MOJO_RENDERER)
#include "content/renderer/media/media_renderer_service_provider.h"
#include "media/mojo/services/mojo_renderer_factory.h"
#else
#include "media/filters/default_renderer_factory.h"
#endif

using blink::WebContextMenuData;
using blink::WebData;
using blink::WebDataSource;
Expand Down Expand Up @@ -1875,7 +1881,7 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
blink::WebLocalFrame* frame,
const blink::WebURL& url,
blink::WebMediaPlayerClient* client) {
return createMediaPlayer(frame, url, client, NULL);
return createMediaPlayer(frame, url, client, nullptr);
}

blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
Expand Down Expand Up @@ -1921,6 +1927,11 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
scoped_ptr<media::CdmFactory> cdm_factory(new RenderCdmFactory());
#endif

#if defined(ENABLE_MEDIA_MOJO_RENDERER)
scoped_ptr<media::RendererFactory> media_renderer_factory(
new media::MojoRendererFactory(make_scoped_ptr(
new MediaRendererServiceProvider(GetServiceRegistry()))));
#else
scoped_ptr<media::RendererFactory> media_renderer_factory =
GetContentClient()->renderer()->CreateMediaRendererFactory(this);

Expand All @@ -1929,6 +1940,7 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
media_log, render_thread->GetGpuFactories(),
*render_thread->GetAudioHardwareConfig()));
}
#endif // defined(ENABLE_MEDIA_MOJO_RENDERER)

return new media::WebMediaPlayerImpl(
frame, client, weak_factory_.GetWeakPtr(), media_renderer_factory.Pass(),
Expand Down
7 changes: 5 additions & 2 deletions media/media_options.gni
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ declare_args() {
# default since it's not available on the normal Web Platform and costs money.
enable_mpeg2ts_stream_parser = false

# Enables browser side Content Decryption Modules. Required for android where
# the typical PPAPI based CDM is not available.
# Enables browser side Content Decryption Modules. Required for embedders
# (e.g. Android and ChromeCast) that use a browser side CDM.
enable_browser_cdms = is_android

# Experiment to enable mojo based media renderer: http://crbug.com/431776
enable_media_mojo_renderer = false

# TODO(GYP): This should be a platform define.
is_openbsd = false
}
13 changes: 11 additions & 2 deletions media/mojo/services/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//media/media_options.gni")
import("//testing/test.gni")
import("//third_party/mojo/src/mojo/public/mojo_application.gni")

Expand All @@ -12,6 +13,12 @@ import("//third_party/mojo/src/mojo/public/mojo_application.gni")
# - unittests: Unit tests for a particular class/file.
# - test: Tests for a particular app, e.g. media.

config("enable_media_mojo_renderer_config") {
if (enable_media_mojo_renderer) {
defines = [ "ENABLE_MEDIA_MOJO_RENDERER" ]
}
}

source_set("converters") {
sources = [
"media_type_converters.cc",
Expand Down Expand Up @@ -41,7 +48,6 @@ source_set("cdm_proxy") {
"//mojo/environment:chromium",
"//third_party/mojo/src/mojo/public/interfaces/application",
"//third_party/mojo/src/mojo/public/c/system:for_component",
"//third_party/mojo/src/mojo/public/cpp/application",
]

sources = [
Expand Down Expand Up @@ -83,6 +89,8 @@ source_set("renderer_proxy") {
"mojo_renderer_impl.h",
]

public_configs = [ ":enable_media_mojo_renderer_config" ]

deps = [
":converters",
"//base",
Expand All @@ -91,7 +99,6 @@ source_set("renderer_proxy") {
"//mojo/common",
"//mojo/environment:chromium",
"//third_party/mojo/src/mojo/public/c/system:for_component",
"//third_party/mojo/src/mojo/public/cpp/application",
"//third_party/mojo/src/mojo/public/interfaces/application",
]
}
Expand Down Expand Up @@ -125,6 +132,8 @@ source_set("renderer_service") {
"renderer_config_default.cc",
]

public_configs = [ ":enable_media_mojo_renderer_config" ]

deps = [
":renderer_service_generic",
"//base",
Expand Down
5 changes: 4 additions & 1 deletion media/mojo/services/mojo_renderer_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
#define MEDIA_MOJO_SERVICES_MOJO_RENDERER_SERVICE_H_

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/buffering_state.h"
#include "media/base/media_export.h"
#include "media/base/pipeline_status.h"
#include "media/mojo/interfaces/media_renderer.mojom.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_impl.h"
Expand All @@ -29,7 +31,8 @@ class Renderer;

// A mojo::MediaRenderer implementation that uses media::AudioRenderer to
// decode and render audio to a sink obtained from the ApplicationConnection.
class MojoRendererService : public mojo::InterfaceImpl<mojo::MediaRenderer> {
class MEDIA_EXPORT MojoRendererService
: NON_EXPORTED_BASE(public mojo::InterfaceImpl<mojo::MediaRenderer>) {
public:
MojoRendererService();
~MojoRendererService() override;
Expand Down

0 comments on commit e611733

Please sign in to comment.