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 |