Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy VideoGeometrySetter Service for Cobalt #4836

Merged
merged 1 commit into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions cobalt/media/service/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2015 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//chromecast/chromecast.gni")

cast_source_set("service") {
sources = [
"cast_mojo_media_client.cc",
"cast_mojo_media_client.h",
"cast_renderer.cc",
"cast_renderer.h",
"video_geometry_setter_service.cc",
"video_geometry_setter_service.h",
]

public_deps = [
"//media/mojo/mojom",
"//media/mojo/services",
"//services/service_manager/public/cpp",
]

deps = [
"//base",
"//chromecast/base",
"//chromecast/common/mojom",
"//chromecast/external_mojo/external_service_support:external_service",
"//chromecast/media",
"//chromecast/media/service/mojom",
"//media",
"//ui/gfx",
"//ui/gfx/geometry",
]
}
15 changes: 15 additions & 0 deletions cobalt/media/service/mojom/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//mojo/public/tools/bindings/mojom.gni")

mojom("mojom") {
sources = [ "video_geometry_setter.mojom" ]

public_deps = [
"//mojo/public/mojom/base",
"//ui/gfx/geometry/mojom",
"//ui/gfx/mojom",
]
}
58 changes: 58 additions & 0 deletions cobalt/media/service/mojom/video_geometry_setter.mojom
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module chromecast.media.mojom;

import "mojo/public/mojom/base/unguessable_token.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/mojom/overlay_transform.mojom";

// The purpose of VideoGeometrySetterService is to provide a brokerage between
// chromecast::media::CastRenderers and viz::OverlayStrategyUnderlayCast, in a
// situation where multiple instances of CastRenderers possibly run within
// different instances of MediaService. When OverlayStrategyUnderlayCast decides
// to set video geometry on a certain CastRenderer, it relies on
// VideoGeometrySetterService to pass the geometry information to the right CastRenderer.

// CastRenderer must implement this interface.
// CastRenderer is used in multiple places but right now only CastRenderers
// running within ::media::MediaService, on browser process, are using
// video geometry setter service.
interface VideoGeometryChangeClient {
// Implementation of VideoGeometryChangeClient sets the video geometry on
// itself.
OnVideoGeometryChange(gfx.mojom.RectF rect_f, gfx.mojom.OverlayTransform
transform);
};

// A single instance of VideoGeometrySetterService provides both the interface
// and VideoGeometryChangeSubscriber and VideoGeometrySetter.

// To be used by a VideoGeometryChangeClient(i.e., a CastRenderer).
// CastRenders running in browser process can subscribe for the video geometry
// information, that would be sent from compositor, which is being migrated
// from browser process to GPU process.
interface VideoGeometryChangeSubscriber {
// A VideoGeometryChangeClient informs VideoGeometrySetterService its existence.
// |overlay_plane_id| identifies the VideoGeometryChangeClient,
// |client_pending_remote| is the pending remote bound to the
// VideoGeometryChangeClient itself.
SubscribeToVideoGeometryChange(
mojo_base.mojom.UnguessableToken overlay_plane_id,
pending_remote<VideoGeometryChangeClient> client_pending_remote) => ();
};

// To be used by OverlayStrategyUnderlayCast, which is part of compositor that
// is being migrated to GPU process. Within GPU process
// OverlayStrategyUnderlayCast cannot access CastRenderer any more, so it
// uses VideoGeometrySetter interface to send out the geometry information to
// VideoGeometrySetter, which then forward it to the right CastRenderer.
interface VideoGeometrySetter {
// Informs VideoGeometrySetterService the video geometry information and the
// target CastRenderer, identified by |overlay_plane_id|, that the geometry is
// set to.
SetVideoGeometry(gfx.mojom.RectF rect_f,
gfx.mojom.OverlayTransform transform,
mojo_base.mojom.UnguessableToken overlay_plane_id);
};
89 changes: 89 additions & 0 deletions cobalt/media/service/video_geometry_setter_service.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "video_geometry_setter_service.h"

#include <utility>

#include "base/task/sequenced_task_runner.h"

