123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "services/video_capture/device_media_to_mojo_adapter.h"
- #include "base/bind.h"
- #include "base/check.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/trace_event/trace_event.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.h"
- #include "media/base/bind_to_current_loop.h"
- #include "media/base/scoped_async_trace.h"
- #include "media/capture/video/video_capture_buffer_pool_impl.h"
- #include "media/capture/video/video_capture_buffer_pool_util.h"
- #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
- #include "media/capture/video/video_frame_receiver_on_task_runner.h"
- #include "mojo/public/cpp/bindings/callback_helpers.h"
- #include "services/video_capture/public/cpp/receiver_mojo_to_media_adapter.h"
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- #include "media/capture/video/chromeos/scoped_video_capture_jpeg_decoder.h"
- #include "media/capture/video/chromeos/video_capture_jpeg_decoder_impl.h"
- #elif BUILDFLAG(IS_WIN)
- #include "media/capture/video/win/video_capture_buffer_tracker_factory_win.h"
- #include "media/capture/video/win/video_capture_device_factory_win.h"
- #endif
- namespace {
- using ScopedCaptureTrace =
- media::TypedScopedAsyncTrace<media::TraceCategory::kVideoAndImageCapture>;
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
- scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
- media::MojoMjpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback,
- media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb,
- base::RepeatingCallback<void(const std::string&)> send_log_message_cb) {
- return std::make_unique<media::ScopedVideoCaptureJpegDecoder>(
- std::make_unique<media::VideoCaptureJpegDecoderImpl>(
- jpeg_decoder_factory_callback, decoder_task_runner,
- std::move(decode_done_cb), std::move(send_log_message_cb)),
- decoder_task_runner);
- }
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- void TakePhotoCallbackTrampoline(
- media::VideoCaptureDevice::TakePhotoCallback callback,
- std::unique_ptr<ScopedCaptureTrace> trace,
- media::mojom::BlobPtr blob) {
- std::move(callback).Run(std::move(blob));
- }
- } // anonymous namespace
- namespace video_capture {
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter(
- std::unique_ptr<media::VideoCaptureDevice> device,
- media::MojoMjpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback,
- scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner)
- : device_(std::move(device)),
- jpeg_decoder_factory_callback_(std::move(jpeg_decoder_factory_callback)),
- jpeg_decoder_task_runner_(std::move(jpeg_decoder_task_runner)) {}
- #elif BUILDFLAG(IS_WIN)
- DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter(
- std::unique_ptr<media::VideoCaptureDevice> device,
- media::VideoCaptureDeviceFactory* factory)
- : device_(std::move(device)),
- device_started_(false),
- dxgi_device_manager_(factory ? factory->GetDxgiDeviceManager()
- : nullptr) {}
- #else
- DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter(
- std::unique_ptr<media::VideoCaptureDevice> device)
- : device_(std::move(device)), device_started_(false) {}
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- DeviceMediaToMojoAdapter::~DeviceMediaToMojoAdapter() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (device_started_)
- device_->StopAndDeAllocate();
- }
- void DeviceMediaToMojoAdapter::Start(
- const media::VideoCaptureParams& requested_settings,
- mojo::PendingRemote<mojom::VideoFrameHandler>
- video_frame_handler_pending_remote) {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
- "DeviceMediaToMojoAdapter::Start");
- mojo::Remote<mojom::VideoFrameHandler> handler_remote(
- std::move(video_frame_handler_pending_remote));
- handler_remote.set_disconnect_handler(
- base::BindOnce(&DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose,
- weak_factory_.GetWeakPtr()));
- receiver_ =
- std::make_unique<ReceiverMojoToMediaAdapter>(std::move(handler_remote));
- auto media_receiver = std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
- receiver_->GetWeakPtr(), base::ThreadTaskRunnerHandle::Get());
- if (requested_settings.buffer_type !=
- media::VideoCaptureBufferType::kSharedMemory &&
- requested_settings.buffer_type !=
- media::VideoCaptureBufferType::kGpuMemoryBuffer &&
- requested_settings.buffer_type !=
- media::VideoCaptureBufferType::kSharedMemoryViaRawFileDescriptor) {
- // Buffer types other than shared memory are not supported.
- media_receiver->OnError(
- media::VideoCaptureError::
- kDeviceMediaToMojoAdapterEncounteredUnsupportedBufferType);
- return;
- }
- scoped_refptr<media::VideoCaptureBufferPool> buffer_pool;
- {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
- "CreateVideoCaptureBufferPoolImpl");
- // Create a dedicated buffer pool for the device usage session.
- #if BUILDFLAG(IS_WIN)
- buffer_pool = base::MakeRefCounted<media::VideoCaptureBufferPoolImpl>(
- requested_settings.buffer_type, max_buffer_pool_buffer_count(),
- std::make_unique<media::VideoCaptureBufferTrackerFactoryWin>(
- dxgi_device_manager_));
- #else
- buffer_pool = base::MakeRefCounted<media::VideoCaptureBufferPoolImpl>(
- requested_settings.buffer_type, max_buffer_pool_buffer_count());
- #endif
- }
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- auto device_client = std::make_unique<media::VideoCaptureDeviceClient>(
- requested_settings.buffer_type, std::move(media_receiver), buffer_pool,
- base::BindRepeating(
- &CreateGpuJpegDecoder, jpeg_decoder_task_runner_,
- jpeg_decoder_factory_callback_,
- media::BindToCurrentLoop(base::BindRepeating(
- &media::VideoFrameReceiver::OnFrameReadyInBuffer,
- receiver_->GetWeakPtr())),
- media::BindToCurrentLoop(base::BindRepeating(
- &media::VideoFrameReceiver::OnLog, receiver_->GetWeakPtr()))));
- #else
- auto device_client = std::make_unique<media::VideoCaptureDeviceClient>(
- requested_settings.buffer_type, std::move(media_receiver), buffer_pool);
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- device_->AllocateAndStart(requested_settings, std::move(device_client));
- device_started_ = true;
- }
- void DeviceMediaToMojoAdapter::MaybeSuspend() {
- if (!device_started_)
- return;
- device_->MaybeSuspend();
- }
- void DeviceMediaToMojoAdapter::Resume() {
- if (!device_started_)
- return;
- device_->Resume();
- }
- void DeviceMediaToMojoAdapter::GetPhotoState(GetPhotoStateCallback callback) {
- media::VideoCaptureDevice::GetPhotoStateCallback scoped_callback =
- mojo::WrapCallbackWithDefaultInvokeIfNotRun(
- media::BindToCurrentLoop(std::move(callback)), nullptr);
- device_->GetPhotoState(std::move(scoped_callback));
- }
- void DeviceMediaToMojoAdapter::SetPhotoOptions(
- media::mojom::PhotoSettingsPtr settings,
- SetPhotoOptionsCallback callback) {
- media::mojom::ImageCapture::SetOptionsCallback scoped_callback =
- mojo::WrapCallbackWithDefaultInvokeIfNotRun(
- media::BindToCurrentLoop(std::move(callback)), false);
- device_->SetPhotoOptions(std::move(settings), std::move(scoped_callback));
- }
- void DeviceMediaToMojoAdapter::TakePhoto(TakePhotoCallback callback) {
- auto scoped_trace = ScopedCaptureTrace::CreateIfEnabled("TakePhoto");
- media::mojom::ImageCapture::TakePhotoCallback scoped_callback =
- mojo::WrapCallbackWithDefaultInvokeIfNotRun(
- media::BindToCurrentLoop(base::BindOnce(&TakePhotoCallbackTrampoline,
- std::move(callback),
- std::move(scoped_trace))),
- nullptr);
- device_->TakePhoto(std::move(scoped_callback));
- }
- void DeviceMediaToMojoAdapter::ProcessFeedback(
- const media::VideoCaptureFeedback& feedback) {
- // Feedback ID may not propagated by mojo interface.
- device_->OnUtilizationReport(feedback);
- }
- void DeviceMediaToMojoAdapter::RequestRefreshFrame() {
- device_->RequestRefreshFrame();
- }
- void DeviceMediaToMojoAdapter::Stop() {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
- "DeviceMediaToMojoAdapter::Stop");
- if (!device_started_)
- return;
- device_started_ = false;
- weak_factory_.InvalidateWeakPtrs();
- device_->StopAndDeAllocate();
- // We need to post the deletion of receiver to the end of the message queue,
- // because |device_->StopAndDeAllocate()| may post messages (e.g.
- // OnBufferRetired()) to a WeakPtr to |receiver_| to this queue,
- // and we need those messages to be sent before we invalidate the WeakPtr.
- base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
- std::move(receiver_));
- }
- void DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose() {
- DCHECK(thread_checker_.CalledOnValidThread());
- Stop();
- }
- // static
- int DeviceMediaToMojoAdapter::max_buffer_pool_buffer_count() {
- return media::DeviceVideoCaptureMaxBufferPoolSize();
- }
- } // namespace video_capture
|