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 |