 Chromium Code Reviews
 Chromium Code Reviews Issue 2753073006:
  [Mojo Video Capture] Add support to BuildableVideoCaptureDevice for aborting the device start.  (Closed)
    
  
    Issue 2753073006:
  [Mojo Video Capture] Add support to BuildableVideoCaptureDevice for aborting the device start.  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "content/browser/renderer_host/media/in_process_buildable_video_capture _device.h" | 5 #include "content/browser/renderer_host/media/in_process_buildable_video_capture _device.h" | 
| 6 | 6 | 
| 7 #include "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" | 
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" | 
| 9 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" | 9 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" | 
| 10 #include "content/browser/media/capture/web_contents_video_capture_device.h" | 10 #include "content/browser/media/capture/web_contents_video_capture_device.h" | 
| 11 #include "content/browser/renderer_host/media/ownership.h" | |
| 11 #include "content/browser/renderer_host/media/video_capture_controller.h" | 12 #include "content/browser/renderer_host/media/video_capture_controller.h" | 
| 12 #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" | 13 #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" | 
| 13 #include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread. h" | 14 #include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread. h" | 
| 14 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" | 
| 15 #include "content/public/browser/desktop_media_id.h" | 16 #include "content/public/browser/desktop_media_id.h" | 
| 16 #include "content/public/common/media_stream_request.h" | 17 #include "content/public/common/media_stream_request.h" | 
| 17 #include "media/base/bind_to_current_loop.h" | 18 #include "media/base/bind_to_current_loop.h" | 
| 18 #include "media/capture/video/video_capture_buffer_pool_impl.h" | 19 #include "media/capture/video/video_capture_buffer_pool_impl.h" | 
| 19 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" | 20 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" | 
| 20 #include "media/capture/video/video_capture_device_client.h" | 21 #include "media/capture/video/video_capture_device_client.h" | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 93 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 93 DCHECK(!device_); | 94 DCHECK(!device_); | 
| 94 } | 95 } | 
| 95 | 96 | 
| 96 void InProcessBuildableVideoCaptureDevice::CreateAndStartDeviceAsync( | 97 void InProcessBuildableVideoCaptureDevice::CreateAndStartDeviceAsync( | 
| 97 VideoCaptureController* controller, | 98 VideoCaptureController* controller, | 
| 98 const media::VideoCaptureParams& params, | 99 const media::VideoCaptureParams& params, | 
| 99 BuildableDeviceCallbacks* callbacks, | 100 BuildableDeviceCallbacks* callbacks, | 
| 100 std::unique_ptr<Ownership> context_reference) { | 101 std::unique_ptr<Ownership> context_reference) { | 
| 101 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 102 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 103 DCHECK(state_ == State::NO_DEVICE); | |
| 102 | 104 | 
| 103 const int max_buffers = (controller->stream_type() == MEDIA_TAB_VIDEO_CAPTURE | 105 const int max_buffers = (controller->stream_type() == MEDIA_TAB_VIDEO_CAPTURE | 
| 104 ? kMaxNumberOfBuffersForTabCapture | 106 ? kMaxNumberOfBuffersForTabCapture | 
| 105 : kMaxNumberOfBuffers); | 107 : kMaxNumberOfBuffers); | 
| 106 | 108 | 
| 107 auto device_client = | 109 auto device_client = | 
| 108 CreateDeviceClient(max_buffers, controller->GetWeakPtrForIOThread()); | 110 CreateDeviceClient(max_buffers, controller->GetWeakPtrForIOThread()); | 
| 109 | 111 | 
| 110 base::Closure start_capture_closure; | 112 base::Closure start_capture_closure; | 
| 111 // Use of Unretained() is safe, because |context_reference| guarantees that | 113 // Use of Unretained() is safe, because |context_reference| guarantees that | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 std::move(after_start_capture_callback)); | 160 std::move(after_start_capture_callback)); | 
| 159 break; | 161 break; | 
| 160 | 162 | 
| 161 default: { | 163 default: { | 
| 162 NOTIMPLEMENTED(); | 164 NOTIMPLEMENTED(); | 
| 163 return; | 165 return; | 
| 164 } | 166 } | 
| 165 } | 167 } | 
| 166 | 168 | 
| 167 device_task_runner_->PostTask(FROM_HERE, start_capture_closure); | 169 device_task_runner_->PostTask(FROM_HERE, start_capture_closure); | 
| 170 state_ = State::DEVICE_START_IN_PROGRESS; | |
| 168 } | 171 } | 
| 169 | 172 | 
| 170 void InProcessBuildableVideoCaptureDevice::ReleaseDeviceAsync( | 173 void InProcessBuildableVideoCaptureDevice::ReleaseDeviceAsync( | 
| 171 VideoCaptureController* controller, | 174 VideoCaptureController* controller, | 
| 172 std::unique_ptr<Ownership>) { | 175 std::unique_ptr<Ownership>) { | 
| 173 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 176 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 174 controller->SetConsumerFeedbackObserver(nullptr); | 177 controller->SetConsumerFeedbackObserver(nullptr); | 
| 175 if (!device_) | 178 switch (state_) { | 
| 176 return; | 179 case State::DEVICE_START_IN_PROGRESS: | 
| 177 media::VideoCaptureDevice* device_ptr = device_.release(); | 180 state_ = State::DEVICE_START_ABORTING; | 
| 178 auto device_task_runner_context_reference = | 181 return; | 
| 179 MakeScopedRefptrOwnership(device_task_runner_); | 182 case State::NO_DEVICE: | 
| 180 bool posting_task_succeeded = device_task_runner_->PostTask( | 183 case State::DEVICE_START_ABORTING: | 
| 181 FROM_HERE, | 184 return; | 
| 182 base::Bind(&StopAndReleaseDeviceOnDeviceThread, device_ptr, | 185 case State::DEVICE_STARTED: | 
| 183 base::Passed(&device_task_runner_context_reference))); | 186 media::VideoCaptureDevice* device_ptr = device_.release(); | 
| 184 if (posting_task_succeeded == false) { | 187 auto device_task_runner_context_reference = | 
| 185 // Since posting to the task runner has failed, we attempt doing it on | 188 MakeScopedRefptrOwnership(device_task_runner_); | 
| 186 // the calling thread instead. | 189 bool posting_task_succeeded = device_task_runner_->PostTask( | 
| 187 StopAndReleaseDeviceOnDeviceThread(device_ptr, nullptr); | 190 FROM_HERE, | 
| 191 base::Bind(&StopAndReleaseDeviceOnDeviceThread, device_ptr, | |
| 192 base::Passed(&device_task_runner_context_reference))); | |
| 193 if (posting_task_succeeded == false) { | |
| 194 // Since posting to the task runner has failed, we attempt doing it on | |
| 195 // the calling thread instead. | |
| 196 StopAndReleaseDeviceOnDeviceThread(device_ptr, nullptr); | |
| 197 } | |
| 198 state_ = State::NO_DEVICE; | |
| 199 return; | |
| 188 } | 200 } | 
| 189 } | 201 } | 
| 190 | 202 | 
| 191 bool InProcessBuildableVideoCaptureDevice::IsDeviceAlive() const { | 203 bool InProcessBuildableVideoCaptureDevice::IsDeviceAlive() const { | 
| 192 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 204 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 193 return device_ != nullptr; | 205 return device_ != nullptr; | 
| 194 } | 206 } | 
| 195 | 207 | 
| 196 void InProcessBuildableVideoCaptureDevice::GetPhotoCapabilities( | 208 void InProcessBuildableVideoCaptureDevice::GetPhotoCapabilities( | 
| 197 media::VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) const { | 209 media::VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) const { | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 base::Unretained(this), device_.get(), window_id, | 285 base::Unretained(this), device_.get(), window_id, | 
| 274 base::Passed(&context_reference))); | 286 base::Passed(&context_reference))); | 
| 275 } | 287 } | 
| 276 | 288 | 
| 277 std::unique_ptr<media::VideoCaptureDeviceClient> | 289 std::unique_ptr<media::VideoCaptureDeviceClient> | 
| 278 InProcessBuildableVideoCaptureDevice::CreateDeviceClient( | 290 InProcessBuildableVideoCaptureDevice::CreateDeviceClient( | 
| 279 int buffer_pool_max_buffer_count, | 291 int buffer_pool_max_buffer_count, | 
| 280 base::WeakPtr<media::VideoFrameReceiver> receiver) { | 292 base::WeakPtr<media::VideoFrameReceiver> receiver) { | 
| 281 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 293 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 282 | 294 | 
| 283 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool_ = | 295 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool = | 
| 284 new media::VideoCaptureBufferPoolImpl( | 296 new media::VideoCaptureBufferPoolImpl( | 
| 285 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), | 297 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), | 
| 286 buffer_pool_max_buffer_count); | 298 buffer_pool_max_buffer_count); | 
| 287 | 299 | 
| 288 return base::MakeUnique<media::VideoCaptureDeviceClient>( | 300 return base::MakeUnique<media::VideoCaptureDeviceClient>( | 
| 289 base::MakeUnique<VideoFrameReceiverOnIOThread>(receiver), buffer_pool_, | 301 base::MakeUnique<VideoFrameReceiverOnIOThread>(receiver), | 
| 302 std::move(buffer_pool), | |
| 
miu
2017/03/17 21:48:02
Note: Mistakes like this can be avoided by biasing
 
chfremer
2017/03/21 22:37:23
Done.
 | |
| 290 base::Bind(&CreateGpuJpegDecoder, | 303 base::Bind(&CreateGpuJpegDecoder, | 
| 291 base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, | 304 base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, | 
| 292 receiver))); | 305 receiver))); | 
| 293 } | 306 } | 
| 294 | 307 | 
| 295 void InProcessBuildableVideoCaptureDevice::OnDeviceStarted( | 308 void InProcessBuildableVideoCaptureDevice::OnDeviceStarted( | 
| 296 VideoCaptureController* controller, | 309 VideoCaptureController* controller, | 
| 297 BuildableDeviceCallbacks* callbacks, | 310 BuildableDeviceCallbacks* callbacks, | 
| 298 std::unique_ptr<Ownership> context_reference, | 311 std::unique_ptr<Ownership> context_reference, | 
| 299 std::unique_ptr<media::VideoCaptureDevice> device) { | 312 std::unique_ptr<media::VideoCaptureDevice> device) { | 
| 300 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 313 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 301 if (!device) { | 314 switch (state_) { | 
| 302 callbacks->OnDeviceStartFailed(controller); | 315 case State::DEVICE_START_IN_PROGRESS: | 
| 303 return; | 316 if (!device) { | 
| 317 state_ = State::NO_DEVICE; | |
| 318 callbacks->OnDeviceStartFailed(controller); | |
| 319 return; | |
| 320 } | |
| 321 // Passing raw pointer |device.get()| to the controller is safe, | |
| 322 // because we take ownership of |device| and we call | |
| 323 // controller->SetConsumerFeedbackObserver(nullptr) before releasing | |
| 324 // |device|. | |
| 325 controller->SetConsumerFeedbackObserver( | |
| 326 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( | |
| 327 device.get(), device_task_runner_)); | |
| 328 device_ = std::move(device); | |
| 329 state_ = State::DEVICE_STARTED; | |
| 330 callbacks->DidStartDevice(controller); | |
| 331 return; | |
| 332 case State::DEVICE_START_ABORTING: | |
| 333 if (device) { | |
| 334 device_ = std::move(device); | |
| 335 state_ = State::DEVICE_STARTED; | |
| 336 // We do not move our |context_reference| to this invocation, because | |
| 337 // we still need it for the remainder of this method execution. | |
| 338 // Our implementation of ReleaseDeviceAsync() does not actually need the | |
| 339 // context while releasing the device. | |
| 340 ReleaseDeviceAsync(controller, nullptr); | |
| 341 } | |
| 342 state_ = State::NO_DEVICE; | |
| 343 callbacks->OnDeviceStartAborted(); | |
| 344 return; | |
| 345 case State::NO_DEVICE: | |
| 346 case State::DEVICE_STARTED: | |
| 347 NOTREACHED(); | |
| 348 return; | |
| 304 } | 349 } | 
| 305 // Passing raw pointer |device.get()| to the controller is safe, | |
| 306 // because we take ownership of |device| and we call | |
| 307 // controller->SetConsumerFeedbackObserver(nullptr) before releasing |device|. | |
| 308 controller->SetConsumerFeedbackObserver( | |
| 309 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( | |
| 310 device.get(), device_task_runner_)); | |
| 311 device_ = std::move(device); | |
| 312 callbacks->DidStartDevice(controller); | |
| 313 } | 350 } | 
| 314 | 351 | 
| 315 void InProcessBuildableVideoCaptureDevice::DoStartDeviceCaptureOnDeviceThread( | 352 void InProcessBuildableVideoCaptureDevice::DoStartDeviceCaptureOnDeviceThread( | 
| 316 const media::VideoCaptureDeviceDescriptor& descriptor, | 353 const media::VideoCaptureDeviceDescriptor& descriptor, | 
| 317 const media::VideoCaptureParams& params, | 354 const media::VideoCaptureParams& params, | 
| 318 std::unique_ptr<media::VideoCaptureDeviceClient> device_client, | 355 std::unique_ptr<media::VideoCaptureDeviceClient> device_client, | 
| 319 ReceiveDeviceCallback result_callback) { | 356 ReceiveDeviceCallback result_callback) { | 
| 320 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 357 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 
| 321 DCHECK(device_task_runner_->BelongsToCurrentThread()); | 358 DCHECK(device_task_runner_->BelongsToCurrentThread()); | 
| 322 | 359 | 
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 414 #if defined(ENABLE_SCREEN_CAPTURE) && BUILDFLAG(ENABLE_WEBRTC) && \ | 451 #if defined(ENABLE_SCREEN_CAPTURE) && BUILDFLAG(ENABLE_WEBRTC) && \ | 
| 415 !defined(OS_ANDROID) | 452 !defined(OS_ANDROID) | 
| 416 DesktopCaptureDevice* desktop_device = | 453 DesktopCaptureDevice* desktop_device = | 
| 417 static_cast<DesktopCaptureDevice*>(device); | 454 static_cast<DesktopCaptureDevice*>(device); | 
| 418 desktop_device->SetNotificationWindowId(window_id); | 455 desktop_device->SetNotificationWindowId(window_id); | 
| 419 VLOG(2) << "Screen capture notification window passed on device thread."; | 456 VLOG(2) << "Screen capture notification window passed on device thread."; | 
| 420 #endif | 457 #endif | 
| 421 } | 458 } | 
| 422 | 459 | 
| 423 } // namespace content | 460 } // namespace content | 
| OLD | NEW |