#define MAKE_SURE_ON_SEQUENCE(callback, ...) \
if (!task_runner_->RunsTasksInCurrentSequence()) { \
task_runner_->PostTask( \
FROM_HERE, base::BindOnce(&VideoGeometrySetterService::callback, \
weak_factory_.GetWeakPtr(), ##__VA_ARGS__)); \
return; \
}

namespace chromecast {
namespace media {

VideoGeometrySetterService::VideoGeometrySetterService()
: task_runner_(base::SequencedTaskRunner::GetCurrentDefault()),
weak_factory_(this) {}

VideoGeometrySetterService::~VideoGeometrySetterService() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
}

void VideoGeometrySetterService::GetVideoGeometryChangeSubscriber(
mojo::PendingReceiver<mojom::VideoGeometryChangeSubscriber>
pending_receiver) {
MAKE_SURE_ON_SEQUENCE(GetVideoGeometryChangeSubscriber,
std::move(pending_receiver));
video_geometry_change_subscriber_receivers_.Add(this,
std::move(pending_receiver));
}
void VideoGeometrySetterService::GetVideoGeometrySetter(
mojo::PendingReceiver<mojom::VideoGeometrySetter> pending_receiver) {
MAKE_SURE_ON_SEQUENCE(GetVideoGeometrySetter, std::move(pending_receiver));
if (video_geometry_setter_receiver_.is_bound()) {
LOG(ERROR) << __func__ << " VideoGeometrySetter dropped";
video_geometry_setter_receiver_.reset();
}
video_geometry_setter_receiver_.Bind(std::move(pending_receiver));
}

void VideoGeometrySetterService::SubscribeToVideoGeometryChange(
const base::UnguessableToken& overlay_plane_id,
mojo::PendingRemote<mojom::VideoGeometryChangeClient> client_pending_remote,
SubscribeToVideoGeometryChangeCallback callback) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
auto client = mojo::Remote<mojom::VideoGeometryChangeClient>(
std::move(client_pending_remote));
// The remote end closes the message pipe for the client when it no longer
// wants to receive updates.
// If the disconnect_handler is called, |this| must be alive, so Unretained is
// safe.
client.set_disconnect_handler(base::BindOnce(
&VideoGeometrySetterService::OnVideoGeometryChangeClientGone,
base::Unretained(this), overlay_plane_id));
video_geometry_change_clients_[overlay_plane_id] = std::move(client);

std::move(callback).Run();
}

void VideoGeometrySetterService::SetVideoGeometry(
const gfx::RectF& rect_f,
gfx::OverlayTransform transform,
const base::UnguessableToken& overlay_plane_id) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
auto video_geometry_change_client =
video_geometry_change_clients_.find(overlay_plane_id);
if (video_geometry_change_client != video_geometry_change_clients_.end()) {
video_geometry_change_client->second->OnVideoGeometryChange(rect_f,
transform);
}
}

// When a VideoGeometryChangeClient is gone, delete the corresponding entry in
// the mapping.
void VideoGeometrySetterService::OnVideoGeometryChangeClientGone(
const base::UnguessableToken overlay_plane_id) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
video_geometry_change_clients_.erase(overlay_plane_id);
}

} // namespace media
} // namespace chromecast
79 changes: 79 additions & 0 deletions cobalt/media/service/video_geometry_setter_service.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMECAST_MEDIA_SERVICE_VIDEO_GEOMETRY_SETTER_SERVICE_H_
#define CHROMECAST_MEDIA_SERVICE_VIDEO_GEOMETRY_SETTER_SERVICE_H_

#include "base/containers/flat_map.h"
#include "base/functional/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/unguessable_token.h"
#include "chromecast/media/service/mojom/video_geometry_setter.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"

namespace base {
class SequencedTaskRunner;
} // namespace base

namespace chromecast {
namespace media {

// This service runs and destructs on the sequence where it's constructed, but
// the public methods can be run on any sequence.
class VideoGeometrySetterService final
: public mojom::VideoGeometryChangeSubscriber,
public mojom::VideoGeometrySetter {
public:
VideoGeometrySetterService();

VideoGeometrySetterService(const VideoGeometrySetterService&) = delete;
VideoGeometrySetterService& operator=(const VideoGeometrySetterService&) =
delete;

~VideoGeometrySetterService() override;

void GetVideoGeometryChangeSubscriber(
mojo::PendingReceiver<mojom::VideoGeometryChangeSubscriber>
pending_receiver);
void GetVideoGeometrySetter(
mojo::PendingReceiver<mojom::VideoGeometrySetter> pending_receiver);

private:
// mojom::VideoGeometryChangeSubscriber implementation.
void SubscribeToVideoGeometryChange(
const base::UnguessableToken& overlay_plane_id,
mojo::PendingRemote<mojom::VideoGeometryChangeClient>
client_pending_remote,
SubscribeToVideoGeometryChangeCallback callback) override;
// mojom::VideoGeometrySetter implementation.
void SetVideoGeometry(
const gfx::RectF& rect_f,
gfx::OverlayTransform transform,
const base::UnguessableToken& overlay_plane_id) override;

void OnVideoGeometryChangeClientGone(
const base::UnguessableToken overlay_plane_id);

const scoped_refptr<base::SequencedTaskRunner> task_runner_;

base::flat_map<base::UnguessableToken,
mojo::Remote<mojom::VideoGeometryChangeClient>>
video_geometry_change_clients_;

mojo::ReceiverSet<mojom::VideoGeometryChangeSubscriber>
video_geometry_change_subscriber_receivers_;
mojo::Receiver<mojom::VideoGeometrySetter> video_geometry_setter_receiver_{
this};

base::WeakPtrFactory<VideoGeometrySetterService> weak_factory_;
};

} // namespace media
} // namespace chromecast

#endif // CHROMECAST_MEDIA_SERVICE_VIDEO_GEOMETRY_SETTER_SERVICE_H_
Loading