Chromium Code Reviews| 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" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) { | 58 const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) { |
| 59 return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb); | 59 return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb); |
| 60 } | 60 } |
| 61 | 61 |
| 62 void StopAndReleaseDeviceOnDeviceThread(media::VideoCaptureDevice* device, | 62 void StopAndReleaseDeviceOnDeviceThread(media::VideoCaptureDevice* device, |
| 63 base::OnceClosure done_cb) { | 63 base::OnceClosure done_cb) { |
| 64 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); | 64 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
| 65 device->StopAndDeAllocate(); | 65 device->StopAndDeAllocate(); |
| 66 DVLOG(3) << "StopAndReleaseDeviceOnDeviceThread"; | 66 DVLOG(3) << "StopAndReleaseDeviceOnDeviceThread"; |
| 67 delete device; | 67 delete device; |
| 68 std::move(done_cb).Run(); | 68 std::move(done_cb).Run(); |
|
miu
2017/03/22 21:33:28
nit: Is the std::move() necessary (and everywhere
chfremer
2017/03/22 22:37:52
Yes. I believe this is the only way to invoke Run(
| |
| 69 } | 69 } |
| 70 | 70 |
| 71 // The maximum number of video frame buffers in-flight at any one time. This | 71 // The maximum number of video frame buffers in-flight at any one time. This |
| 72 // value should be based on the logical capacity of the capture pipeline, and | 72 // value should be based on the logical capacity of the capture pipeline, and |
| 73 // not on hardware performance. For example, tab capture requires more buffers | 73 // not on hardware performance. For example, tab capture requires more buffers |
| 74 // than webcam capture because the pipeline is longer (it includes read-backs | 74 // than webcam capture because the pipeline is longer (it includes read-backs |
| 75 // pending in the GPU pipeline). | 75 // pending in the GPU pipeline). |
| 76 const int kMaxNumberOfBuffers = 3; | 76 const int kMaxNumberOfBuffers = 3; |
| 77 // TODO(miu): The value for tab capture should be determined programmatically. | 77 // TODO(miu): The value for tab capture should be determined programmatically. |
| 78 // http://crbug.com/460318 | 78 // http://crbug.com/460318 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 92 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 92 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 93 DCHECK(!device_); | 93 DCHECK(!device_); |
| 94 } | 94 } |
| 95 | 95 |
| 96 void InProcessBuildableVideoCaptureDevice::CreateAndStartDeviceAsync( | 96 void InProcessBuildableVideoCaptureDevice::CreateAndStartDeviceAsync( |
| 97 VideoCaptureController* controller, | 97 VideoCaptureController* controller, |
| 98 const media::VideoCaptureParams& params, | 98 const media::VideoCaptureParams& params, |
| 99 BuildableDeviceCallbacks* callbacks, | 99 BuildableDeviceCallbacks* callbacks, |
| 100 base::OnceClosure done_cb) { | 100 base::OnceClosure done_cb) { |
| 101 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 101 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 102 DCHECK(state_ == State::NO_DEVICE); | |
|
mcasas
2017/03/24 21:54:36
DCHECK_EQ(State::NO_DEVICE, state_) ?
Not sure if
chfremer
2017/03/31 17:25:37
Done.
| |
| 102 | 103 |
| 103 const int max_buffers = (controller->stream_type() == MEDIA_TAB_VIDEO_CAPTURE | 104 const int max_buffers = (controller->stream_type() == MEDIA_TAB_VIDEO_CAPTURE |
| 104 ? kMaxNumberOfBuffersForTabCapture | 105 ? kMaxNumberOfBuffersForTabCapture |
| 105 : kMaxNumberOfBuffers); | 106 : kMaxNumberOfBuffers); |
| 106 | 107 |
| 107 auto device_client = | 108 auto device_client = |
| 108 CreateDeviceClient(max_buffers, controller->GetWeakPtrForIOThread()); | 109 CreateDeviceClient(max_buffers, controller->GetWeakPtrForIOThread()); |
| 109 | 110 |
| 110 base::Closure start_capture_closure; | 111 base::Closure start_capture_closure; |
| 111 switch (controller->stream_type()) { | 112 switch (controller->stream_type()) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 std::move(after_start_capture_callback)); | 174 std::move(after_start_capture_callback)); |
| 174 break; | 175 break; |
| 175 } | 176 } |
| 176 default: { | 177 default: { |
| 177 NOTIMPLEMENTED(); | 178 NOTIMPLEMENTED(); |
| 178 return; | 179 return; |
| 179 } | 180 } |
| 180 } | 181 } |
| 181 | 182 |
| 182 device_task_runner_->PostTask(FROM_HERE, start_capture_closure); | 183 device_task_runner_->PostTask(FROM_HERE, start_capture_closure); |
| 184 state_ = State::DEVICE_START_IN_PROGRESS; | |
| 183 } | 185 } |
| 184 | 186 |
| 185 void InProcessBuildableVideoCaptureDevice::ReleaseDeviceAsync( | 187 void InProcessBuildableVideoCaptureDevice::ReleaseDeviceAsync( |
| 186 VideoCaptureController* controller, | 188 VideoCaptureController* controller, |
| 187 base::OnceClosure done_cb) { | 189 base::OnceClosure done_cb) { |
| 188 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 190 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 189 controller->SetConsumerFeedbackObserver(nullptr); | 191 controller->SetConsumerFeedbackObserver(nullptr); |
| 190 if (!device_) | 192 switch (state_) { |
| 191 return; | 193 case State::DEVICE_START_IN_PROGRESS: |
| 192 media::VideoCaptureDevice* device_ptr = device_.release(); | 194 state_ = State::DEVICE_START_ABORTING; |
| 193 | 195 return; |
| 194 bool posting_task_succeeded = device_task_runner_->PostTask( | 196 case State::NO_DEVICE: |
| 195 FROM_HERE, | 197 case State::DEVICE_START_ABORTING: |
| 196 base::Bind(&StopAndReleaseDeviceOnDeviceThread, device_ptr, | 198 return; |
| 197 base::Bind([](scoped_refptr<base::SingleThreadTaskRunner>) {}, | 199 case State::DEVICE_STARTED: |
| 198 device_task_runner_))); | 200 media::VideoCaptureDevice* device_ptr = device_.release(); |
| 199 if (posting_task_succeeded == false) { | 201 bool posting_task_succeeded = device_task_runner_->PostTask( |
| 200 // Since posting to the task runner has failed, we attempt doing it on | 202 FROM_HERE, |
| 201 // the calling thread instead. | 203 base::Bind( |
| 202 StopAndReleaseDeviceOnDeviceThread(device_ptr, base::Bind([]() {})); | 204 &StopAndReleaseDeviceOnDeviceThread, device_ptr, |
| 205 base::Bind([](scoped_refptr<base::SingleThreadTaskRunner>) {}, | |
| 206 device_task_runner_))); | |
| 207 if (posting_task_succeeded == false) { | |
| 208 // Since posting to the task runner has failed, we attempt doing it on | |
| 209 // the calling thread instead. | |
| 210 StopAndReleaseDeviceOnDeviceThread(device_ptr, base::Bind([]() {})); | |
| 211 } | |
| 212 state_ = State::NO_DEVICE; | |
| 213 return; | |
| 203 } | 214 } |
| 204 std::move(done_cb).Run(); | 215 std::move(done_cb).Run(); |
| 205 } | 216 } |
| 206 | 217 |
| 207 bool InProcessBuildableVideoCaptureDevice::IsDeviceAlive() const { | 218 bool InProcessBuildableVideoCaptureDevice::IsDeviceAlive() const { |
| 208 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 219 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 209 return device_ != nullptr; | 220 return device_ != nullptr; |
| 210 } | 221 } |
| 211 | 222 |
| 212 void InProcessBuildableVideoCaptureDevice::GetPhotoCapabilities( | 223 void InProcessBuildableVideoCaptureDevice::GetPhotoCapabilities( |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 base::Unretained(this), device_.get(), window_id, | 300 base::Unretained(this), device_.get(), window_id, |
| 290 base::Passed(&done_cb))); | 301 base::Passed(&done_cb))); |
| 291 } | 302 } |
| 292 | 303 |
| 293 std::unique_ptr<media::VideoCaptureDeviceClient> | 304 std::unique_ptr<media::VideoCaptureDeviceClient> |
| 294 InProcessBuildableVideoCaptureDevice::CreateDeviceClient( | 305 InProcessBuildableVideoCaptureDevice::CreateDeviceClient( |
| 295 int buffer_pool_max_buffer_count, | 306 int buffer_pool_max_buffer_count, |
| 296 base::WeakPtr<media::VideoFrameReceiver> receiver) { | 307 base::WeakPtr<media::VideoFrameReceiver> receiver) { |
| 297 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 308 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 298 | 309 |
| 299 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool_ = | 310 return base::MakeUnique<media::VideoCaptureDeviceClient>( |
| 311 base::MakeUnique<VideoFrameReceiverOnIOThread>(receiver), | |
| 300 new media::VideoCaptureBufferPoolImpl( | 312 new media::VideoCaptureBufferPoolImpl( |
| 301 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), | 313 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), |
| 302 buffer_pool_max_buffer_count); | 314 buffer_pool_max_buffer_count), |
| 303 | |
| 304 return base::MakeUnique<media::VideoCaptureDeviceClient>( | |
| 305 base::MakeUnique<VideoFrameReceiverOnIOThread>(receiver), buffer_pool_, | |
| 306 base::Bind(&CreateGpuJpegDecoder, | 315 base::Bind(&CreateGpuJpegDecoder, |
| 307 base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, | 316 base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, |
| 308 receiver))); | 317 receiver))); |
| 309 } | 318 } |
| 310 | 319 |
| 311 void InProcessBuildableVideoCaptureDevice::OnDeviceStarted( | 320 void InProcessBuildableVideoCaptureDevice::OnDeviceStarted( |
| 312 VideoCaptureController* controller, | 321 VideoCaptureController* controller, |
| 313 BuildableDeviceCallbacks* callbacks, | 322 BuildableDeviceCallbacks* callbacks, |
| 314 base::OnceClosure done_cb, | 323 base::OnceClosure done_cb, |
| 315 std::unique_ptr<media::VideoCaptureDevice> device) { | 324 std::unique_ptr<media::VideoCaptureDevice> device) { |
| 316 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 325 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 317 if (!device) { | 326 switch (state_) { |
| 318 callbacks->OnDeviceStartFailed(controller); | 327 case State::DEVICE_START_IN_PROGRESS: |
| 319 std::move(done_cb).Run(); | 328 if (!device) { |
| 320 return; | 329 state_ = State::NO_DEVICE; |
| 330 callbacks->OnDeviceStartFailed(controller); | |
| 331 std::move(done_cb).Run(); | |
| 332 return; | |
| 333 } | |
| 334 // Passing raw pointer |device.get()| to the controller is safe, | |
| 335 // because we take ownership of |device| and we call | |
| 336 // controller->SetConsumerFeedbackObserver(nullptr) before releasing | |
| 337 // |device|. | |
| 338 controller->SetConsumerFeedbackObserver( | |
| 339 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( | |
| 340 device.get(), device_task_runner_)); | |
| 341 device_ = std::move(device); | |
| 342 state_ = State::DEVICE_STARTED; | |
| 343 callbacks->DidStartDevice(controller); | |
| 344 std::move(done_cb).Run(); | |
| 345 return; | |
| 346 case State::DEVICE_START_ABORTING: | |
| 347 if (device) { | |
| 348 device_ = std::move(device); | |
| 349 state_ = State::DEVICE_STARTED; | |
| 350 // We do not move our |done_cb| to this invocation, because | |
| 351 // we still need it to stay alive for the remainder of this method | |
| 352 // execution. Our implementation of ReleaseDeviceAsync() does not | |
| 353 // actually need the context while releasing the device. | |
| 354 ReleaseDeviceAsync(controller, base::Bind([]() {})); | |
| 355 } | |
| 356 state_ = State::NO_DEVICE; | |
| 357 callbacks->OnDeviceStartAborted(); | |
| 358 std::move(done_cb).Run(); | |
| 359 return; | |
| 360 case State::NO_DEVICE: | |
| 361 case State::DEVICE_STARTED: | |
| 362 NOTREACHED(); | |
| 363 return; | |
| 321 } | 364 } |
| 322 // Passing raw pointer |device.get()| to the controller is safe, | |
| 323 // because we take ownership of |device| and we call | |
| 324 // controller->SetConsumerFeedbackObserver(nullptr) before releasing |device|. | |
| 325 controller->SetConsumerFeedbackObserver( | |
| 326 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( | |
| 327 device.get(), device_task_runner_)); | |
| 328 device_ = std::move(device); | |
| 329 callbacks->DidStartDevice(controller); | |
| 330 std::move(done_cb).Run(); | |
| 331 } | 365 } |
| 332 | 366 |
| 333 void InProcessBuildableVideoCaptureDevice::DoStartDeviceCaptureOnDeviceThread( | 367 void InProcessBuildableVideoCaptureDevice::DoStartDeviceCaptureOnDeviceThread( |
| 334 const media::VideoCaptureDeviceDescriptor& descriptor, | 368 const media::VideoCaptureDeviceDescriptor& descriptor, |
| 335 const media::VideoCaptureParams& params, | 369 const media::VideoCaptureParams& params, |
| 336 std::unique_ptr<media::VideoCaptureDeviceClient> device_client, | 370 std::unique_ptr<media::VideoCaptureDeviceClient> device_client, |
| 337 ReceiveDeviceCallback result_callback) { | 371 ReceiveDeviceCallback result_callback) { |
| 338 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 372 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| 339 DCHECK(device_task_runner_->BelongsToCurrentThread()); | 373 DCHECK(device_task_runner_->BelongsToCurrentThread()); |
| 340 | 374 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 !defined(OS_ANDROID) | 466 !defined(OS_ANDROID) |
| 433 DesktopCaptureDevice* desktop_device = | 467 DesktopCaptureDevice* desktop_device = |
| 434 static_cast<DesktopCaptureDevice*>(device); | 468 static_cast<DesktopCaptureDevice*>(device); |
| 435 desktop_device->SetNotificationWindowId(window_id); | 469 desktop_device->SetNotificationWindowId(window_id); |
| 436 VLOG(2) << "Screen capture notification window passed on device thread."; | 470 VLOG(2) << "Screen capture notification window passed on device thread."; |
| 437 #endif | 471 #endif |
| 438 std::move(done_cb).Run(); | 472 std::move(done_cb).Run(); |
| 439 } | 473 } |
| 440 | 474 |
| 441 } // namespace content | 475 } // namespace content |
| OLD | NEW |