OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/video_capture_manager.h" | 5 #include "content/browser/renderer_host/media/video_capture_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 } | 164 } |
165 | 165 |
166 } // namespace | 166 } // namespace |
167 | 167 |
168 namespace content { | 168 namespace content { |
169 | 169 |
170 // Instances of this struct go through several different phases during their | 170 // Instances of this struct go through several different phases during their |
171 // lifetime. | 171 // lifetime. |
172 // Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of | 172 // Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of |
173 // only the |video_capture_controller|. Clients can already connect to the | 173 // only the |video_capture_controller|. Clients can already connect to the |
174 // controller, but there is no |buffer_pool| or |video_capture_device| present. | 174 // controller, but there is no |video_capture_device| present. |
175 // Phase 2: When a request to "start" the entry comes in (via | 175 // Phase 2: When a request to "start" the entry comes in (via |
176 // HandleQueuedStartRequest()), |buffer_pool| is created and creation of | 176 // HandleQueuedStartRequest()), creation of |video_capture_device| is scheduled |
177 // |video_capture_device| is scheduled to run asynchronously on the Device | 177 // to run asynchronously on the Device Thread. |
178 // Thread. | |
179 // Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this | 178 // Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this |
180 // newly created VideoCaptureDevice instance is connected to the | 179 // newly created VideoCaptureDevice instance is connected to the |
181 // VideoCaptureController via SetConsumerFeedbackObserver(). Furthermore, the | 180 // VideoCaptureController via SetConsumerFeedbackObserver(). |
182 // |buffer_pool| is moved to the |video_capture_controller| as a | |
183 // FrameBufferPool via SetFrameBufferPool(). | |
184 // Phase 4: This phase can only be reached on Android. When the application goes | 181 // Phase 4: This phase can only be reached on Android. When the application goes |
185 // to the background, the |video_capture_device| is asynchronously stopped and | 182 // to the background, the |video_capture_device| is asynchronously stopped and |
186 // released on the Device Thread. When the application is resumed, we | 183 // released on the Device Thread. When the application is resumed, we |
187 // transition to Phase 2. | 184 // transition to Phase 2. |
188 struct VideoCaptureManager::DeviceEntry { | 185 struct VideoCaptureManager::DeviceEntry { |
189 public: | 186 public: |
190 DeviceEntry(MediaStreamType stream_type, | 187 DeviceEntry(MediaStreamType stream_type, |
191 const std::string& id, | 188 const std::string& id, |
192 const media::VideoCaptureParams& params); | 189 const media::VideoCaptureParams& params); |
193 ~DeviceEntry(); | 190 ~DeviceEntry(); |
194 std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient(); | 191 std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient(); |
195 std::unique_ptr<media::FrameBufferPool> CreateFrameBufferPool(); | |
196 | 192 |
197 const int serial_id; | 193 const int serial_id; |
198 const MediaStreamType stream_type; | 194 const MediaStreamType stream_type; |
199 const std::string id; | 195 const std::string id; |
200 const media::VideoCaptureParams parameters; | 196 const media::VideoCaptureParams parameters; |
201 VideoCaptureController video_capture_controller; | 197 VideoCaptureController video_capture_controller; |
202 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool; | |
203 std::unique_ptr<media::VideoCaptureDevice> video_capture_device; | 198 std::unique_ptr<media::VideoCaptureDevice> video_capture_device; |
204 }; | 199 }; |
205 | 200 |
206 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported | 201 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported |
207 // video formats. | 202 // video formats. |
208 struct VideoCaptureManager::DeviceInfo { | 203 struct VideoCaptureManager::DeviceInfo { |
209 DeviceInfo(); | 204 DeviceInfo(); |
210 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); | 205 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); |
211 DeviceInfo(const DeviceInfo& other); | 206 DeviceInfo(const DeviceInfo& other); |
212 ~DeviceInfo(); | 207 ~DeviceInfo(); |
213 DeviceInfo& operator=(const DeviceInfo& other); | 208 DeviceInfo& operator=(const DeviceInfo& other); |
214 | 209 |
215 media::VideoCaptureDeviceDescriptor descriptor; | 210 media::VideoCaptureDeviceDescriptor descriptor; |
216 media::VideoCaptureFormats supported_formats; | 211 media::VideoCaptureFormats supported_formats; |
217 }; | 212 }; |
218 | 213 |
219 class BufferPoolFrameBufferPool : public media::FrameBufferPool { | |
220 public: | |
221 explicit BufferPoolFrameBufferPool( | |
222 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool) | |
223 : buffer_pool_(std::move(buffer_pool)) {} | |
224 | |
225 void SetBufferHold(int buffer_id) override { | |
226 buffer_pool_->HoldForConsumers(buffer_id, 1); | |
227 } | |
228 | |
229 void ReleaseBufferHold(int buffer_id) override { | |
230 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); | |
231 } | |
232 | |
233 private: | |
234 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool_; | |
235 }; | |
236 | |
237 // Class used for queuing request for starting a device. | 214 // Class used for queuing request for starting a device. |
238 class VideoCaptureManager::CaptureDeviceStartRequest { | 215 class VideoCaptureManager::CaptureDeviceStartRequest { |
239 public: | 216 public: |
240 CaptureDeviceStartRequest(int serial_id, | 217 CaptureDeviceStartRequest(int serial_id, |
241 media::VideoCaptureSessionId session_id, | 218 media::VideoCaptureSessionId session_id, |
242 const media::VideoCaptureParams& params); | 219 const media::VideoCaptureParams& params); |
243 int serial_id() const { return serial_id_; } | 220 int serial_id() const { return serial_id_; } |
244 media::VideoCaptureSessionId session_id() const { return session_id_; } | 221 media::VideoCaptureSessionId session_id() const { return session_id_; } |
245 media::VideoCaptureParams params() const { return params_; } | 222 media::VideoCaptureParams params() const { return params_; } |
246 | 223 |
(...skipping 28 matching lines...) Expand all Loading... |
275 DCHECK(video_capture_device == nullptr); | 252 DCHECK(video_capture_device == nullptr); |
276 } | 253 } |
277 | 254 |
278 std::unique_ptr<media::VideoCaptureDevice::Client> | 255 std::unique_ptr<media::VideoCaptureDevice::Client> |
279 VideoCaptureManager::DeviceEntry::CreateDeviceClient() { | 256 VideoCaptureManager::DeviceEntry::CreateDeviceClient() { |
280 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 257 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
281 | 258 |
282 const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE | 259 const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE |
283 ? kMaxNumberOfBuffersForTabCapture | 260 ? kMaxNumberOfBuffersForTabCapture |
284 : kMaxNumberOfBuffers; | 261 : kMaxNumberOfBuffers; |
285 buffer_pool = new media::VideoCaptureBufferPoolImpl( | 262 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool = |
286 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), | 263 new media::VideoCaptureBufferPoolImpl( |
287 max_buffers); | 264 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), |
| 265 max_buffers); |
288 | 266 |
289 return base::MakeUnique<media::VideoCaptureDeviceClient>( | 267 return base::MakeUnique<media::VideoCaptureDeviceClient>( |
290 base::MakeUnique<VideoFrameReceiverOnIOThread>( | 268 base::MakeUnique<VideoFrameReceiverOnIOThread>( |
291 video_capture_controller.GetWeakPtrForIOThread()), | 269 video_capture_controller.GetWeakPtrForIOThread()), |
292 buffer_pool, | 270 std::move(buffer_pool), |
293 base::Bind( | 271 base::Bind(&CreateGpuJpegDecoder, |
294 &CreateGpuJpegDecoder, | 272 base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, |
295 base::Bind(&media::VideoFrameReceiver::OnIncomingCapturedVideoFrame, | 273 video_capture_controller.GetWeakPtrForIOThread()))); |
296 video_capture_controller.GetWeakPtrForIOThread()))); | |
297 } | |
298 | |
299 std::unique_ptr<media::FrameBufferPool> | |
300 VideoCaptureManager::DeviceEntry::CreateFrameBufferPool() { | |
301 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
302 DCHECK(buffer_pool); | |
303 return base::MakeUnique<BufferPoolFrameBufferPool>(std::move(buffer_pool)); | |
304 } | 274 } |
305 | 275 |
306 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; | 276 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; |
307 | 277 |
308 VideoCaptureManager::DeviceInfo::DeviceInfo( | 278 VideoCaptureManager::DeviceInfo::DeviceInfo( |
309 media::VideoCaptureDeviceDescriptor descriptor) | 279 media::VideoCaptureDeviceDescriptor descriptor) |
310 : descriptor(descriptor) {} | 280 : descriptor(descriptor) {} |
311 | 281 |
312 VideoCaptureManager::DeviceInfo::DeviceInfo( | 282 VideoCaptureManager::DeviceInfo::DeviceInfo( |
313 const VideoCaptureManager::DeviceInfo& other) = default; | 283 const VideoCaptureManager::DeviceInfo& other) = default; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 if (device_info != nullptr) { | 455 if (device_info != nullptr) { |
486 for (auto& observer : capture_observers_) | 456 for (auto& observer : capture_observers_) |
487 observer.OnVideoCaptureStopped(device_info->descriptor.facing); | 457 observer.OnVideoCaptureStopped(device_info->descriptor.facing); |
488 } | 458 } |
489 | 459 |
490 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id | 460 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id |
491 << " serial_id = " << entry->serial_id << "."; | 461 << " serial_id = " << entry->serial_id << "."; |
492 entry->video_capture_controller.OnLog( | 462 entry->video_capture_controller.OnLog( |
493 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); | 463 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); |
494 entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr); | 464 entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr); |
495 entry->video_capture_controller.SetFrameBufferPool(nullptr); | |
496 | 465 |
497 // |entry->video_capture_device| can be null if creating the device has | 466 // |entry->video_capture_device| can be null if creating the device has |
498 // failed. | 467 // failed. |
499 if (entry->video_capture_device) { | 468 if (entry->video_capture_device) { |
500 device_task_runner_->PostTask( | 469 device_task_runner_->PostTask( |
501 FROM_HERE, | 470 FROM_HERE, |
502 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 471 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
503 base::Passed(&entry->video_capture_device))); | 472 base::Passed(&entry->video_capture_device))); |
504 } | 473 } |
505 } | 474 } |
(...skipping 11 matching lines...) Expand all Loading... |
517 | 486 |
518 const int serial_id = request->serial_id(); | 487 const int serial_id = request->serial_id(); |
519 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 488 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
520 DCHECK(entry); | 489 DCHECK(entry); |
521 | 490 |
522 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " | 491 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
523 << entry->id << " start id = " << entry->serial_id; | 492 << entry->id << " start id = " << entry->serial_id; |
524 | 493 |
525 std::unique_ptr<media::VideoCaptureDevice::Client> device_client = | 494 std::unique_ptr<media::VideoCaptureDevice::Client> device_client = |
526 entry->CreateDeviceClient(); | 495 entry->CreateDeviceClient(); |
527 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool = | |
528 entry->CreateFrameBufferPool(); | |
529 | 496 |
530 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> | 497 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> |
531 start_capture_function; | 498 start_capture_function; |
532 | 499 |
533 switch (entry->stream_type) { | 500 switch (entry->stream_type) { |
534 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 501 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
535 // We look up the device id from the renderer in our local enumeration | 502 // We look up the device id from the renderer in our local enumeration |
536 // since the renderer does not have all the information that might be | 503 // since the renderer does not have all the information that might be |
537 // held in the browser-side VideoCaptureDevice::Name structure. | 504 // held in the browser-side VideoCaptureDevice::Name structure. |
538 const DeviceInfo* found = GetDeviceInfoById(entry->id); | 505 const DeviceInfo* found = GetDeviceInfoById(entry->id); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 break; | 549 break; |
583 | 550 |
584 default: { | 551 default: { |
585 NOTIMPLEMENTED(); | 552 NOTIMPLEMENTED(); |
586 return; | 553 return; |
587 } | 554 } |
588 } | 555 } |
589 base::PostTaskAndReplyWithResult( | 556 base::PostTaskAndReplyWithResult( |
590 device_task_runner_.get(), FROM_HERE, start_capture_function, | 557 device_task_runner_.get(), FROM_HERE, start_capture_function, |
591 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | 558 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, |
592 request->serial_id(), base::Passed(&frame_buffer_pool))); | 559 request->serial_id())); |
593 } | 560 } |
594 | 561 |
595 void VideoCaptureManager::OnDeviceStarted( | 562 void VideoCaptureManager::OnDeviceStarted( |
596 int serial_id, | 563 int serial_id, |
597 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool, | |
598 std::unique_ptr<VideoCaptureDevice> device) { | 564 std::unique_ptr<VideoCaptureDevice> device) { |
599 DVLOG(3) << __func__; | 565 DVLOG(3) << __func__; |
600 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 566 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
601 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); | 567 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); |
602 // |device| can be null if creation failed in | 568 // |device| can be null if creation failed in |
603 // DoStartDeviceCaptureOnDeviceThread. | 569 // DoStartDeviceCaptureOnDeviceThread. |
604 if (device_start_queue_.front().abort_start()) { | 570 if (device_start_queue_.front().abort_start()) { |
605 // The device is no longer wanted. Stop the device again. | 571 // The device is no longer wanted. Stop the device again. |
606 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; | 572 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; |
607 media::VideoCaptureDevice* device_ptr = device.get(); | 573 media::VideoCaptureDevice* device_ptr = device.get(); |
608 base::Closure closure = | 574 base::Closure closure = |
609 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 575 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
610 base::Passed(&device)); | 576 base::Passed(&device)); |
611 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { | 577 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { |
612 // PostTask failed. The device must be stopped anyway. | 578 // PostTask failed. The device must be stopped anyway. |
613 device_ptr->StopAndDeAllocate(); | 579 device_ptr->StopAndDeAllocate(); |
614 } | 580 } |
615 } else { | 581 } else { |
616 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 582 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
617 DCHECK(entry); | 583 DCHECK(entry); |
618 DCHECK(!entry->video_capture_device); | 584 DCHECK(!entry->video_capture_device); |
619 if (device) { | 585 if (device) { |
620 entry->video_capture_controller.SetFrameBufferPool( | |
621 std::move(frame_buffer_pool)); | |
622 // Passing raw pointer |device.get()| to the controller is safe, | 586 // Passing raw pointer |device.get()| to the controller is safe, |
623 // because we transfer ownership of it to |entry|. We are calling | 587 // because we transfer ownership of it to |entry|. We are calling |
624 // SetConsumerFeedbackObserver(nullptr) before releasing | 588 // SetConsumerFeedbackObserver(nullptr) before releasing |
625 // |entry->video_capture_device_| on the |device_task_runner_|. | 589 // |entry->video_capture_device_| on the |device_task_runner_|. |
626 entry->video_capture_controller.SetConsumerFeedbackObserver( | 590 entry->video_capture_controller.SetConsumerFeedbackObserver( |
627 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( | 591 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( |
628 device.get(), device_task_runner_)); | 592 device.get(), device_task_runner_)); |
629 } | 593 } |
630 entry->video_capture_device = std::move(device); | 594 entry->video_capture_device = std::move(device); |
631 | 595 |
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 if (!device_in_queue) { | 1336 if (!device_in_queue) { |
1373 // Session ID is only valid for Screen capture. So we can fake it to | 1337 // Session ID is only valid for Screen capture. So we can fake it to |
1374 // resume video capture devices here. | 1338 // resume video capture devices here. |
1375 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); | 1339 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
1376 } | 1340 } |
1377 } | 1341 } |
1378 } | 1342 } |
1379 #endif // defined(OS_ANDROID) | 1343 #endif // defined(OS_ANDROID) |
1380 | 1344 |
1381 } // namespace content | 1345 } // namespace content |
OLD | NEW |