Commit 88a40008 authored by Chris Watkins's avatar Chris Watkins Committed by Commit Bot

media: Enable the use of MojoAndroidOverlays from the media service

Previously MojoAndroidOverlays could only be created on the GPU main
thread. Now we can create them on any thread, and specifically the media
service thread, so that MediaCodecVideoDecoder can use them.

Also, they now embed an optional ServiceContextRef so that if they're
used from the media service, they can extend the lifetime of the thread
their mojo interface is bound to. This is necessary because they will
be jointly owned by both MCVD and CodecImages. 

Bug: 660942
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I6497b81eeb7205a4893ef6c4de4ee5af571ac90a
Reviewed-on: https://chromium-review.googlesource.com/684005Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Commit-Queue: Chris Watkins <watk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504854}
parent 2fc2c6ca
......@@ -185,8 +185,7 @@ GpuChildThread::GpuChildThread(
gpu_service_->set_in_host_process(in_browser_process_);
}
GpuChildThread::~GpuChildThread() {
}
GpuChildThread::~GpuChildThread() {}
void GpuChildThread::Init(const base::Time& process_start_time) {
gpu_service_->set_start_time(process_start_time);
......@@ -272,15 +271,19 @@ void GpuChildThread::CreateGpuService(
sync_point_manager, ChildProcess::current()->GetShutDownEvent());
CHECK(gpu_service_->media_gpu_channel_manager());
// Only set once per process instance.
service_factory_.reset(new GpuServiceFactory(
gpu_service_->media_gpu_channel_manager()->AsWeakPtr()));
media::AndroidOverlayMojoFactoryCB overlay_factory_cb;
#if defined(OS_ANDROID)
overlay_factory_cb = base::Bind(&GpuChildThread::CreateAndroidOverlay,
base::ThreadTaskRunnerHandle::Get());
gpu_service_->media_gpu_channel_manager()->SetOverlayFactory(
base::Bind(&GpuChildThread::CreateAndroidOverlay));
overlay_factory_cb);
#endif
// Only set once per process instance.
service_factory_.reset(new GpuServiceFactory(
gpu_service_->media_gpu_channel_manager()->AsWeakPtr(),
overlay_factory_cb));
if (GetContentClient()->gpu()) // NULL in tests.
GetContentClient()->gpu()->GpuServiceInitialized(gpu_preferences);
......@@ -304,13 +307,32 @@ void GpuChildThread::BindServiceFactoryRequest(
#if defined(OS_ANDROID)
// static
std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
std::unique_ptr<service_manager::ServiceContextRef> context_ref,
const base::UnguessableToken& routing_token,
media::AndroidOverlayConfig config) {
media::mojom::AndroidOverlayProviderPtr provider_ptr;
ChildThread::Get()->GetConnector()->BindInterface(
content::mojom::kBrowserServiceName, &provider_ptr);
media::mojom::AndroidOverlayProviderPtr overlay_provider;
if (main_task_runner->RunsTasksInCurrentSequence()) {
ChildThread::Get()->GetConnector()->BindInterface(
content::mojom::kBrowserServiceName, &overlay_provider);
} else {
// Create a connector on this sequence and bind it on the main thread.
service_manager::mojom::ConnectorRequest request;
auto connector = service_manager::Connector::Create(&request);
connector->BindInterface(content::mojom::kBrowserServiceName,
&overlay_provider);
auto bind_connector_request =
[](service_manager::mojom::ConnectorRequest request) {
ChildThread::Get()->GetConnector()->BindConnectorRequest(
std::move(request));
};
main_task_runner->PostTask(
FROM_HERE, base::BindOnce(bind_connector_request, std::move(request)));
}
return base::MakeUnique<media::MojoAndroidOverlay>(
std::move(provider_ptr), std::move(config), routing_token);
std::move(overlay_provider), std::move(config), routing_token,
std::move(context_ref));
}
#endif
......
......@@ -32,6 +32,7 @@
#include "media/base/android_overlay_mojo_factory.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/service_context_ref.h"
#include "services/service_manager/public/interfaces/service_factory.mojom.h"
#include "services/ui/gpu/interfaces/gpu_main.mojom.h"
#include "ui/gfx/native_widget_types.h"
......@@ -106,6 +107,8 @@ class GpuChildThread : public ChildThreadImpl, public ui::mojom::GpuMain {
#if defined(OS_ANDROID)
static std::unique_ptr<media::AndroidOverlay> CreateAndroidOverlay(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
std::unique_ptr<service_manager::ServiceContextRef> context_ref,
const base::UnguessableToken& routing_token,
media::AndroidOverlayConfig);
#endif
......
......@@ -18,10 +18,12 @@
namespace content {
GpuServiceFactory::GpuServiceFactory(
base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager) {
base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager,
media::AndroidOverlayMojoFactoryCB android_overlay_factory_cb) {
#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
task_runner_ = base::ThreadTaskRunnerHandle::Get();
media_gpu_channel_manager_ = std::move(media_gpu_channel_manager);
android_overlay_factory_cb_ = std::move(android_overlay_factory_cb);
#endif
}
......@@ -30,8 +32,9 @@ GpuServiceFactory::~GpuServiceFactory() {}
void GpuServiceFactory::RegisterServices(ServiceMap* services) {
#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
service_manager::EmbeddedServiceInfo info;
info.factory = base::Bind(&media::CreateGpuMediaService, task_runner_,
media_gpu_channel_manager_);
info.factory =
base::Bind(&media::CreateGpuMediaService, task_runner_,
media_gpu_channel_manager_, android_overlay_factory_cb_);
info.use_own_thread = true;
services->insert(std::make_pair("media", info));
#endif
......
......@@ -10,6 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "content/child/service_factory.h"
#include "media/base/android_overlay_mojo_factory.h"
#include "media/mojo/features.h"
namespace media {
......@@ -21,8 +22,9 @@ namespace content {
// Customization of ServiceFactory for the GPU process.
class GpuServiceFactory : public ServiceFactory {
public:
explicit GpuServiceFactory(
base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager);
GpuServiceFactory(
base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager,
media::AndroidOverlayMojoFactoryCB android_overlay_factory_cb);
~GpuServiceFactory() override;
// ServiceFactory overrides:
......@@ -36,6 +38,7 @@ class GpuServiceFactory : public ServiceFactory {
// implementation doesn't care.
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager_;
media::AndroidOverlayMojoFactoryCB android_overlay_factory_cb_;
#endif
DISALLOW_COPY_AND_ASSIGN(GpuServiceFactory);
......
......@@ -10,11 +10,18 @@
#include "base/unguessable_token.h"
#include "media/base/android_overlay_config.h"
namespace service_manager {
class ServiceContextRef;
}
namespace media {
// Note that this compiles on non-android too.
using AndroidOverlayMojoFactoryCB = base::RepeatingCallback<std::unique_ptr<
AndroidOverlay>(const base::UnguessableToken&, AndroidOverlayConfig)>;
using AndroidOverlayMojoFactoryCB =
base::RepeatingCallback<std::unique_ptr<AndroidOverlay>(
std::unique_ptr<service_manager::ServiceContextRef>,
const base::UnguessableToken&,
AndroidOverlayConfig)>;
} // namespace media
......
......@@ -44,6 +44,7 @@
#include "media/gpu/shared_memory_region.h"
#include "media/mojo/features.h"
#include "media/video/picture.h"
#include "services/service_manager/public/cpp/service_context_ref.h"
#include "ui/gl/android/scoped_java_surface.h"
#include "ui/gl/android/surface_texture.h"
#include "ui/gl/gl_bindings.h"
......@@ -441,8 +442,8 @@ void AndroidVideoDecodeAccelerator::StartSurfaceChooser() {
config_.overlay_info.surface_id);
} else if (config_.overlay_info.HasValidRoutingToken() &&
overlay_factory_cb_) {
factory =
base::Bind(overlay_factory_cb_, *config_.overlay_info.routing_token);
factory = base::Bind(overlay_factory_cb_, nullptr,
*config_.overlay_info.routing_token);
}
// Notify |surface_chooser_| that we've started. This guarantees that we'll
......@@ -1342,7 +1343,7 @@ void AndroidVideoDecodeAccelerator::SetOverlayInfo(
if (surface_id != previous_info.surface_id ||
routing_token != previous_info.routing_token) {
if (routing_token && overlay_factory_cb_)
new_factory = base::Bind(overlay_factory_cb_, *routing_token);
new_factory = base::Bind(overlay_factory_cb_, nullptr, *routing_token);
else if (surface_id != SurfaceManager::kNoSurfaceID)
new_factory = base::Bind(&ContentVideoViewOverlay::Create, surface_id);
}
......
......@@ -637,10 +637,22 @@ void MediaCodecVideoDecoder::ReleaseCodec() {
AndroidOverlayFactoryCB MediaCodecVideoDecoder::CreateOverlayFactoryCb() {
DCHECK(!overlay_info_.HasValidSurfaceId());
if (overlay_info_.HasValidRoutingToken() && overlay_factory_cb_) {
return base::Bind(overlay_factory_cb_, *overlay_info_.routing_token);
}
return AndroidOverlayFactoryCB();
if (!overlay_factory_cb_ || !overlay_info_.HasValidRoutingToken())
return AndroidOverlayFactoryCB();
// This wrapper forwards its arguments and clones a context ref on each call.
auto wrapper = [](AndroidOverlayMojoFactoryCB overlay_factory_cb,
service_manager::ServiceContextRef* context_ref,
base::UnguessableToken routing_token,
AndroidOverlayConfig config) {
return overlay_factory_cb.Run(context_ref->Clone(),
std::move(routing_token), std::move(config));
};
// Pass ownership of a new context ref into the callback.
return base::Bind(wrapper, overlay_factory_cb_,
base::Owned(context_ref_->Clone().release()),
*overlay_info_.routing_token);
}
std::string MediaCodecVideoDecoder::GetDisplayName() const {
......
......@@ -38,6 +38,7 @@ void OutputWithReleaseMailboxCb(VideoFrameFactory::ReleaseMailboxCB,
void RequestOverlayInfoCb(bool, const ProvideOverlayInfoCB&) {}
std::unique_ptr<AndroidOverlay> CreateAndroidOverlayCb(
std::unique_ptr<service_manager::ServiceContextRef>,
const base::UnguessableToken&,
AndroidOverlayConfig) {
return nullptr;
......@@ -53,6 +54,13 @@ struct DestructionObservableMCVD : public DestructionObservable,
using MediaCodecVideoDecoder::MediaCodecVideoDecoder;
};
class MockServiceContextRef : public service_manager::ServiceContextRef {
public:
std::unique_ptr<ServiceContextRef> Clone() override {
return base::MakeUnique<MockServiceContextRef>();
}
};
} // namespace
class MockVideoFrameFactory : public VideoFrameFactory {
......@@ -109,7 +117,8 @@ class MediaCodecVideoDecoderTest : public testing::Test {
base::Bind(&OutputWithReleaseMailboxCb), device_info_.get(),
codec_allocator_.get(), std::move(surface_chooser),
base::Bind(&CreateAndroidOverlayCb), base::Bind(&RequestOverlayInfoCb),
std::move(video_frame_factory), nullptr);
std::move(video_frame_factory),
base::MakeUnique<MockServiceContextRef>());
mcvd_.reset(observable_mcvd);
mcvd_raw_ = observable_mcvd;
destruction_observer_ = observable_mcvd->CreateDestructionObserver();
......
......@@ -12,8 +12,11 @@ namespace media {
MojoAndroidOverlay::MojoAndroidOverlay(
mojom::AndroidOverlayProviderPtr provider_ptr,
AndroidOverlayConfig config,
const base::UnguessableToken& routing_token)
: config_(std::move(config)), binding_(this) {
const base::UnguessableToken& routing_token,
std::unique_ptr<service_manager::ServiceContextRef> context_ref)
: config_(std::move(config)),
binding_(this),
context_ref_(std::move(context_ref)) {
// Fill in details of |config| into |mojo_config|. Our caller could do this
// too, but since we want to retain |config_| anyway, we do it here.
mojom::AndroidOverlayConfigPtr mojo_config =
......
......@@ -10,6 +10,7 @@
#include "media/base/android/android_overlay.h"
#include "media/mojo/interfaces/android_overlay.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/service_context_ref.h"
namespace media {
......@@ -17,9 +18,12 @@ namespace media {
class MojoAndroidOverlay : public AndroidOverlay,
public mojom::AndroidOverlayClient {
public:
MojoAndroidOverlay(mojom::AndroidOverlayProviderPtr provider_ptr,
AndroidOverlayConfig config,
const base::UnguessableToken& routing_token);
// |context_ref| may be null.
MojoAndroidOverlay(
mojom::AndroidOverlayProviderPtr provider_ptr,
AndroidOverlayConfig config,
const base::UnguessableToken& routing_token,
std::unique_ptr<service_manager::ServiceContextRef> context_ref);
~MojoAndroidOverlay() override;
......@@ -37,6 +41,7 @@ class MojoAndroidOverlay : public AndroidOverlay,
mojom::AndroidOverlayPtr overlay_ptr_;
mojo::Binding<mojom::AndroidOverlayClient> binding_;
gl::ScopedJavaSurface surface_;
std::unique_ptr<service_manager::ServiceContextRef> context_ref_;
// Have we received OnSurfaceReady yet?
bool received_surface_ = false;
......
......@@ -20,8 +20,8 @@
#include "ui/gl/android/scoped_java_surface.h"
#include "ui/gl/android/surface_texture.h"
using ::testing::_;
using ::testing::StrictMock;
using ::testing::_;
namespace media {
......@@ -111,7 +111,7 @@ class MojoAndroidOverlayTest : public ::testing::Test {
provider_binding_.Bind(mojo::MakeRequest(&provider_ptr));
overlay_client_.reset(new MojoAndroidOverlay(
std::move(provider_ptr), std::move(config_), routing_token));
std::move(provider_ptr), std::move(config_), routing_token, nullptr));
overlay_client_->AddSurfaceDestroyedCallback(base::Bind(
&MockClientCallbacks::OnDestroyed, base::Unretained(&callbacks_)));
base::RunLoop().RunUntilIdle();
......
......@@ -69,18 +69,6 @@ gpu::GpuCommandBufferStub* GetGpuCommandBufferStub(
return channel->LookupCommandBuffer(route_id);
}
std::unique_ptr<AndroidOverlay> CreateAndroidOverlay(
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager,
const base::UnguessableToken& routing_token,
media::AndroidOverlayConfig config) {
if (!media_gpu_channel_manager)
return nullptr;
AndroidOverlayMojoFactoryCB factory_cb =
media_gpu_channel_manager->GetOverlayFactory();
DCHECK(factory_cb);
return factory_cb.Run(routing_token, std::move(config));
}
#endif // BUILDFLAG(ENABLE_MEDIA_CODEC_VIDEO_DECODER)
#endif // defined(OS_ANDROID)
......@@ -88,9 +76,11 @@ std::unique_ptr<AndroidOverlay> CreateAndroidOverlay(
GpuMojoMediaClient::GpuMojoMediaClient(
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager)
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager,
AndroidOverlayMojoFactoryCB android_overlay_factory_cb)
: gpu_task_runner_(std::move(gpu_task_runner)),
media_gpu_channel_manager_(std::move(media_gpu_channel_manager)) {}
media_gpu_channel_manager_(std::move(media_gpu_channel_manager)),
android_overlay_factory_cb_(std::move(android_overlay_factory_cb)) {}
GpuMojoMediaClient::~GpuMojoMediaClient() {}
......@@ -125,8 +115,7 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
AVDACodecAllocator::GetInstance(),
base::MakeUnique<AndroidVideoSurfaceChooserImpl>(
DeviceInfo::GetInstance()->IsSetOutputSurfaceSupported()),
base::Bind(&CreateAndroidOverlay, media_gpu_channel_manager_),
std::move(request_overlay_info_cb),
android_overlay_factory_cb_, std::move(request_overlay_info_cb),
base::MakeUnique<VideoFrameFactoryImpl>(),
context_ref_factory_->CreateRef());
#else
......
......@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "media/base/android_overlay_mojo_factory.h"
#include "media/mojo/services/mojo_media_client.h"
namespace media {
......@@ -23,7 +24,8 @@ class GpuMojoMediaClient : public MojoMediaClient {
// is expected to be the GPU main thread task runner.
GpuMojoMediaClient(
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager);
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager,
AndroidOverlayMojoFactoryCB android_overlay_factory_cb);
~GpuMojoMediaClient() final;
// MojoMediaClient implementation.
......@@ -45,6 +47,7 @@ class GpuMojoMediaClient : public MojoMediaClient {
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_;
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager_;
service_manager::ServiceContextRefFactory* context_ref_factory_;
AndroidOverlayMojoFactoryCB android_overlay_factory_cb_;
DISALLOW_COPY_AND_ASSIGN(GpuMojoMediaClient);
};
......
......@@ -30,10 +30,12 @@ std::unique_ptr<service_manager::Service> CreateMediaService() {
std::unique_ptr<service_manager::Service> CreateGpuMediaService(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager) {
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager,
AndroidOverlayMojoFactoryCB android_overlay_factory_cb) {
return std::unique_ptr<service_manager::Service>(
new MediaService(base::MakeUnique<GpuMojoMediaClient>(
task_runner, media_gpu_channel_manager)));
task_runner, media_gpu_channel_manager,
std::move(android_overlay_factory_cb))));
}
std::unique_ptr<service_manager::Service> CreateMediaServiceForTesting() {
......
......@@ -10,6 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "media/base/android_overlay_mojo_factory.h"
#include "media/mojo/services/media_mojo_export.h"
#include "services/service_manager/public/cpp/service.h"
......@@ -29,7 +30,8 @@ CreateMediaService();
std::unique_ptr<service_manager::Service> MEDIA_MOJO_EXPORT
CreateGpuMediaService(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager);
base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager,
AndroidOverlayMojoFactoryCB android_overlay_factory_cb);
// Creates a MediaService instance using the TestMojoMediaClient.
std::unique_ptr<service_manager::Service> MEDIA_MOJO_EXPORT
......
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