| 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 // all clients of |video_capture_controller| stay connected. When the | 180 // all clients of |video_capture_controller| stay connected. When the |
| 181 // application is resumed, we transition to Phase 2, except that the existing | 181 // application is resumed, we transition to Phase 2, except that the existing |
| 182 // |buffer_pool| get reused instead of creating a new one. | 182 // |buffer_pool| get reused instead of creating a new one. |
| 183 struct VideoCaptureManager::DeviceEntry { | 183 struct VideoCaptureManager::DeviceEntry { |
| 184 public: | 184 public: |
| 185 DeviceEntry(MediaStreamType stream_type, | 185 DeviceEntry(MediaStreamType stream_type, |
| 186 const std::string& id, | 186 const std::string& id, |
| 187 const media::VideoCaptureParams& params); | 187 const media::VideoCaptureParams& params); |
| 188 ~DeviceEntry(); | 188 ~DeviceEntry(); |
| 189 std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient(); | 189 std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient(); |
| 190 std::unique_ptr<media::FrameBufferPool> CreateFrameBufferPool(); | |
| 191 | 190 |
| 192 const int serial_id; | 191 const int serial_id; |
| 193 const MediaStreamType stream_type; | 192 const MediaStreamType stream_type; |
| 194 const std::string id; | 193 const std::string id; |
| 195 const media::VideoCaptureParams parameters; | 194 const media::VideoCaptureParams parameters; |
| 196 VideoCaptureController video_capture_controller; | 195 VideoCaptureController video_capture_controller; |
| 197 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool; | |
| 198 std::unique_ptr<media::VideoCaptureDevice> video_capture_device; | 196 std::unique_ptr<media::VideoCaptureDevice> video_capture_device; |
| 199 }; | 197 }; |
| 200 | 198 |
| 201 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported | 199 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported |
| 202 // video formats. | 200 // video formats. |
| 203 struct VideoCaptureManager::DeviceInfo { | 201 struct VideoCaptureManager::DeviceInfo { |
| 204 DeviceInfo(); | 202 DeviceInfo(); |
| 205 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); | 203 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); |
| 206 DeviceInfo(const DeviceInfo& other); | 204 DeviceInfo(const DeviceInfo& other); |
| 207 ~DeviceInfo(); | 205 ~DeviceInfo(); |
| 208 DeviceInfo& operator=(const DeviceInfo& other); | 206 DeviceInfo& operator=(const DeviceInfo& other); |
| 209 | 207 |
| 210 media::VideoCaptureDeviceDescriptor descriptor; | 208 media::VideoCaptureDeviceDescriptor descriptor; |
| 211 media::VideoCaptureFormats supported_formats; | 209 media::VideoCaptureFormats supported_formats; |
| 212 }; | 210 }; |
| 213 | 211 |
| 214 class BufferPoolFrameBufferPool : public media::FrameBufferPool { | |
| 215 public: | |
| 216 explicit BufferPoolFrameBufferPool( | |
| 217 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool) | |
| 218 : buffer_pool_(std::move(buffer_pool)) {} | |
| 219 | |
| 220 void SetBufferHold(int buffer_id) override { | |
| 221 buffer_pool_->HoldForConsumers(buffer_id, 1); | |
| 222 } | |
| 223 | |
| 224 void ReleaseBufferHold(int buffer_id) override { | |
| 225 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); | |
| 226 } | |
| 227 | |
| 228 private: | |
| 229 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool_; | |
| 230 }; | |
| 231 | |
| 232 // Class used for queuing request for starting a device. | 212 // Class used for queuing request for starting a device. |
| 233 class VideoCaptureManager::CaptureDeviceStartRequest { | 213 class VideoCaptureManager::CaptureDeviceStartRequest { |
| 234 public: | 214 public: |
| 235 CaptureDeviceStartRequest(int serial_id, | 215 CaptureDeviceStartRequest(int serial_id, |
| 236 media::VideoCaptureSessionId session_id, | 216 media::VideoCaptureSessionId session_id, |
| 237 const media::VideoCaptureParams& params); | 217 const media::VideoCaptureParams& params); |
| 238 int serial_id() const { return serial_id_; } | 218 int serial_id() const { return serial_id_; } |
| 239 media::VideoCaptureSessionId session_id() const { return session_id_; } | 219 media::VideoCaptureSessionId session_id() const { return session_id_; } |
| 240 media::VideoCaptureParams params() const { return params_; } | 220 media::VideoCaptureParams params() const { return params_; } |
| 241 | 221 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 270 DCHECK(video_capture_device == nullptr); | 250 DCHECK(video_capture_device == nullptr); |
| 271 } | 251 } |
| 272 | 252 |
| 273 std::unique_ptr<media::VideoCaptureDevice::Client> | 253 std::unique_ptr<media::VideoCaptureDevice::Client> |
| 274 VideoCaptureManager::DeviceEntry::CreateDeviceClient() { | 254 VideoCaptureManager::DeviceEntry::CreateDeviceClient() { |
| 275 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 255 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 276 | 256 |
| 277 const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE | 257 const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE |
| 278 ? kMaxNumberOfBuffersForTabCapture | 258 ? kMaxNumberOfBuffersForTabCapture |
| 279 : kMaxNumberOfBuffers; | 259 : kMaxNumberOfBuffers; |
| 280 if (!buffer_pool) { | 260 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool = |
| 281 buffer_pool = new media::VideoCaptureBufferPoolImpl( | 261 new media::VideoCaptureBufferPoolImpl( |
| 282 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), | 262 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), |
| 283 max_buffers); | 263 max_buffers); |
| 284 } | |
| 285 | 264 |
| 286 return base::MakeUnique<media::VideoCaptureDeviceClient>( | 265 return base::MakeUnique<media::VideoCaptureDeviceClient>( |
| 287 base::MakeUnique<VideoFrameReceiverOnIOThread>( | 266 base::MakeUnique<VideoFrameReceiverOnIOThread>( |
| 288 video_capture_controller.GetWeakPtrForIOThread()), | 267 video_capture_controller.GetWeakPtrForIOThread()), |
| 289 buffer_pool, | 268 std::move(buffer_pool), |
| 290 base::Bind( | 269 base::Bind(&CreateGpuJpegDecoder, |
| 291 &CreateGpuJpegDecoder, | 270 base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, |
| 292 base::Bind(&media::VideoFrameReceiver::OnIncomingCapturedVideoFrame, | 271 video_capture_controller.GetWeakPtrForIOThread()))); |
| 293 video_capture_controller.GetWeakPtrForIOThread()))); | |
| 294 } | |
| 295 | |
| 296 std::unique_ptr<media::FrameBufferPool> | |
| 297 VideoCaptureManager::DeviceEntry::CreateFrameBufferPool() { | |
| 298 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 299 DCHECK(buffer_pool); | |
| 300 return base::MakeUnique<BufferPoolFrameBufferPool>(buffer_pool); | |
| 301 } | 272 } |
| 302 | 273 |
| 303 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; | 274 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; |
| 304 | 275 |
| 305 VideoCaptureManager::DeviceInfo::DeviceInfo( | 276 VideoCaptureManager::DeviceInfo::DeviceInfo( |
| 306 media::VideoCaptureDeviceDescriptor descriptor) | 277 media::VideoCaptureDeviceDescriptor descriptor) |
| 307 : descriptor(descriptor) {} | 278 : descriptor(descriptor) {} |
| 308 | 279 |
| 309 VideoCaptureManager::DeviceInfo::DeviceInfo( | 280 VideoCaptureManager::DeviceInfo::DeviceInfo( |
| 310 const VideoCaptureManager::DeviceInfo& other) = default; | 281 const VideoCaptureManager::DeviceInfo& other) = default; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 << entry->id << " serial_id = " << entry->serial_id; | 434 << entry->id << " serial_id = " << entry->serial_id; |
| 464 return; | 435 return; |
| 465 } | 436 } |
| 466 } | 437 } |
| 467 | 438 |
| 468 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id | 439 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id |
| 469 << " serial_id = " << entry->serial_id << "."; | 440 << " serial_id = " << entry->serial_id << "."; |
| 470 entry->video_capture_controller.OnLog( | 441 entry->video_capture_controller.OnLog( |
| 471 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); | 442 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); |
| 472 entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr); | 443 entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr); |
| 473 entry->video_capture_controller.SetFrameBufferPool(nullptr); | |
| 474 | 444 |
| 475 // |entry->video_capture_device| can be null if creating the device has | 445 // |entry->video_capture_device| can be null if creating the device has |
| 476 // failed. | 446 // failed. |
| 477 if (entry->video_capture_device) { | 447 if (entry->video_capture_device) { |
| 478 device_task_runner_->PostTask( | 448 device_task_runner_->PostTask( |
| 479 FROM_HERE, | 449 FROM_HERE, |
| 480 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 450 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| 481 base::Passed(&entry->video_capture_device))); | 451 base::Passed(&entry->video_capture_device))); |
| 482 } | 452 } |
| 483 } | 453 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 495 | 465 |
| 496 const int serial_id = request->serial_id(); | 466 const int serial_id = request->serial_id(); |
| 497 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 467 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
| 498 DCHECK(entry); | 468 DCHECK(entry); |
| 499 | 469 |
| 500 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " | 470 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
| 501 << entry->id << " start id = " << entry->serial_id; | 471 << entry->id << " start id = " << entry->serial_id; |
| 502 | 472 |
| 503 std::unique_ptr<media::VideoCaptureDevice::Client> device_client = | 473 std::unique_ptr<media::VideoCaptureDevice::Client> device_client = |
| 504 entry->CreateDeviceClient(); | 474 entry->CreateDeviceClient(); |
| 505 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool = | |
| 506 entry->CreateFrameBufferPool(); | |
| 507 | 475 |
| 508 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> | 476 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> |
| 509 start_capture_function; | 477 start_capture_function; |
| 510 | 478 |
| 511 switch (entry->stream_type) { | 479 switch (entry->stream_type) { |
| 512 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 480 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
| 513 // We look up the device id from the renderer in our local enumeration | 481 // We look up the device id from the renderer in our local enumeration |
| 514 // since the renderer does not have all the information that might be | 482 // since the renderer does not have all the information that might be |
| 515 // held in the browser-side VideoCaptureDevice::Name structure. | 483 // held in the browser-side VideoCaptureDevice::Name structure. |
| 516 const DeviceInfo* found = GetDeviceInfoById(entry->id); | 484 const DeviceInfo* found = GetDeviceInfoById(entry->id); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 break; | 525 break; |
| 558 | 526 |
| 559 default: { | 527 default: { |
| 560 NOTIMPLEMENTED(); | 528 NOTIMPLEMENTED(); |
| 561 return; | 529 return; |
| 562 } | 530 } |
| 563 } | 531 } |
| 564 base::PostTaskAndReplyWithResult( | 532 base::PostTaskAndReplyWithResult( |
| 565 device_task_runner_.get(), FROM_HERE, start_capture_function, | 533 device_task_runner_.get(), FROM_HERE, start_capture_function, |
| 566 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | 534 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, |
| 567 request->serial_id(), base::Passed(&frame_buffer_pool))); | 535 request->serial_id())); |
| 568 } | 536 } |
| 569 | 537 |
| 570 void VideoCaptureManager::OnDeviceStarted( | 538 void VideoCaptureManager::OnDeviceStarted( |
| 571 int serial_id, | 539 int serial_id, |
| 572 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool, | |
| 573 std::unique_ptr<VideoCaptureDevice> device) { | 540 std::unique_ptr<VideoCaptureDevice> device) { |
| 574 DVLOG(3) << __func__; | 541 DVLOG(3) << __func__; |
| 575 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 542 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 576 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); | 543 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); |
| 577 // |device| can be null if creation failed in | 544 // |device| can be null if creation failed in |
| 578 // DoStartDeviceCaptureOnDeviceThread. | 545 // DoStartDeviceCaptureOnDeviceThread. |
| 579 if (device_start_queue_.front().abort_start()) { | 546 if (device_start_queue_.front().abort_start()) { |
| 580 // The device is no longer wanted. Stop the device again. | 547 // The device is no longer wanted. Stop the device again. |
| 581 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; | 548 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; |
| 582 media::VideoCaptureDevice* device_ptr = device.get(); | 549 media::VideoCaptureDevice* device_ptr = device.get(); |
| 583 base::Closure closure = | 550 base::Closure closure = |
| 584 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 551 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| 585 base::Passed(&device)); | 552 base::Passed(&device)); |
| 586 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { | 553 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { |
| 587 // PostTask failed. The device must be stopped anyway. | 554 // PostTask failed. The device must be stopped anyway. |
| 588 device_ptr->StopAndDeAllocate(); | 555 device_ptr->StopAndDeAllocate(); |
| 589 } | 556 } |
| 590 } else { | 557 } else { |
| 591 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 558 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
| 592 DCHECK(entry); | 559 DCHECK(entry); |
| 593 DCHECK(!entry->video_capture_device); | 560 DCHECK(!entry->video_capture_device); |
| 594 if (device) { | 561 if (device) { |
| 595 entry->video_capture_controller.SetFrameBufferPool( | |
| 596 std::move(frame_buffer_pool)); | |
| 597 // Passing raw pointer |device.get()| to the controller is safe, | 562 // Passing raw pointer |device.get()| to the controller is safe, |
| 598 // because we transfer ownership of it to |entry|. We are calling | 563 // because we transfer ownership of it to |entry|. We are calling |
| 599 // SetConsumerFeedbackObserver(nullptr) before releasing | 564 // SetConsumerFeedbackObserver(nullptr) before releasing |
| 600 // |entry->video_capture_device_| on the |device_task_runner_|. | 565 // |entry->video_capture_device_| on the |device_task_runner_|. |
| 601 entry->video_capture_controller.SetConsumerFeedbackObserver( | 566 entry->video_capture_controller.SetConsumerFeedbackObserver( |
| 602 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( | 567 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( |
| 603 device.get(), device_task_runner_)); | 568 device.get(), device_task_runner_)); |
| 604 } | 569 } |
| 605 entry->video_capture_device = std::move(device); | 570 entry->video_capture_device = std::move(device); |
| 606 | 571 |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 if (!device_in_queue) { | 1277 if (!device_in_queue) { |
| 1313 // Session ID is only valid for Screen capture. So we can fake it to | 1278 // Session ID is only valid for Screen capture. So we can fake it to |
| 1314 // resume video capture devices here. | 1279 // resume video capture devices here. |
| 1315 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); | 1280 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
| 1316 } | 1281 } |
| 1317 } | 1282 } |
| 1318 } | 1283 } |
| 1319 #endif // defined(OS_ANDROID) | 1284 #endif // defined(OS_ANDROID) |
| 1320 | 1285 |
| 1321 } // namespace content | 1286 } // namespace content |
| OLD | NEW |