Reland "Expose effects processor from MediaEffectsService up to content client"
This is a reland of commit fd87acad32
Original CL was failing in CI because of a missing dependency from
content/browser:browser to services/video_effects/public/mojom:mojom
target (now required because of a transitive include). This was
missing because content/brower:browser does not depend on the target
where the public_deps entry was added. The reland addresses it by
explicitly adding the dependency, compare PS1 and PS2 to see the
change.
Original change's description:
> Expose effects processor from MediaEffectsService up to content client
>
> Additionally, add unit tests for VideoEffectsProcessor that mostly
> mimic the tests that have been written for Video Effects Manager. This
> also includes a basic fake implementation of VideoEffectsService and
> VideoEffectsProcessor.
>
> MediaEffectsService header file also now exposes a way to override the
> VideoEffectsService for testing, as otherwise it'd have to spawn a new
> utility process, and this is not desired in unittests.
>
> Bug: b:328118837
> Change-Id: Id096ecb09e0059d660896d743b80c991915dc4ff
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5353891
> Reviewed-by: Bryant Chandler <bryantchandler@chromium.org>
> Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
> Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1278592}
Bug: b:328118837
Change-Id: I7373387ed8478a3df654196c88b831421e82709d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5401456
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Theresa Sullivan <twellington@chromium.org>
Reviewed-by: Bryant Chandler <bryantchandler@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1279231}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
a7388995d0
commit
c2c709d84c
chrome
browser
DEPSchrome_content_browser_client.ccchrome_content_browser_client.hchrome_content_browser_client_unittest.cc
test
components/media_effects
BUILD.gnDEPSREADME.mdmedia_effects_manager_binder.ccmedia_effects_manager_binder.hmedia_effects_manager_binder_unittest.ccmedia_effects_service.ccmedia_effects_service.hmedia_effects_service_unittest.cc
content
services/video_effects
@ -466,6 +466,8 @@ include_rules = [
|
||||
"+services/strings",
|
||||
"+services/tracing/public/cpp",
|
||||
"+services/video_capture/public",
|
||||
"+services/video_effects/public",
|
||||
"+services/video_effects/test",
|
||||
"+services/viz/public",
|
||||
"+services/viz/privileged",
|
||||
"+skia/ext",
|
||||
|
@ -375,6 +375,7 @@
|
||||
#include "services/network/public/cpp/web_sandbox_flags.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/public/mojom/web_transport.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h"
|
||||
#include "third_party/blink/public/common/features.h"
|
||||
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
|
||||
#include "third_party/blink/public/common/navigation/navigation_policy.h"
|
||||
@ -8237,6 +8238,15 @@ void ChromeContentBrowserClient::BindVideoEffectsManager(
|
||||
media_effects::BindVideoEffectsManager(device_id, browser_context,
|
||||
std::move(video_effects_manager));
|
||||
}
|
||||
|
||||
void ChromeContentBrowserClient::BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor) {
|
||||
media_effects::BindVideoEffectsProcessor(device_id, browser_context,
|
||||
std::move(video_effects_processor));
|
||||
}
|
||||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
|
||||
void ChromeContentBrowserClient::PreferenceRankAudioDeviceInfos(
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "services/metrics/public/cpp/ukm_source_id.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h"
|
||||
#include "third_party/blink/public/mojom/worker/shared_worker_info.mojom.h"
|
||||
|
||||
class ChromeContentBrowserClientParts;
|
||||
@ -996,6 +997,12 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
|
||||
content::BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager>
|
||||
video_effects_manager) override;
|
||||
|
||||
void BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor) override;
|
||||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
|
||||
void PreferenceRankAudioDeviceInfos(
|
||||
|
@ -77,6 +77,8 @@
|
||||
#include "net/test/cert_test_util.h"
|
||||
#include "net/test/test_data_directory.h"
|
||||
#include "services/network/test/test_network_context.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_service.mojom.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/blink/public/common/switches.h"
|
||||
@ -90,7 +92,12 @@
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "chrome/test/base/browser_with_test_window_test.h"
|
||||
#include "chrome/test/base/search_test_utils.h"
|
||||
// `gn check` is failing on Android for this particular include even though
|
||||
// the (conditional) dependency path exists, adding `nogncheck`:
|
||||
#include "components/media_effects/media_effects_service.h" // nogncheck
|
||||
#include "components/password_manager/core/common/password_manager_features.h"
|
||||
// Ditto:
|
||||
#include "services/video_effects/test/fake_video_effects_service.h" // nogncheck
|
||||
#include "ui/base/page_transition_types.h"
|
||||
#else
|
||||
#include "base/system/sys_info.h"
|
||||
@ -630,6 +637,26 @@ TEST_F(ChromeContentBrowserClientTest, BindVideoEffectsManager) {
|
||||
// result means that the plumbing worked.
|
||||
EXPECT_FALSE(configuration_future.Get().is_null());
|
||||
}
|
||||
|
||||
TEST_F(ChromeContentBrowserClientTest, BindVideoEffectsProcessor) {
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService> service;
|
||||
video_effects::FakeVideoEffectsService fake_effects_service(
|
||||
service.BindNewPipeAndPassReceiver());
|
||||
auto service_reset = SetVideoEffectsServiceRemoteForTesting(&service);
|
||||
|
||||
std::unique_ptr<base::test::TestFuture<void>> effects_processor_future =
|
||||
fake_effects_service.GetEffectsProcessorCreationFuture();
|
||||
|
||||
TestChromeContentBrowserClient test_content_browser_client;
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor;
|
||||
test_content_browser_client.BindVideoEffectsProcessor(
|
||||
"test_device_id", &profile_,
|
||||
video_effects_processor.BindNewPipeAndPassReceiver());
|
||||
|
||||
EXPECT_TRUE(effects_processor_future->Wait());
|
||||
EXPECT_TRUE(video_effects_processor.is_connected());
|
||||
}
|
||||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
|
||||
TEST_F(ChromeContentBrowserClientTest, PreferenceRankAudioDeviceInfos) {
|
||||
|
@ -8285,6 +8285,7 @@ test("unit_tests") {
|
||||
"//components/lens:buildflags",
|
||||
"//components/lens:lens_mojo",
|
||||
"//components/manta",
|
||||
"//components/media_effects:media_effects",
|
||||
"//components/media_effects/test:test_support",
|
||||
"//components/media_message_center:test_support",
|
||||
"//components/media_router/common:test_support",
|
||||
@ -8314,6 +8315,7 @@ test("unit_tests") {
|
||||
"//services/device/public/cpp/bluetooth",
|
||||
"//services/metrics/public/cpp:ukm_builders",
|
||||
"//services/network:test_support",
|
||||
"//services/video_effects/test:test_support",
|
||||
"//third_party/crashpad/crashpad/util",
|
||||
"//third_party/libaddressinput",
|
||||
"//third_party/lzma_sdk/google:unit_tests",
|
||||
|
@ -1,4 +1,8 @@
|
||||
source_set("media_effects") {
|
||||
public_deps = [
|
||||
"//media/capture/mojom:video_effects_manager",
|
||||
"//services/video_effects/public/mojom:mojom",
|
||||
]
|
||||
deps = [
|
||||
"//base",
|
||||
"//components/keyed_service/content",
|
||||
@ -32,6 +36,7 @@ source_set("unit_tests") {
|
||||
"//components/prefs:test_support",
|
||||
"//components/user_prefs/test:test_support",
|
||||
"//content/test:test_support",
|
||||
"//services/video_effects/test:test_support",
|
||||
"//testing/gtest",
|
||||
"//third_party/mediapipe",
|
||||
]
|
||||
|
@ -11,6 +11,8 @@ include_rules = [
|
||||
"+services/audio/public/cpp/fake_system_info.h",
|
||||
"+services/audio/public/mojom",
|
||||
"+services/video_capture/public/mojom",
|
||||
"+services/video_effects/public/mojom",
|
||||
"+services/video_effects/test",
|
||||
"+third_party/mediapipe/buildflags.h",
|
||||
"+third_party/mediapipe/src",
|
||||
"+ui/gfx/geometry",
|
||||
|
@ -1,4 +1,4 @@
|
||||
The MediaEffectsService provides the source of truth for media effect config and
|
||||
control of camera input from the Video Capture Service via browser-context-keyed effect
|
||||
managers that are able to get/set prefs and communicate configuration to
|
||||
Browser UI, contents, and the video capture service.
|
||||
Browser UI, contents, and the Video Effects Service.
|
||||
|
@ -5,8 +5,10 @@
|
||||
#include "components/media_effects/media_effects_manager_binder.h"
|
||||
#include "components/media_effects/media_effects_service_factory.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void BindVideoEffectsManagerOnUIThread(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
@ -24,10 +26,45 @@ void BindVideoEffectsManagerOnUIThread(
|
||||
media_effects_service->BindVideoEffectsManager(
|
||||
device_id, std::move(video_effects_manager));
|
||||
}
|
||||
|
||||
void BindVideoEffectsProcessorOnUIThread(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
auto* media_effects_service =
|
||||
MediaEffectsServiceFactory::GetForBrowserContext(browser_context);
|
||||
if (!media_effects_service) {
|
||||
LOG(WARNING) << "Video device not registered because no service was "
|
||||
"returned for the current BrowserContext";
|
||||
return;
|
||||
}
|
||||
|
||||
media_effects_service->BindVideoEffectsProcessor(
|
||||
device_id, std::move(video_effects_processor));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace media_effects {
|
||||
|
||||
void BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor) {
|
||||
if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
|
||||
BindVideoEffectsProcessorOnUIThread(device_id, browser_context,
|
||||
std::move(video_effects_processor));
|
||||
return;
|
||||
}
|
||||
// The function wasn't called from the UI thread, so post a task.
|
||||
content::GetUIThreadTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&BindVideoEffectsProcessorOnUIThread, device_id,
|
||||
browser_context, std::move(video_effects_processor)));
|
||||
}
|
||||
|
||||
void BindVideoEffectsManager(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
@ -44,4 +81,5 @@ void BindVideoEffectsManager(
|
||||
base::BindOnce(&BindVideoEffectsManagerOnUIThread, device_id,
|
||||
browser_context, std::move(video_effects_manager)));
|
||||
}
|
||||
|
||||
} // namespace media_effects
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "media/capture/mojom/video_effects_manager.mojom-forward.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h"
|
||||
|
||||
namespace media_effects {
|
||||
|
||||
@ -17,6 +18,12 @@ void BindVideoEffectsManager(
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager>
|
||||
video_effects_manager);
|
||||
|
||||
void BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor);
|
||||
|
||||
} // namespace media_effects
|
||||
|
||||
#endif // COMPONENTS_MEDIA_EFFECTS_MEDIA_EFFECTS_MANAGER_BINDER_H_
|
||||
|
@ -4,10 +4,14 @@
|
||||
|
||||
#include "components/media_effects/media_effects_manager_binder.h"
|
||||
#include "base/test/test_future.h"
|
||||
#include "components/media_effects/media_effects_service.h"
|
||||
#include "components/user_prefs/test/test_browser_context_with_prefs.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "media/capture/mojom/video_effects_manager.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_service.mojom.h"
|
||||
#include "services/video_effects/test/fake_video_effects_service.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/gfx/geometry/insets_f.h"
|
||||
|
||||
@ -50,3 +54,25 @@ TEST_F(MediaEffectsManagerBinderTest, BindVideoEffectsManager) {
|
||||
EXPECT_EQ(kPaddingRatio, GetConfigurationSync(video_effects_manager)
|
||||
->framing->padding_ratios.top());
|
||||
}
|
||||
|
||||
TEST_F(MediaEffectsManagerBinderTest, BindVideoEffectsProcessor) {
|
||||
// Tests that `media_effects::BindVideoEffectsProcessor()` works, i.e.
|
||||
// causes the passed in remote to be connected.
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService> service;
|
||||
video_effects::FakeVideoEffectsService fake_effects_service(
|
||||
service.BindNewPipeAndPassReceiver());
|
||||
auto service_reset = SetVideoEffectsServiceRemoteForTesting(&service);
|
||||
|
||||
auto effects_processor_future =
|
||||
fake_effects_service.GetEffectsProcessorCreationFuture();
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor;
|
||||
media_effects::BindVideoEffectsProcessor(
|
||||
"some_device_id", &browser_context_,
|
||||
video_effects_processor.BindNewPipeAndPassReceiver());
|
||||
|
||||
EXPECT_TRUE(effects_processor_future->Wait());
|
||||
EXPECT_TRUE(video_effects_processor.is_connected());
|
||||
}
|
||||
|
@ -2,8 +2,49 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "base/auto_reset.h"
|
||||
#include "components/media_effects/media_effects_service.h"
|
||||
#include "content/public/browser/service_process_host.h"
|
||||
#include "media/capture/mojom/video_effects_manager.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_service.mojom.h"
|
||||
|
||||
namespace {
|
||||
|
||||
static mojo::Remote<video_effects::mojom::VideoEffectsService>*
|
||||
g_service_remote = nullptr;
|
||||
|
||||
video_effects::mojom::VideoEffectsService* GetVideoEffectsService() {
|
||||
if (!g_service_remote) {
|
||||
g_service_remote =
|
||||
new mojo::Remote<video_effects::mojom::VideoEffectsService>();
|
||||
}
|
||||
|
||||
if (!g_service_remote->is_bound()) {
|
||||
content::ServiceProcessHost::Launch(
|
||||
g_service_remote->BindNewPipeAndPassReceiver(),
|
||||
content::ServiceProcessHost::Options()
|
||||
.WithDisplayName("Video Effects Service")
|
||||
.Pass());
|
||||
|
||||
g_service_remote->reset_on_disconnect();
|
||||
g_service_remote->reset_on_idle_timeout(base::Seconds(5));
|
||||
}
|
||||
|
||||
return g_service_remote->get();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
base::AutoReset<mojo::Remote<video_effects::mojom::VideoEffectsService>*>
|
||||
SetVideoEffectsServiceRemoteForTesting(
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService>* service_override) {
|
||||
return base::AutoReset<
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService>*>(
|
||||
&g_service_remote, service_override);
|
||||
}
|
||||
|
||||
MediaEffectsService::MediaEffectsService(PrefService* prefs) : prefs_(prefs) {}
|
||||
|
||||
@ -17,6 +58,22 @@ void MediaEffectsService::BindVideoEffectsManager(
|
||||
effects_manager.Bind(std::move(effects_manager_receiver));
|
||||
}
|
||||
|
||||
void MediaEffectsService::BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
effects_processor_receiver) {
|
||||
mojo::PendingRemote<media::mojom::VideoEffectsManager> video_effects_manager;
|
||||
BindVideoEffectsManager(
|
||||
device_id, video_effects_manager.InitWithNewPipeAndPassReceiver());
|
||||
|
||||
auto* video_effects_service = GetVideoEffectsService();
|
||||
CHECK(video_effects_service);
|
||||
|
||||
video_effects_service->CreateEffectsProcessor(
|
||||
device_id, std::move(video_effects_manager),
|
||||
std::move(effects_processor_receiver));
|
||||
}
|
||||
|
||||
VideoEffectsManagerImpl& MediaEffectsService::GetOrCreateVideoEffectsManager(
|
||||
const std::string& device_id) {
|
||||
if (auto effects_manager = video_effects_managers_.find(device_id);
|
||||
|
@ -5,10 +5,18 @@
|
||||
#ifndef COMPONENTS_MEDIA_EFFECTS_MEDIA_EFFECTS_SERVICE_H_
|
||||
#define COMPONENTS_MEDIA_EFFECTS_MEDIA_EFFECTS_SERVICE_H_
|
||||
|
||||
#include "base/auto_reset.h"
|
||||
#include "components/keyed_service/core/keyed_service.h"
|
||||
#include "components/media_effects/video_effects_manager_impl.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "media/capture/mojom/video_effects_manager.mojom-forward.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_service.mojom-forward.h"
|
||||
|
||||
[[nodiscard]] base::AutoReset<
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService>*>
|
||||
SetVideoEffectsServiceRemoteForTesting(
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService>* service_override);
|
||||
|
||||
class MediaEffectsService : public KeyedService {
|
||||
public:
|
||||
@ -44,6 +52,30 @@ class MediaEffectsService : public KeyedService {
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager>
|
||||
effects_manager_receiver);
|
||||
|
||||
// Connects a `VideoEffectsManagerImpl` to the provided
|
||||
// `effects_processor_receiver`. If the keyed profile already has a manager
|
||||
// for the passed `device_id`, then it will be used. Otherwise, a new manager
|
||||
// will be created.
|
||||
//
|
||||
// The device id must be the raw string from
|
||||
// `media::mojom::VideoCaptureDeviceDescriptor::device_id`.
|
||||
//
|
||||
// The manager remote will be sent to the Video Effects Service, where
|
||||
// it will be used to subscribe to the effects configuration. The passed in
|
||||
// pending receiver is going to be used to create a Video Effects Processor
|
||||
// in the Video Effects Service.
|
||||
//
|
||||
// Note that this API does not expose the `VideoEffectsManagerImpl` in any
|
||||
// way. If you need to interact with the manager, call
|
||||
// `BindVideoEffectsManager()` instead.
|
||||
//
|
||||
// Calling this method will launch a new instance of Video Effects Service if
|
||||
// it's not already running.
|
||||
void BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
effects_processor_receiver);
|
||||
|
||||
private:
|
||||
VideoEffectsManagerImpl& GetOrCreateVideoEffectsManager(
|
||||
const std::string& device_id);
|
||||
|
@ -8,6 +8,10 @@
|
||||
#include "base/test/test_future.h"
|
||||
#include "components/user_prefs/test/test_browser_context_with_prefs.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_service.mojom-forward.h"
|
||||
#include "services/video_effects/test/fake_video_effects_service.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/gfx/geometry/insets_f.h"
|
||||
|
||||
@ -104,6 +108,11 @@ TEST_F(
|
||||
TEST_F(
|
||||
MediaEffectsServiceTest,
|
||||
OnLastReceiverDisconnected_ErasesTheManagerWhenAllReceiversAreDisconnected) {
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService> service;
|
||||
video_effects::FakeVideoEffectsService fake_effects_service(
|
||||
service.BindNewPipeAndPassReceiver());
|
||||
auto service_reset = SetVideoEffectsServiceRemoteForTesting(&service);
|
||||
|
||||
mojo::Remote<media::mojom::VideoEffectsManager> effects_manager1;
|
||||
service_.BindVideoEffectsManager(
|
||||
kDeviceId, effects_manager1.BindNewPipeAndPassReceiver());
|
||||
@ -111,6 +120,13 @@ TEST_F(
|
||||
service_.BindVideoEffectsManager(
|
||||
kDeviceId, effects_manager2.BindNewPipeAndPassReceiver());
|
||||
|
||||
auto effects_processor_future =
|
||||
fake_effects_service.GetEffectsProcessorCreationFuture();
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsProcessor> effects_processor;
|
||||
service_.BindVideoEffectsProcessor(
|
||||
kDeviceId, effects_processor.BindNewPipeAndPassReceiver());
|
||||
|
||||
const float kFramingPaddingRatio = 0.234;
|
||||
|
||||
SetFramingSync(effects_manager1, kFramingPaddingRatio);
|
||||
@ -121,8 +137,18 @@ TEST_F(
|
||||
EXPECT_EQ(gfx::InsetsF{kFramingPaddingRatio},
|
||||
GetConfigurationSync(effects_manager2)->framing->padding_ratios);
|
||||
|
||||
// Wait for the fake effects service to create the processor:
|
||||
EXPECT_TRUE(effects_processor_future->Wait());
|
||||
ASSERT_EQ(fake_effects_service.GetProcessors().size(), 1u);
|
||||
EXPECT_EQ(
|
||||
gfx::InsetsF{kFramingPaddingRatio},
|
||||
GetConfigurationSync(fake_effects_service.GetProcessors()[kDeviceId]
|
||||
->GetVideoEffectsManager())
|
||||
->framing->padding_ratios);
|
||||
|
||||
effects_manager1.reset();
|
||||
effects_manager2.reset();
|
||||
fake_effects_service.GetProcessors().erase(kDeviceId);
|
||||
// Wait for the reset to complete
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -134,3 +160,100 @@ TEST_F(
|
||||
// `VideoEffectsManager`.
|
||||
EXPECT_TRUE(GetConfigurationSync(effects_manager3)->framing.is_null());
|
||||
}
|
||||
|
||||
TEST_F(MediaEffectsServiceTest, BindVideoEffectsProcessor) {
|
||||
// Tests that `MediaEffectsService::BindVideoEffectsProcessor()` works, i.e.
|
||||
// causes the passed in remote to be connected.
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService> service;
|
||||
video_effects::FakeVideoEffectsService fake_effects_service(
|
||||
service.BindNewPipeAndPassReceiver());
|
||||
auto service_reset = SetVideoEffectsServiceRemoteForTesting(&service);
|
||||
|
||||
auto effects_processor_future =
|
||||
fake_effects_service.GetEffectsProcessorCreationFuture();
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsProcessor> effects_processor;
|
||||
service_.BindVideoEffectsProcessor(
|
||||
kDeviceId, effects_processor.BindNewPipeAndPassReceiver());
|
||||
|
||||
EXPECT_TRUE(effects_processor_future->Wait());
|
||||
EXPECT_TRUE(effects_processor.is_connected());
|
||||
EXPECT_EQ(fake_effects_service.GetProcessors().size(), 1u);
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
MediaEffectsServiceTest,
|
||||
BindVideoEffectsProcessor_TwoProcessorsWithDifferentIdConnectToDifferentManager) {
|
||||
// Tests that `MediaEffectsService::BindVideoEffectsProcessor()` connects to
|
||||
// a different manager if a different ID was used. This is validated by
|
||||
// checking that the managers return different configurations. We also set a
|
||||
// different config directly via effects manager interface (originating from
|
||||
// a call to `MediaEffectsService::BindVideoEffectsManager()`) so this test
|
||||
// also checks that a correct relationship is established between manager
|
||||
// and processor.
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsService> service;
|
||||
video_effects::FakeVideoEffectsService fake_effects_service(
|
||||
service.BindNewPipeAndPassReceiver());
|
||||
auto service_reset = SetVideoEffectsServiceRemoteForTesting(&service);
|
||||
|
||||
mojo::Remote<media::mojom::VideoEffectsManager> effects_manager;
|
||||
service_.BindVideoEffectsManager(
|
||||
"test_device_1", effects_manager.BindNewPipeAndPassReceiver());
|
||||
|
||||
constexpr float kFramingPaddingRatio1 = 0.234;
|
||||
SetFramingSync(effects_manager, kFramingPaddingRatio1);
|
||||
|
||||
EXPECT_EQ(gfx::InsetsF{kFramingPaddingRatio1},
|
||||
GetConfigurationSync(effects_manager)->framing->padding_ratios);
|
||||
|
||||
auto effects_processor_future1 =
|
||||
fake_effects_service.GetEffectsProcessorCreationFuture();
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsProcessor> effects_processor1;
|
||||
service_.BindVideoEffectsProcessor(
|
||||
"test_device_2", effects_processor1.BindNewPipeAndPassReceiver());
|
||||
EXPECT_TRUE(effects_processor_future1->Wait());
|
||||
ASSERT_EQ(fake_effects_service.GetProcessors().size(), 1u);
|
||||
|
||||
constexpr float kFramingPaddingRatio2 = 0.345;
|
||||
SetFramingSync(fake_effects_service.GetProcessors()["test_device_2"]
|
||||
->GetVideoEffectsManager(),
|
||||
kFramingPaddingRatio2);
|
||||
|
||||
EXPECT_EQ(gfx::InsetsF{kFramingPaddingRatio2},
|
||||
GetConfigurationSync(
|
||||
fake_effects_service.GetProcessors()["test_device_2"]
|
||||
->GetVideoEffectsManager())
|
||||
->framing->padding_ratios);
|
||||
|
||||
auto effects_processor_future2 =
|
||||
fake_effects_service.GetEffectsProcessorCreationFuture();
|
||||
|
||||
mojo::Remote<video_effects::mojom::VideoEffectsProcessor> effects_processor2;
|
||||
service_.BindVideoEffectsProcessor(
|
||||
"test_device_3", effects_processor2.BindNewPipeAndPassReceiver());
|
||||
EXPECT_TRUE(effects_processor_future2->Wait());
|
||||
ASSERT_EQ(fake_effects_service.GetProcessors().size(), 2u);
|
||||
|
||||
constexpr float kFramingPaddingRatio3 = 0.456;
|
||||
SetFramingSync(fake_effects_service.GetProcessors()["test_device_3"]
|
||||
->GetVideoEffectsManager(),
|
||||
kFramingPaddingRatio3);
|
||||
|
||||
auto padding2 =
|
||||
std::move(GetConfigurationSync(
|
||||
fake_effects_service.GetProcessors()["test_device_2"]
|
||||
->GetVideoEffectsManager())
|
||||
->framing->padding_ratios);
|
||||
auto padding3 =
|
||||
std::move(GetConfigurationSync(
|
||||
fake_effects_service.GetProcessors()["test_device_3"]
|
||||
->GetVideoEffectsManager())
|
||||
->framing->padding_ratios);
|
||||
|
||||
EXPECT_NE(padding2, padding3);
|
||||
EXPECT_EQ(gfx::InsetsF{kFramingPaddingRatio2}, padding2);
|
||||
EXPECT_EQ(gfx::InsetsF{kFramingPaddingRatio3}, padding3);
|
||||
}
|
||||
|
@ -223,6 +223,7 @@ source_set("browser") {
|
||||
"//services/video_capture:lib",
|
||||
"//services/video_capture/public/cpp",
|
||||
"//services/video_capture/public/mojom:constants",
|
||||
"//services/video_effects/public/mojom:mojom",
|
||||
"//services/viz/privileged/mojom",
|
||||
"//services/viz/public/cpp/gpu",
|
||||
"//services/viz/public/mojom",
|
||||
|
@ -548,6 +548,7 @@ source_set("browser_sources") {
|
||||
"//services/tracing/public/cpp",
|
||||
"//services/tracing/public/mojom",
|
||||
"//services/video_capture/public/mojom",
|
||||
"//services/video_effects/public/mojom:mojom",
|
||||
"//services/viz/public/mojom",
|
||||
|
||||
# We expose skia headers in the public API.
|
||||
|
@ -20,6 +20,7 @@ include_rules = [
|
||||
"+services/resource_coordinator/public",
|
||||
"+services/tracing/public/mojom",
|
||||
"+services/video_capture/public/mojom",
|
||||
"+services/video_effects/public/mojom",
|
||||
"+services/viz/public/mojom",
|
||||
"+third_party/jni_zero",
|
||||
"+third_party/perfetto/protos/perfetto/config/chrome/scenario_config.gen.h",
|
||||
|
@ -85,6 +85,8 @@
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
#include "content/public/browser/tts_environment_android.h"
|
||||
#else
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h"
|
||||
#endif
|
||||
|
||||
using AttributionReportType =
|
||||
@ -1669,9 +1671,15 @@ bool ContentBrowserClient::UseOutermostMainFrameOrEmbedderForSubCaptureTargets()
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
void ContentBrowserClient::BindVideoEffectsManager(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager>
|
||||
video_effects_manager) {}
|
||||
|
||||
void ContentBrowserClient::BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_manager) {}
|
||||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
|
||||
void ContentBrowserClient::PreferenceRankAudioDeviceInfos(
|
||||
|
@ -90,6 +90,7 @@
|
||||
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
#include "media/capture/mojom/video_effects_manager.mojom.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h"
|
||||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
|
||||
namespace net {
|
||||
@ -2803,9 +2804,17 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
// effect settings.
|
||||
virtual void BindVideoEffectsManager(
|
||||
const std::string& device_id,
|
||||
content::BrowserContext* browser_context,
|
||||
BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager>
|
||||
video_effects_manager);
|
||||
|
||||
// Allows the embedder to correlate backend media services with profile-keyed
|
||||
// effect settings.
|
||||
virtual void BindVideoEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
BrowserContext* browser_context,
|
||||
mojo::PendingReceiver<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor);
|
||||
#endif // !BUILDFLAG(IS_ANDROID)
|
||||
|
||||
// Re-order audio device `infos` based on user preference. The ordering will
|
||||
|
@ -4,4 +4,5 @@ include_rules = [
|
||||
"+media/base",
|
||||
"+media/capture/mojom",
|
||||
"+services/viz/public/cpp/gpu",
|
||||
"+services/video_effects/public/mojom",
|
||||
]
|
||||
|
@ -16,13 +16,17 @@ import "services/video_effects/public/mojom/video_effects_processor.mojom";
|
||||
interface VideoEffectsService {
|
||||
// Creates a Video Effects Processor whose effects configuration will be
|
||||
// managed by the passed in `manager`. Note that the created processor will
|
||||
// be bound to `processor`, i.e. it is not going to be returned in `result`.
|
||||
// This is done so that the caller can create both ends of the pipe for
|
||||
// `VideoEffectsProcessor` & send the receiver to Video Effects Service, and
|
||||
// the remote to Video Capture Service.
|
||||
// In case of failure, the remote end of the `processor` will eventually
|
||||
// return `false` from the calls to its `.is_connected()` method.
|
||||
// be bound to `processor`. This is done so that the caller can create both
|
||||
// ends of the pipe for `VideoEffectsProcessor` & send the receiver to Video
|
||||
// Effects Service, and the remote to Video Capture Service.
|
||||
// The `device_id` is a string that uniquely identifies the device for which
|
||||
// the processor is being created. If the service has already created a
|
||||
// processor for a given device id, subsequent attempts to create one will
|
||||
// fail.
|
||||
// In case of failure, the remote end of the `processor` will be
|
||||
// disconnected.
|
||||
CreateEffectsProcessor(
|
||||
string device_id,
|
||||
pending_remote<media.mojom.VideoEffectsManager> manager,
|
||||
pending_receiver<VideoEffectsProcessor> processor);
|
||||
};
|
||||
|
19
services/video_effects/test/BUILD.gn
Normal file
19
services/video_effects/test/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright 2024 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
source_set("test_support") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"fake_video_effects_processor.cc",
|
||||
"fake_video_effects_processor.h",
|
||||
"fake_video_effects_service.cc",
|
||||
"fake_video_effects_service.h",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"//base/test:test_support",
|
||||
"//services/video_effects/public/mojom",
|
||||
]
|
||||
}
|
33
services/video_effects/test/fake_video_effects_processor.cc
Normal file
33
services/video_effects/test/fake_video_effects_processor.cc
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "services/video_effects/test/fake_video_effects_processor.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom-shared.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
|
||||
namespace video_effects {
|
||||
|
||||
FakeVideoEffectsProcessor::FakeVideoEffectsProcessor(
|
||||
mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor,
|
||||
mojo::PendingRemote<media::mojom::VideoEffectsManager> manager)
|
||||
: receiver_(this, std::move(processor)), manager_(std::move(manager)) {}
|
||||
|
||||
FakeVideoEffectsProcessor::~FakeVideoEffectsProcessor() = default;
|
||||
|
||||
void FakeVideoEffectsProcessor::PostProcess(
|
||||
media::mojom::VideoBufferHandlePtr input_frame_data,
|
||||
media::mojom::VideoFrameInfoPtr input_frame_info,
|
||||
media::mojom::VideoBufferHandlePtr result_frame_data,
|
||||
media::VideoPixelFormat result_pixel_format,
|
||||
PostProcessCallback callback) {
|
||||
std::move(callback).Run(
|
||||
mojom::PostProcessResult::NewError(mojom::PostProcessError::kUnknown));
|
||||
}
|
||||
|
||||
mojo::Remote<media::mojom::VideoEffectsManager>&
|
||||
FakeVideoEffectsProcessor::GetVideoEffectsManager() {
|
||||
return manager_;
|
||||
}
|
||||
|
||||
} // namespace video_effects
|
42
services/video_effects/test/fake_video_effects_processor.h
Normal file
42
services/video_effects/test/fake_video_effects_processor.h
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SERVICES_VIDEO_EFFECTS_TEST_FAKE_VIDEO_EFFECTS_PROCESSOR_H_
|
||||
#define SERVICES_VIDEO_EFFECTS_TEST_FAKE_VIDEO_EFFECTS_PROCESSOR_H_
|
||||
|
||||
#include "media/capture/mojom/video_effects_manager.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/remote.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
|
||||
namespace video_effects {
|
||||
|
||||
class FakeVideoEffectsProcessor : public mojom::VideoEffectsProcessor {
|
||||
public:
|
||||
explicit FakeVideoEffectsProcessor(
|
||||
mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor,
|
||||
mojo::PendingRemote<media::mojom::VideoEffectsManager> manager);
|
||||
~FakeVideoEffectsProcessor() override;
|
||||
|
||||
// mojom::VideoEffectsProcessor implementation
|
||||
void PostProcess(media::mojom::VideoBufferHandlePtr input_frame_data,
|
||||
media::mojom::VideoFrameInfoPtr input_frame_info,
|
||||
media::mojom::VideoBufferHandlePtr result_frame_data,
|
||||
media::VideoPixelFormat result_pixel_format,
|
||||
PostProcessCallback callback) override;
|
||||
|
||||
// For testing, get the manager that this processor will use to obtain the
|
||||
// video effects configuration:
|
||||
mojo::Remote<media::mojom::VideoEffectsManager>& GetVideoEffectsManager();
|
||||
|
||||
private:
|
||||
mojo::Receiver<mojom::VideoEffectsProcessor> receiver_;
|
||||
mojo::Remote<media::mojom::VideoEffectsManager> manager_;
|
||||
};
|
||||
|
||||
} // namespace video_effects
|
||||
|
||||
#endif // SERVICES_VIDEO_EFFECTS_TEST_FAKE_VIDEO_EFFECTS_PROCESSOR_H_
|
49
services/video_effects/test/fake_video_effects_service.cc
Normal file
49
services/video_effects/test/fake_video_effects_service.cc
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "services/video_effects/test/fake_video_effects_service.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "services/video_effects/public/mojom/video_effects_processor.mojom.h"
|
||||
#include "services/video_effects/test/fake_video_effects_processor.h"
|
||||
|
||||
namespace video_effects {
|
||||
|
||||
FakeVideoEffectsService::FakeVideoEffectsService(
|
||||
mojo::PendingReceiver<mojom::VideoEffectsService> receiver)
|
||||
: receiver_(this, std::move(receiver)) {}
|
||||
|
||||
FakeVideoEffectsService::~FakeVideoEffectsService() = default;
|
||||
|
||||
void FakeVideoEffectsService::CreateEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
mojo::PendingRemote<media::mojom::VideoEffectsManager> manager,
|
||||
mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor) {
|
||||
processors_.insert(
|
||||
std::make_pair(device_id, std::make_unique<FakeVideoEffectsProcessor>(
|
||||
std::move(processor), std::move(manager))));
|
||||
|
||||
if (effects_processor_creation_cb_) {
|
||||
std::move(effects_processor_creation_cb_).Run();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<base::test::TestFuture<void>>
|
||||
FakeVideoEffectsService::GetEffectsProcessorCreationFuture() {
|
||||
CHECK(!effects_processor_creation_cb_);
|
||||
|
||||
std::unique_ptr<base::test::TestFuture<void>> result =
|
||||
std::make_unique<base::test::TestFuture<void>>();
|
||||
effects_processor_creation_cb_ = result->GetCallback();
|
||||
return result;
|
||||
}
|
||||
|
||||
base::flat_map<std::string, std::unique_ptr<FakeVideoEffectsProcessor>>&
|
||||
FakeVideoEffectsService::GetProcessors() {
|
||||
return processors_;
|
||||
}
|
||||
|
||||
} // namespace video_effects
|
62
services/video_effects/test/fake_video_effects_service.h
Normal file
62
services/video_effects/test/fake_video_effects_service.h
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SERVICES_VIDEO_EFFECTS_TEST_FAKE_VIDEO_EFFECTS_SERVICE_H_
|
||||
#define SERVICES_VIDEO_EFFECTS_TEST_FAKE_VIDEO_EFFECTS_SERVICE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/functional/callback_forward.h"
|
||||
#include "base/test/test_future.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 "services/video_effects/public/mojom/video_effects_service.mojom.h"
|
||||
#include "services/video_effects/test/fake_video_effects_processor.h"
|
||||
|
||||
namespace video_effects {
|
||||
|
||||
// Fake implementation of Video Effects Service.
|
||||
// Intended to be used in unit tests.
|
||||
class FakeVideoEffectsService : public mojom::VideoEffectsService {
|
||||
public:
|
||||
explicit FakeVideoEffectsService(
|
||||
mojo::PendingReceiver<mojom::VideoEffectsService> receiver);
|
||||
~FakeVideoEffectsService() override;
|
||||
|
||||
// mojom::VideoEffectsService implementation:
|
||||
|
||||
// The fake implementation will ensure that the remote end of the passed in
|
||||
// `processor` receiver will stay connected for as long as the fake is alive.
|
||||
void CreateEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
mojo::PendingRemote<media::mojom::VideoEffectsManager> manager,
|
||||
mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor) override;
|
||||
|
||||
// Returns a test future which will be resolved when the next video effects
|
||||
// processor creation request is fulfilled. There can be at most one
|
||||
// outstanding test feature created at any given time.
|
||||
std::unique_ptr<base::test::TestFuture<void>>
|
||||
GetEffectsProcessorCreationFuture();
|
||||
|
||||
// For testing, get the processors that this service created.
|
||||
base::flat_map<std::string, std::unique_ptr<FakeVideoEffectsProcessor>>&
|
||||
GetProcessors();
|
||||
|
||||
private:
|
||||
mojo::Receiver<mojom::VideoEffectsService> receiver_;
|
||||
|
||||
// Note: indirection via std::unique_ptr is required since the processor is
|
||||
// not copyable and not moveable.
|
||||
base::flat_map<std::string, std::unique_ptr<FakeVideoEffectsProcessor>>
|
||||
processors_;
|
||||
|
||||
base::OnceClosure effects_processor_creation_cb_;
|
||||
};
|
||||
|
||||
} // namespace video_effects
|
||||
|
||||
#endif // SERVICES_VIDEO_EFFECTS_TEST_FAKE_VIDEO_EFFECTS_SERVICE_H_
|
@ -28,13 +28,18 @@ VideoEffectsServiceImpl::VideoEffectsServiceImpl(
|
||||
VideoEffectsServiceImpl::~VideoEffectsServiceImpl() = default;
|
||||
|
||||
void VideoEffectsServiceImpl::CreateEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
mojo::PendingRemote<media::mojom::VideoEffectsManager> manager,
|
||||
mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor) {
|
||||
if (processors_.contains(device_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEffectsProcessorImpl> effects_processor =
|
||||
std::make_unique<VideoEffectsProcessorImpl>(std::move(manager),
|
||||
std::move(processor));
|
||||
|
||||
processors_.push_back(std::move(effects_processor));
|
||||
processors_.insert(std::make_pair(device_id, std::move(effects_processor)));
|
||||
}
|
||||
|
||||
} // namespace video_effects
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "gpu/ipc/client/gpu_channel_host.h"
|
||||
#include "media/capture/mojom/video_effects_manager.mojom-forward.h"
|
||||
@ -48,11 +49,15 @@ class VideoEffectsServiceImpl : public mojom::VideoEffectsService {
|
||||
|
||||
// mojom::VideoEffectsService implementation:
|
||||
void CreateEffectsProcessor(
|
||||
const std::string& device_id,
|
||||
mojo::PendingRemote<media::mojom::VideoEffectsManager> manager,
|
||||
mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor) override;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<VideoEffectsProcessorImpl>> processors_;
|
||||
// Mapping from the device ID to processor implementation. Device ID is only
|
||||
// used to deduplicate processor creation requests.
|
||||
base::flat_map<std::string, std::unique_ptr<VideoEffectsProcessorImpl>>
|
||||
processors_;
|
||||
|
||||
mojo::Receiver<mojom::VideoEffectsService> receiver_;
|
||||
std::unique_ptr<GpuChannelHostProvider> gpu_channel_host_provider_;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "services/video_effects/video_effects_service_impl.h"
|
||||
|
||||
#include "base/run_loop.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
@ -21,6 +22,8 @@ using testing::_;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kDeviceId[] = "test_device";
|
||||
|
||||
class TestGpuChannelHostProvider : public GpuChannelHostProvider {
|
||||
public:
|
||||
TestGpuChannelHostProvider() = default;
|
||||
@ -50,18 +53,41 @@ TEST_F(VideoEffectsServiceTest, CreateEffectsProcessorWorks) {
|
||||
// Calling into `VideoEffectsService:::CreateEffectsProcessor()` is expected
|
||||
// to work (irrespective of whether the passed-in pipes are usable or not).
|
||||
|
||||
base::RunLoop run_loop;
|
||||
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager> manager_receiver;
|
||||
mojo::Remote<mojom::VideoEffectsProcessor> processor_remote;
|
||||
|
||||
service_remote_->CreateEffectsProcessor(
|
||||
manager_receiver.InitWithNewPipeAndPassRemote(),
|
||||
kDeviceId, manager_receiver.InitWithNewPipeAndPassRemote(),
|
||||
processor_remote.BindNewPipeAndPassReceiver());
|
||||
|
||||
run_loop.RunUntilIdle();
|
||||
|
||||
base::RunLoop().RunUntilIdle();
|
||||
EXPECT_TRUE(processor_remote.is_connected());
|
||||
}
|
||||
|
||||
TEST_F(VideoEffectsServiceTest, CreateEffectsProcessorWithSameIdFails) {
|
||||
// Calling into `VideoEffectsService:::CreateEffectsProcessor()` is expected
|
||||
// to fail if the same device id is passed.
|
||||
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager> manager_receiver1;
|
||||
mojo::Remote<mojom::VideoEffectsProcessor> processor_remote1;
|
||||
|
||||
service_remote_->CreateEffectsProcessor(
|
||||
kDeviceId, manager_receiver1.InitWithNewPipeAndPassRemote(),
|
||||
processor_remote1.BindNewPipeAndPassReceiver());
|
||||
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_TRUE(processor_remote1.is_connected());
|
||||
|
||||
mojo::PendingReceiver<media::mojom::VideoEffectsManager> manager_receiver2;
|
||||
mojo::Remote<mojom::VideoEffectsProcessor> processor_remote2;
|
||||
|
||||
service_remote_->CreateEffectsProcessor(
|
||||
kDeviceId, manager_receiver2.InitWithNewPipeAndPassRemote(),
|
||||
processor_remote2.BindNewPipeAndPassReceiver());
|
||||
|
||||
base::RunLoop().RunUntilIdle();
|
||||
EXPECT_TRUE(processor_remote1.is_connected());
|
||||
EXPECT_FALSE(processor_remote2.is_connected());
|
||||
}
|
||||
|
||||
} // namespace video_effects
|
||||
|
Reference in New Issue
Block a user