video_capture_service_impl.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/video_capture/video_capture_service_impl.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/feature_list.h"
  8. #include "base/task/thread_pool.h"
  9. #include "build/build_config.h"
  10. #include "build/chromeos_buildflags.h"
  11. #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
  12. #include "media/capture/video/create_video_capture_device_factory.h"
  13. #include "media/capture/video/fake_video_capture_device_factory.h"
  14. #include "media/capture/video/video_capture_buffer_pool.h"
  15. #include "media/capture/video/video_capture_buffer_tracker.h"
  16. #include "media/capture/video/video_capture_system_impl.h"
  17. #include "mojo/public/cpp/bindings/pending_receiver.h"
  18. #include "mojo/public/cpp/bindings/pending_remote.h"
  19. #include "mojo/public/cpp/bindings/remote.h"
  20. #include "mojo/public/cpp/bindings/self_owned_receiver.h"
  21. #include "services/video_capture/device_factory_media_to_mojo_adapter.h"
  22. #include "services/video_capture/testing_controls_impl.h"
  23. #include "services/video_capture/video_source_provider_impl.h"
  24. #include "services/video_capture/virtual_device_enabled_device_factory.h"
  25. #include "services/viz/public/cpp/gpu/gpu.h"
  26. #if BUILDFLAG(IS_MAC)
  27. #include "media/capture/video/mac/video_capture_device_factory_mac.h"
  28. #endif
  29. #if BUILDFLAG(IS_CHROMEOS_ASH)
  30. #include "media/capture/video/chromeos/camera_app_device_bridge_impl.h"
  31. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  32. #if BUILDFLAG(IS_CHROMEOS_LACROS)
  33. #include "chromeos/crosapi/mojom/video_capture.mojom.h"
  34. #include "chromeos/lacros/lacros_service.h"
  35. #include "services/video_capture/lacros/device_factory_adapter_lacros.h"
  36. #endif // BUILDFLAG(IS_CHROMEOS_LACROS)
  37. namespace video_capture {
  38. // Intended usage of this class is to instantiate on any sequence, and then
  39. // operate and release the instance on the task runner exposed via
  40. // GetTaskRunner() via WeakPtrs provided via GetWeakPtr(). To this end,
  41. // GetTaskRunner() and GetWeakPtr() can be called from any sequence, typically
  42. // the same as the one calling the constructor.
  43. class VideoCaptureServiceImpl::GpuDependenciesContext {
  44. public:
  45. GpuDependenciesContext() {
  46. gpu_io_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
  47. {base::TaskPriority::USER_BLOCKING, base::MayBlock()});
  48. }
  49. ~GpuDependenciesContext() {
  50. DCHECK(gpu_io_task_runner_->RunsTasksInCurrentSequence());
  51. }
  52. base::WeakPtr<GpuDependenciesContext> GetWeakPtr() {
  53. return weak_factory_for_gpu_io_thread_.GetWeakPtr();
  54. }
  55. scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() {
  56. return gpu_io_task_runner_;
  57. }
  58. #if BUILDFLAG(IS_CHROMEOS_ASH)
  59. void InjectGpuDependencies(
  60. mojo::PendingRemote<mojom::AcceleratorFactory> accelerator_factory_info) {
  61. DCHECK(gpu_io_task_runner_->RunsTasksInCurrentSequence());
  62. accelerator_factory_.reset();
  63. accelerator_factory_.Bind(std::move(accelerator_factory_info));
  64. }
  65. void CreateJpegDecodeAccelerator(
  66. mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator>
  67. receiver) {
  68. DCHECK(gpu_io_task_runner_->RunsTasksInCurrentSequence());
  69. if (!accelerator_factory_)
  70. return;
  71. accelerator_factory_->CreateJpegDecodeAccelerator(std::move(receiver));
  72. }
  73. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  74. private:
  75. // Task runner for operating |accelerator_factory_| and
  76. // |gpu_memory_buffer_manager_| on. This must be a different thread from the
  77. // main service thread in order to avoid a deadlock during shutdown where
  78. // the main service thread joins a video capture device thread that, in turn,
  79. // will try to post the release of the jpeg decoder to the thread it is
  80. // operated on.
  81. scoped_refptr<base::SequencedTaskRunner> gpu_io_task_runner_;
  82. #if BUILDFLAG(IS_CHROMEOS_ASH)
  83. mojo::Remote<mojom::AcceleratorFactory> accelerator_factory_;
  84. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  85. base::WeakPtrFactory<GpuDependenciesContext> weak_factory_for_gpu_io_thread_{
  86. this};
  87. };
  88. VideoCaptureServiceImpl::VideoCaptureServiceImpl(
  89. mojo::PendingReceiver<mojom::VideoCaptureService> receiver,
  90. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
  91. : receiver_(this, std::move(receiver)),
  92. ui_task_runner_(std::move(ui_task_runner)) {}
  93. VideoCaptureServiceImpl::~VideoCaptureServiceImpl() {
  94. factory_receivers_.Clear();
  95. device_factory_.reset();
  96. if (gpu_dependencies_context_) {
  97. gpu_dependencies_context_->GetTaskRunner()->DeleteSoon(
  98. FROM_HERE, std::move(gpu_dependencies_context_));
  99. }
  100. }
  101. #if BUILDFLAG(IS_CHROMEOS_ASH)
  102. void VideoCaptureServiceImpl::InjectGpuDependencies(
  103. mojo::PendingRemote<mojom::AcceleratorFactory> accelerator_factory) {
  104. LazyInitializeGpuDependenciesContext();
  105. gpu_dependencies_context_->GetTaskRunner()->PostTask(
  106. FROM_HERE, base::BindOnce(&GpuDependenciesContext::InjectGpuDependencies,
  107. gpu_dependencies_context_->GetWeakPtr(),
  108. std::move(accelerator_factory)));
  109. }
  110. void VideoCaptureServiceImpl::ConnectToCameraAppDeviceBridge(
  111. mojo::PendingReceiver<cros::mojom::CameraAppDeviceBridge> receiver) {
  112. LazyInitializeDeviceFactory();
  113. media::CameraAppDeviceBridgeImpl::GetInstance()->BindReceiver(
  114. std::move(receiver));
  115. }
  116. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  117. void VideoCaptureServiceImpl::ConnectToDeviceFactory(
  118. mojo::PendingReceiver<mojom::DeviceFactory> receiver) {
  119. LazyInitializeDeviceFactory();
  120. factory_receivers_.Add(device_factory_.get(), std::move(receiver));
  121. }
  122. void VideoCaptureServiceImpl::ConnectToVideoSourceProvider(
  123. mojo::PendingReceiver<mojom::VideoSourceProvider> receiver) {
  124. LazyInitializeVideoSourceProvider();
  125. video_source_provider_->AddClient(std::move(receiver));
  126. }
  127. void VideoCaptureServiceImpl::SetRetryCount(int32_t count) {
  128. #if BUILDFLAG(IS_MAC)
  129. media::VideoCaptureDeviceFactoryMac::SetGetDevicesInfoRetryCount(count);
  130. #endif
  131. }
  132. void VideoCaptureServiceImpl::BindControlsForTesting(
  133. mojo::PendingReceiver<mojom::TestingControls> receiver) {
  134. mojo::MakeSelfOwnedReceiver(std::make_unique<TestingControlsImpl>(),
  135. std::move(receiver));
  136. }
  137. void VideoCaptureServiceImpl::LazyInitializeGpuDependenciesContext() {
  138. if (!gpu_dependencies_context_)
  139. gpu_dependencies_context_ = std::make_unique<GpuDependenciesContext>();
  140. }
  141. void VideoCaptureServiceImpl::LazyInitializeDeviceFactory() {
  142. if (device_factory_)
  143. return;
  144. LazyInitializeGpuDependenciesContext();
  145. // Create the platform-specific device factory.
  146. // The task runner passed to CreateFactory is used for things that need to
  147. // happen on a "UI thread equivalent", e.g. obtaining screen rotation on
  148. // Chrome OS.
  149. std::unique_ptr<media::VideoCaptureDeviceFactory> media_device_factory =
  150. media::CreateVideoCaptureDeviceFactory(ui_task_runner_);
  151. auto video_capture_system = std::make_unique<media::VideoCaptureSystemImpl>(
  152. std::move(media_device_factory));
  153. #if BUILDFLAG(IS_CHROMEOS_ASH)
  154. device_factory_ = std::make_unique<VirtualDeviceEnabledDeviceFactory>(
  155. std::make_unique<DeviceFactoryMediaToMojoAdapter>(
  156. std::move(video_capture_system),
  157. base::BindRepeating(
  158. &GpuDependenciesContext::CreateJpegDecodeAccelerator,
  159. gpu_dependencies_context_->GetWeakPtr()),
  160. gpu_dependencies_context_->GetTaskRunner()));
  161. #elif BUILDFLAG(IS_CHROMEOS_LACROS)
  162. // LacrosService might be null in unit tests.
  163. auto* lacros_service = chromeos::LacrosService::Get();
  164. // For requests for fake (including file) video capture device factory, we
  165. // don't need to forward the request to Ash-Chrome.
  166. if (!media::ShouldUseFakeVideoCaptureDeviceFactory() && lacros_service &&
  167. lacros_service->IsVideoCaptureDeviceFactoryAvailable()) {
  168. mojo::PendingRemote<crosapi::mojom::VideoCaptureDeviceFactory>
  169. device_factory_ash;
  170. lacros_service->BindVideoCaptureDeviceFactory(
  171. device_factory_ash.InitWithNewPipeAndPassReceiver());
  172. device_factory_ = std::make_unique<VirtualDeviceEnabledDeviceFactory>(
  173. std::make_unique<DeviceFactoryAdapterLacros>(
  174. std::move(device_factory_ash)));
  175. } else {
  176. LOG(WARNING)
  177. << "Connected to an older version of ash. Use device factory in "
  178. "Lacros-Chrome which is backed by Linux VCD instead of CrOS VCD.";
  179. device_factory_ = std::make_unique<VirtualDeviceEnabledDeviceFactory>(
  180. std::make_unique<DeviceFactoryMediaToMojoAdapter>(
  181. std::move(video_capture_system)));
  182. }
  183. #else
  184. device_factory_ = std::make_unique<VirtualDeviceEnabledDeviceFactory>(
  185. std::make_unique<DeviceFactoryMediaToMojoAdapter>(
  186. std::move(video_capture_system)));
  187. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  188. }
  189. void VideoCaptureServiceImpl::LazyInitializeVideoSourceProvider() {
  190. if (video_source_provider_)
  191. return;
  192. LazyInitializeDeviceFactory();
  193. video_source_provider_ = std::make_unique<VideoSourceProviderImpl>(
  194. device_factory_.get(),
  195. // Unretained(this) is safe, because |this| owns |video_source_provider_|.
  196. base::BindRepeating(
  197. &VideoCaptureServiceImpl::OnLastSourceProviderClientDisconnected,
  198. base::Unretained(this)));
  199. }
  200. void VideoCaptureServiceImpl::OnLastSourceProviderClientDisconnected() {
  201. video_source_provider_.reset();
  202. }
  203. #if BUILDFLAG(IS_WIN)
  204. void VideoCaptureServiceImpl::OnGpuInfoUpdate(const CHROME_LUID& luid) {
  205. LazyInitializeDeviceFactory();
  206. device_factory_->OnGpuInfoUpdate(luid);
  207. }
  208. #endif
  209. } // namespace video_capture