| Index: services/video_capture/device_media_to_mojo_adapter.cc
|
| diff --git a/services/video_capture/device_media_to_mojo_adapter.cc b/services/video_capture/device_media_to_mojo_adapter.cc
|
| index ea7656a2efa153af72827e4d57c8035cc10fcfd5..837dcd8c4f0043c9ad8608ab4ac608b77caa8a87 100644
|
| --- a/services/video_capture/device_media_to_mojo_adapter.cc
|
| +++ b/services/video_capture/device_media_to_mojo_adapter.cc
|
| @@ -22,27 +22,40 @@ static const int kMaxBufferCount = 3;
|
| namespace video_capture {
|
|
|
| DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter(
|
| + std::unique_ptr<service_manager::ServiceContextRef> service_ref,
|
| std::unique_ptr<media::VideoCaptureDevice> device,
|
| const media::VideoCaptureJpegDecoderFactoryCB&
|
| jpeg_decoder_factory_callback)
|
| - : device_(std::move(device)),
|
| + : service_ref_(std::move(service_ref)),
|
| + device_(std::move(device)),
|
| jpeg_decoder_factory_callback_(jpeg_decoder_factory_callback),
|
| - device_running_(false) {}
|
| + device_started_(false) {}
|
|
|
| DeviceMediaToMojoAdapter::~DeviceMediaToMojoAdapter() {
|
| - if (device_running_)
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + if (device_started_)
|
| device_->StopAndDeAllocate();
|
| }
|
|
|
| void DeviceMediaToMojoAdapter::Start(
|
| const media::VideoCaptureParams& requested_settings,
|
| mojom::ReceiverPtr receiver) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| receiver.set_connection_error_handler(
|
| base::Bind(&DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose,
|
| base::Unretained(this)));
|
|
|
| - auto media_receiver =
|
| + auto receiver_adapter =
|
| base::MakeUnique<ReceiverMojoToMediaAdapter>(std::move(receiver));
|
| + // We must hold on something that allows us to unsubscribe from
|
| + // receiver.set_connection_error_handler() when we stop the device. Otherwise,
|
| + // we may receive a corresponding callback after having been destroyed.
|
| + // This happens when the deletion of |receiver| is delayed (scheduled to a
|
| + // task runner) when we release |device_|, as is the case when using
|
| + // ReceiverOnTaskRunner.
|
| + receiver_adapter_ptr_ = receiver_adapter.get();
|
| + auto media_receiver = base::MakeUnique<ReceiverOnTaskRunner>(
|
| + std::move(receiver_adapter), base::ThreadTaskRunnerHandle::Get());
|
|
|
| // Create a dedicated buffer pool for the device usage session.
|
| auto buffer_tracker_factory =
|
| @@ -55,23 +68,29 @@ void DeviceMediaToMojoAdapter::Start(
|
| std::move(media_receiver), buffer_pool, jpeg_decoder_factory_callback_);
|
|
|
| device_->AllocateAndStart(requested_settings, std::move(device_client));
|
| - device_running_ = true;
|
| + device_started_ = true;
|
| }
|
|
|
| void DeviceMediaToMojoAdapter::OnReceiverReportingUtilization(
|
| int32_t frame_feedback_id,
|
| double utilization) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| device_->OnUtilizationReport(frame_feedback_id, utilization);
|
| }
|
|
|
| void DeviceMediaToMojoAdapter::Stop() {
|
| - if (device_running_ == false)
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + if (device_started_ == false)
|
| return;
|
| - device_running_ = false;
|
| + device_started_ = false;
|
| + // Unsubscribe from connection error callbacks.
|
| + receiver_adapter_ptr_->ResetConnectionErrorHandler();
|
| + receiver_adapter_ptr_ = nullptr;
|
| device_->StopAndDeAllocate();
|
| }
|
|
|
| void DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| Stop();
|
| }
|
|
|
|
|