chromium/services/video_capture/video_capture_service_impl.cc

// Copyright 2017 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_capture/video_capture_service_impl.h"

#include <utility>

#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/ipc/client/client_shared_image_interface.h"
#include "media/capture/video/create_video_capture_device_factory.h"
#include "media/capture/video/fake_video_capture_device_factory.h"
#include "media/capture/video/video_capture_buffer_pool.h"
#include "media/capture/video/video_capture_buffer_tracker.h"
#include "media/capture/video/video_capture_system_impl.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/video_capture/device_factory_impl.h"
#include "services/video_capture/public/cpp/features.h"
#include "services/video_capture/testing_controls_impl.h"
#include "services/video_capture/video_source_provider_impl.h"
#include "services/video_capture/virtual_device_enabled_device_factory.h"
#include "services/viz/public/cpp/gpu/gpu.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "media/capture/video/chromeos/camera_app_device_bridge_impl.h"
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chromeos/crosapi/mojom/video_capture.mojom.h"
#include "chromeos/lacros/lacros_service.h"
#include "media/capture/capture_switches.h"
#include "services/video_capture/lacros/device_factory_adapter_lacros.h"
#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
#include "media/capture/capture_switches.h"
#include "media/capture/video/video_capture_gpu_channel_host.h"
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) ||
        // BUILDFLAG(IS_CHROMEOS_ASH)

namespace video_capture {

// Intended usage of this class is to instantiate on any sequence, and then
// operate and release the instance on the task runner exposed via
// GetTaskRunner() via WeakPtrs provided via GetWeakPtr(). To this end,
// GetTaskRunner() and GetWeakPtr() can be called from any sequence, typically
// the same as the one calling the constructor.
class VideoCaptureServiceImpl::GpuDependenciesContext {};

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
// Intended usage of this class is to create viz::Gpu in utility process and
// connect to viz::GpuClient of browser process, which will call to Gpu service.
// Also, this class holds the viz::ContextProvider to listen and monitor Gpu
// context lost event. The viz::Gpu and viz::ContextProvider need be created in
// the main thread of utility process. The |main_task_runner_| is initialized as
// the default single thread task runner of main thread. The
// viz::ContextProvider will call BindToCurrentSequence on |main_task_runner_|
// sequence of main thread. Then, the gpu context lost event will be called in
// the |main_task_runner_| sequence, which will be notified to the
// media::VideoCaptureGpuChannelHost.
class VideoCaptureServiceImpl::VizGpuContextProvider
    : public viz::ContextLostObserver {};
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) ||
        // BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_CHROMEOS_LACROS)
bool ShouldUseVCDFromAsh() {
  // LacrosService might be null in unit tests.
  auto* lacros_service = chromeos::LacrosService::Get();
  if (!lacros_service) {
    return false;
  }
  if (!lacros_service
           ->IsSupported<crosapi::mojom::VideoCaptureDeviceFactory>()) {
    return false;
  }
  // Fake VCD on Lacros side can be used only when using shared memory. Other
  // than this use case, try to use VCD on Ash side if possible.
  auto useLacrosFakeVCD = media::ShouldUseFakeVideoCaptureDeviceFactory() &&
                          !switches::IsVideoCaptureUseGpuMemoryBufferEnabled();
  return !useLacrosFakeVCD;
}
#endif

VideoCaptureServiceImpl::VideoCaptureServiceImpl(
    mojo::PendingReceiver<mojom::VideoCaptureService> receiver,
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
    bool create_system_monitor)
    :{}

VideoCaptureServiceImpl::~VideoCaptureServiceImpl() {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
void VideoCaptureServiceImpl::InjectGpuDependencies(
    mojo::PendingRemote<mojom::AcceleratorFactory> accelerator_factory) {
  LazyInitializeGpuDependenciesContext();
  gpu_dependencies_context_->GetTaskRunner()->PostTask(
      FROM_HERE, base::BindOnce(&GpuDependenciesContext::InjectGpuDependencies,
                                gpu_dependencies_context_->GetWeakPtr(),
                                std::move(accelerator_factory)));
}

void VideoCaptureServiceImpl::ConnectToCameraAppDeviceBridge(
    mojo::PendingReceiver<cros::mojom::CameraAppDeviceBridge> receiver) {
  LazyInitializeDeviceFactory();
  media::CameraAppDeviceBridgeImpl::GetInstance()->BindReceiver(
      std::move(receiver));
}

void VideoCaptureServiceImpl::BindVideoCaptureDeviceFactory(
    mojo::PendingReceiver<crosapi::mojom::VideoCaptureDeviceFactory> receiver) {
  LazyInitializeDeviceFactory();
  factory_receivers_ash_.Add(device_factory_ash_adapter_.get(),
                             std::move(receiver));
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

void VideoCaptureServiceImpl::ConnectToVideoSourceProvider(
    mojo::PendingReceiver<mojom::VideoSourceProvider> receiver) {}

void VideoCaptureServiceImpl::BindControlsForTesting(
    mojo::PendingReceiver<mojom::TestingControls> receiver) {}

void VideoCaptureServiceImpl::LazyInitializeGpuDependenciesContext() {}

void VideoCaptureServiceImpl::LazyInitializeDeviceFactory() {}

void VideoCaptureServiceImpl::LazyInitializeVideoSourceProvider() {}

void VideoCaptureServiceImpl::OnLastSourceProviderClientDisconnected() {}

void VideoCaptureServiceImpl::InitializeDeviceMonitor() {}

#if BUILDFLAG(IS_WIN)
void VideoCaptureServiceImpl::OnGpuInfoUpdate(const CHROME_LUID& luid) {
  LazyInitializeDeviceFactory();
  device_factory_->OnGpuInfoUpdate(luid);
}
#endif

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
void VideoCaptureServiceImpl::SetVizGpu(std::unique_ptr<viz::Gpu> viz_gpu) {}
#endif

#if BUILDFLAG(IS_CHROMEOS_LACROS)
void VideoCaptureServiceImpl::OnDisconnectedFromVCDFactoryAsh() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  video_source_provider_.reset();
  device_factory_.reset();
}
#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)

}  // namespace video_capture