device_media_to_mojo_adapter.cc 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright 2016 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/device_media_to_mojo_adapter.h"
  5. #include "base/bind.h"
  6. #include "base/check.h"
  7. #include "base/threading/thread_task_runner_handle.h"
  8. #include "base/trace_event/trace_event.h"
  9. #include "build/build_config.h"
  10. #include "build/chromeos_buildflags.h"
  11. #include "media/base/bind_to_current_loop.h"
  12. #include "media/base/scoped_async_trace.h"
  13. #include "media/capture/video/video_capture_buffer_pool_impl.h"
  14. #include "media/capture/video/video_capture_buffer_pool_util.h"
  15. #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
  16. #include "media/capture/video/video_frame_receiver_on_task_runner.h"
  17. #include "mojo/public/cpp/bindings/callback_helpers.h"
  18. #include "services/video_capture/public/cpp/receiver_mojo_to_media_adapter.h"
  19. #if BUILDFLAG(IS_CHROMEOS_ASH)
  20. #include "media/capture/video/chromeos/scoped_video_capture_jpeg_decoder.h"
  21. #include "media/capture/video/chromeos/video_capture_jpeg_decoder_impl.h"
  22. #elif BUILDFLAG(IS_WIN)
  23. #include "media/capture/video/win/video_capture_buffer_tracker_factory_win.h"
  24. #include "media/capture/video/win/video_capture_device_factory_win.h"
  25. #endif
  26. namespace {
  27. using ScopedCaptureTrace =
  28. media::TypedScopedAsyncTrace<media::TraceCategory::kVideoAndImageCapture>;
  29. #if BUILDFLAG(IS_CHROMEOS_ASH)
  30. std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
  31. scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
  32. media::MojoMjpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback,
  33. media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb,
  34. base::RepeatingCallback<void(const std::string&)> send_log_message_cb) {
  35. return std::make_unique<media::ScopedVideoCaptureJpegDecoder>(
  36. std::make_unique<media::VideoCaptureJpegDecoderImpl>(
  37. jpeg_decoder_factory_callback, decoder_task_runner,
  38. std::move(decode_done_cb), std::move(send_log_message_cb)),
  39. decoder_task_runner);
  40. }
  41. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  42. void TakePhotoCallbackTrampoline(
  43. media::VideoCaptureDevice::TakePhotoCallback callback,
  44. std::unique_ptr<ScopedCaptureTrace> trace,
  45. media::mojom::BlobPtr blob) {
  46. std::move(callback).Run(std::move(blob));
  47. }
  48. } // anonymous namespace
  49. namespace video_capture {
  50. #if BUILDFLAG(IS_CHROMEOS_ASH)
  51. DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter(
  52. std::unique_ptr<media::VideoCaptureDevice> device,
  53. media::MojoMjpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback,
  54. scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner)
  55. : device_(std::move(device)),
  56. jpeg_decoder_factory_callback_(std::move(jpeg_decoder_factory_callback)),
  57. jpeg_decoder_task_runner_(std::move(jpeg_decoder_task_runner)) {}
  58. #elif BUILDFLAG(IS_WIN)
  59. DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter(
  60. std::unique_ptr<media::VideoCaptureDevice> device,
  61. media::VideoCaptureDeviceFactory* factory)
  62. : device_(std::move(device)),
  63. device_started_(false),
  64. dxgi_device_manager_(factory ? factory->GetDxgiDeviceManager()
  65. : nullptr) {}
  66. #else
  67. DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter(
  68. std::unique_ptr<media::VideoCaptureDevice> device)
  69. : device_(std::move(device)), device_started_(false) {}
  70. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  71. DeviceMediaToMojoAdapter::~DeviceMediaToMojoAdapter() {
  72. DCHECK(thread_checker_.CalledOnValidThread());
  73. if (device_started_)
  74. device_->StopAndDeAllocate();
  75. }
  76. void DeviceMediaToMojoAdapter::Start(
  77. const media::VideoCaptureParams& requested_settings,
  78. mojo::PendingRemote<mojom::VideoFrameHandler>
  79. video_frame_handler_pending_remote) {
  80. DCHECK(thread_checker_.CalledOnValidThread());
  81. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
  82. "DeviceMediaToMojoAdapter::Start");
  83. mojo::Remote<mojom::VideoFrameHandler> handler_remote(
  84. std::move(video_frame_handler_pending_remote));
  85. handler_remote.set_disconnect_handler(
  86. base::BindOnce(&DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose,
  87. weak_factory_.GetWeakPtr()));
  88. receiver_ =
  89. std::make_unique<ReceiverMojoToMediaAdapter>(std::move(handler_remote));
  90. auto media_receiver = std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
  91. receiver_->GetWeakPtr(), base::ThreadTaskRunnerHandle::Get());
  92. if (requested_settings.buffer_type !=
  93. media::VideoCaptureBufferType::kSharedMemory &&
  94. requested_settings.buffer_type !=
  95. media::VideoCaptureBufferType::kGpuMemoryBuffer &&
  96. requested_settings.buffer_type !=
  97. media::VideoCaptureBufferType::kSharedMemoryViaRawFileDescriptor) {
  98. // Buffer types other than shared memory are not supported.
  99. media_receiver->OnError(
  100. media::VideoCaptureError::
  101. kDeviceMediaToMojoAdapterEncounteredUnsupportedBufferType);
  102. return;
  103. }
  104. scoped_refptr<media::VideoCaptureBufferPool> buffer_pool;
  105. {
  106. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
  107. "CreateVideoCaptureBufferPoolImpl");
  108. // Create a dedicated buffer pool for the device usage session.
  109. #if BUILDFLAG(IS_WIN)
  110. buffer_pool = base::MakeRefCounted<media::VideoCaptureBufferPoolImpl>(
  111. requested_settings.buffer_type, max_buffer_pool_buffer_count(),
  112. std::make_unique<media::VideoCaptureBufferTrackerFactoryWin>(
  113. dxgi_device_manager_));
  114. #else
  115. buffer_pool = base::MakeRefCounted<media::VideoCaptureBufferPoolImpl>(
  116. requested_settings.buffer_type, max_buffer_pool_buffer_count());
  117. #endif
  118. }
  119. #if BUILDFLAG(IS_CHROMEOS_ASH)
  120. auto device_client = std::make_unique<media::VideoCaptureDeviceClient>(
  121. requested_settings.buffer_type, std::move(media_receiver), buffer_pool,
  122. base::BindRepeating(
  123. &CreateGpuJpegDecoder, jpeg_decoder_task_runner_,
  124. jpeg_decoder_factory_callback_,
  125. media::BindToCurrentLoop(base::BindRepeating(
  126. &media::VideoFrameReceiver::OnFrameReadyInBuffer,
  127. receiver_->GetWeakPtr())),
  128. media::BindToCurrentLoop(base::BindRepeating(
  129. &media::VideoFrameReceiver::OnLog, receiver_->GetWeakPtr()))));
  130. #else
  131. auto device_client = std::make_unique<media::VideoCaptureDeviceClient>(
  132. requested_settings.buffer_type, std::move(media_receiver), buffer_pool);
  133. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  134. device_->AllocateAndStart(requested_settings, std::move(device_client));
  135. device_started_ = true;
  136. }
  137. void DeviceMediaToMojoAdapter::MaybeSuspend() {
  138. if (!device_started_)
  139. return;
  140. device_->MaybeSuspend();
  141. }
  142. void DeviceMediaToMojoAdapter::Resume() {
  143. if (!device_started_)
  144. return;
  145. device_->Resume();
  146. }
  147. void DeviceMediaToMojoAdapter::GetPhotoState(GetPhotoStateCallback callback) {
  148. media::VideoCaptureDevice::GetPhotoStateCallback scoped_callback =
  149. mojo::WrapCallbackWithDefaultInvokeIfNotRun(
  150. media::BindToCurrentLoop(std::move(callback)), nullptr);
  151. device_->GetPhotoState(std::move(scoped_callback));
  152. }
  153. void DeviceMediaToMojoAdapter::SetPhotoOptions(
  154. media::mojom::PhotoSettingsPtr settings,
  155. SetPhotoOptionsCallback callback) {
  156. media::mojom::ImageCapture::SetOptionsCallback scoped_callback =
  157. mojo::WrapCallbackWithDefaultInvokeIfNotRun(
  158. media::BindToCurrentLoop(std::move(callback)), false);
  159. device_->SetPhotoOptions(std::move(settings), std::move(scoped_callback));
  160. }
  161. void DeviceMediaToMojoAdapter::TakePhoto(TakePhotoCallback callback) {
  162. auto scoped_trace = ScopedCaptureTrace::CreateIfEnabled("TakePhoto");
  163. media::mojom::ImageCapture::TakePhotoCallback scoped_callback =
  164. mojo::WrapCallbackWithDefaultInvokeIfNotRun(
  165. media::BindToCurrentLoop(base::BindOnce(&TakePhotoCallbackTrampoline,
  166. std::move(callback),
  167. std::move(scoped_trace))),
  168. nullptr);
  169. device_->TakePhoto(std::move(scoped_callback));
  170. }
  171. void DeviceMediaToMojoAdapter::ProcessFeedback(
  172. const media::VideoCaptureFeedback& feedback) {
  173. // Feedback ID may not propagated by mojo interface.
  174. device_->OnUtilizationReport(feedback);
  175. }
  176. void DeviceMediaToMojoAdapter::RequestRefreshFrame() {
  177. device_->RequestRefreshFrame();
  178. }
  179. void DeviceMediaToMojoAdapter::Stop() {
  180. DCHECK(thread_checker_.CalledOnValidThread());
  181. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
  182. "DeviceMediaToMojoAdapter::Stop");
  183. if (!device_started_)
  184. return;
  185. device_started_ = false;
  186. weak_factory_.InvalidateWeakPtrs();
  187. device_->StopAndDeAllocate();
  188. // We need to post the deletion of receiver to the end of the message queue,
  189. // because |device_->StopAndDeAllocate()| may post messages (e.g.
  190. // OnBufferRetired()) to a WeakPtr to |receiver_| to this queue,
  191. // and we need those messages to be sent before we invalidate the WeakPtr.
  192. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
  193. std::move(receiver_));
  194. }
  195. void DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose() {
  196. DCHECK(thread_checker_.CalledOnValidThread());
  197. Stop();
  198. }
  199. // static
  200. int DeviceMediaToMojoAdapter::max_buffer_pool_buffer_count() {
  201. return media::DeviceVideoCaptureMaxBufferPoolSize();
  202. }
  203. } // namespace video_capture