| 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_video_capture_device_la
     uncher.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/in_process_launched_video_capture_
     device.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/public/browser/browser_thread.h" |   14 #include "content/public/browser/browser_thread.h" | 
|   14 #include "content/public/browser/desktop_media_id.h" |   15 #include "content/public/browser/desktop_media_id.h" | 
|   15 #include "content/public/common/media_stream_request.h" |   16 #include "content/public/common/media_stream_request.h" | 
|   16 #include "media/base/bind_to_current_loop.h" |   17 #include "media/base/bind_to_current_loop.h" | 
|   17 #include "media/capture/video/video_capture_buffer_pool_impl.h" |   18 #include "media/capture/video/video_capture_buffer_pool_impl.h" | 
|   18 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" |   19 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" | 
|   19 #include "media/capture/video/video_capture_device_client.h" |   20 #include "media/capture/video/video_capture_device_client.h" | 
 |   21 #include "media/capture/video/video_frame_receiver.h" | 
|   20 #include "media/capture/video/video_frame_receiver_on_task_runner.h" |   22 #include "media/capture/video/video_frame_receiver_on_task_runner.h" | 
|   21  |   23  | 
|   22 #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID) |   24 #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID) | 
|   23 #include "content/browser/media/capture/desktop_capture_device.h" |   25 #include "content/browser/media/capture/desktop_capture_device.h" | 
|   24 #if defined(USE_AURA) |   26 #if defined(USE_AURA) | 
|   25 #include "content/browser/media/capture/desktop_capture_device_aura.h" |   27 #include "content/browser/media/capture/desktop_capture_device_aura.h" | 
|   26 #endif |   28 #endif | 
|   27 #endif |   29 #endif | 
|   28  |   30  | 
|   29 #if defined(ENABLE_SCREEN_CAPTURE) && defined(OS_ANDROID) |   31 #if defined(ENABLE_SCREEN_CAPTURE) && defined(OS_ANDROID) | 
|   30 #include "content/browser/media/capture/screen_capture_device_android.h" |   32 #include "content/browser/media/capture/screen_capture_device_android.h" | 
|   31 #endif |   33 #endif | 
|   32  |   34  | 
|   33 namespace { |   35 namespace { | 
|   34  |   36  | 
|   35 class VideoFrameConsumerFeedbackObserverOnTaskRunner |  | 
|   36     : public media::VideoFrameConsumerFeedbackObserver { |  | 
|   37  public: |  | 
|   38   VideoFrameConsumerFeedbackObserverOnTaskRunner( |  | 
|   39       media::VideoFrameConsumerFeedbackObserver* observer, |  | 
|   40       scoped_refptr<base::SingleThreadTaskRunner> task_runner) |  | 
|   41       : observer_(observer), task_runner_(std::move(task_runner)) {} |  | 
|   42  |  | 
|   43   void OnUtilizationReport(int frame_feedback_id, double utilization) override { |  | 
|   44     task_runner_->PostTask( |  | 
|   45         FROM_HERE, |  | 
|   46         base::Bind( |  | 
|   47             &media::VideoFrameConsumerFeedbackObserver::OnUtilizationReport, |  | 
|   48             base::Unretained(observer_), frame_feedback_id, utilization)); |  | 
|   49   } |  | 
|   50  |  | 
|   51  private: |  | 
|   52   media::VideoFrameConsumerFeedbackObserver* const observer_; |  | 
|   53   const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |  | 
|   54 }; |  | 
|   55  |  | 
|   56 std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( |   37 std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( | 
|   57     const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) { |   38     const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) { | 
|   58   return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb); |   39   return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb); | 
|   59 } |   40 } | 
|   60  |   41  | 
|   61 void StopAndReleaseDeviceOnDeviceThread(media::VideoCaptureDevice* device, |  | 
|   62                                         base::OnceClosure done_cb) { |  | 
|   63   SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |  | 
|   64   device->StopAndDeAllocate(); |  | 
|   65   DVLOG(3) << "StopAndReleaseDeviceOnDeviceThread"; |  | 
|   66   delete device; |  | 
|   67   base::ResetAndReturn(&done_cb).Run(); |  | 
|   68 } |  | 
|   69  |  | 
|   70 // The maximum number of video frame buffers in-flight at any one time. This |   42 // The maximum number of video frame buffers in-flight at any one time. This | 
|   71 // value should be based on the logical capacity of the capture pipeline, and |   43 // value should be based on the logical capacity of the capture pipeline, and | 
|   72 // not on hardware performance.  For example, tab capture requires more buffers |   44 // not on hardware performance.  For example, tab capture requires more buffers | 
|   73 // than webcam capture because the pipeline is longer (it includes read-backs |   45 // than webcam capture because the pipeline is longer (it includes read-backs | 
|   74 // pending in the GPU pipeline). |   46 // pending in the GPU pipeline). | 
|   75 const int kMaxNumberOfBuffers = 3; |   47 const int kMaxNumberOfBuffers = 3; | 
|   76 // TODO(miu): The value for tab capture should be determined programmatically. |   48 // TODO(miu): The value for tab capture should be determined programmatically. | 
|   77 // http://crbug.com/460318 |   49 // http://crbug.com/460318 | 
|   78 const int kMaxNumberOfBuffersForTabCapture = 10; |   50 const int kMaxNumberOfBuffersForTabCapture = 10; | 
|   79  |   51  | 
|   80 }  // anonymous namespace |   52 }  // anonymous namespace | 
|   81  |   53  | 
|   82 namespace content { |   54 namespace content { | 
|   83  |   55  | 
|   84 InProcessBuildableVideoCaptureDevice::InProcessBuildableVideoCaptureDevice( |   56 InProcessVideoCaptureDeviceLauncher::InProcessVideoCaptureDeviceLauncher( | 
|   85     scoped_refptr<base::SingleThreadTaskRunner> device_task_runner, |   57     scoped_refptr<base::SingleThreadTaskRunner> device_task_runner, | 
|   86     media::VideoCaptureSystem* video_capture_system) |   58     media::VideoCaptureSystem* video_capture_system) | 
|   87     : device_task_runner_(std::move(device_task_runner)), |   59     : device_task_runner_(std::move(device_task_runner)), | 
|   88       video_capture_system_(video_capture_system) {} |   60       video_capture_system_(video_capture_system), | 
 |   61       state_(State::READY_TO_LAUNCH) {} | 
|   89  |   62  | 
|   90 InProcessBuildableVideoCaptureDevice::~InProcessBuildableVideoCaptureDevice() { |   63 InProcessVideoCaptureDeviceLauncher::~InProcessVideoCaptureDeviceLauncher() { | 
|   91   DCHECK_CURRENTLY_ON(BrowserThread::IO); |   64   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
|   92   DCHECK(!device_); |   65   DCHECK(state_ == State::READY_TO_LAUNCH); | 
|   93 } |   66 } | 
|   94  |   67  | 
|   95 void InProcessBuildableVideoCaptureDevice::CreateAndStartDeviceAsync( |   68 void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync( | 
|   96     VideoCaptureController* controller, |   69     const std::string& device_id, | 
 |   70     MediaStreamType stream_type, | 
|   97     const media::VideoCaptureParams& params, |   71     const media::VideoCaptureParams& params, | 
 |   72     base::WeakPtr<media::VideoFrameReceiver> receiver, | 
|   98     Callbacks* callbacks, |   73     Callbacks* callbacks, | 
|   99     base::OnceClosure done_cb) { |   74     base::OnceClosure done_cb) { | 
|  100   DCHECK_CURRENTLY_ON(BrowserThread::IO); |   75   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
|  101   DCHECK_EQ(State::NO_DEVICE, state_); |   76   DCHECK(state_ == State::READY_TO_LAUNCH); | 
|  102  |   77  | 
|  103   const int max_buffers = (controller->stream_type() == MEDIA_TAB_VIDEO_CAPTURE |   78   const int max_buffers = | 
|  104                                ? kMaxNumberOfBuffersForTabCapture |   79       (stream_type == MEDIA_TAB_VIDEO_CAPTURE ? kMaxNumberOfBuffersForTabCapture | 
|  105                                : kMaxNumberOfBuffers); |   80                                               : kMaxNumberOfBuffers); | 
|  106  |   81  | 
|  107   auto device_client = |   82   auto device_client = CreateDeviceClient(max_buffers, std::move(receiver)); | 
|  108       CreateDeviceClient(max_buffers, controller->GetWeakPtrForIOThread()); |  | 
|  109  |   83  | 
|  110   base::Closure start_capture_closure; |   84   base::Closure start_capture_closure; | 
|  111   // Use of Unretained() is safe, because |done_cb| guarantees that |   85   // Use of |this| is safe, because |done_cb| guarantees that |this| | 
|  112   // |this| stays alive. |   86   // stays alive. | 
|  113   ReceiveDeviceCallback after_start_capture_callback = media::BindToCurrentLoop( |   87   ReceiveDeviceCallback after_start_capture_callback = media::BindToCurrentLoop( | 
|  114       base::Bind(&InProcessBuildableVideoCaptureDevice::OnDeviceStarted, |   88       base::Bind(&InProcessVideoCaptureDeviceLauncher::OnDeviceStarted, | 
|  115                  base::Unretained(this), controller, callbacks, |   89                  base::Unretained(this), callbacks, base::Passed(&done_cb))); | 
|  116                  base::Passed(&done_cb))); |  | 
|  117  |   90  | 
|  118   switch (controller->stream_type()) { |   91   switch (stream_type) { | 
|  119     case MEDIA_DEVICE_VIDEO_CAPTURE: { |   92     case MEDIA_DEVICE_VIDEO_CAPTURE: { | 
|  120       start_capture_closure = |   93       start_capture_closure = | 
|  121           base::Bind(&InProcessBuildableVideoCaptureDevice:: |   94           base::Bind(&InProcessVideoCaptureDeviceLauncher:: | 
|  122                          DoStartDeviceCaptureOnDeviceThread, |   95                          DoStartDeviceCaptureOnDeviceThread, | 
|  123                      base::Unretained(this), controller->device_id(), params, |   96                      base::Unretained(this), device_id, params, | 
|  124                      base::Passed(std::move(device_client)), |   97                      base::Passed(std::move(device_client)), | 
|  125                      std::move(after_start_capture_callback)); |   98                      std::move(after_start_capture_callback)); | 
|  126       break; |   99       break; | 
|  127     } |  100     } | 
|  128     case MEDIA_TAB_VIDEO_CAPTURE: |  101     case MEDIA_TAB_VIDEO_CAPTURE: | 
|  129       start_capture_closure = |  102       start_capture_closure = base::Bind( | 
|  130           base::Bind(&InProcessBuildableVideoCaptureDevice:: |  103           &InProcessVideoCaptureDeviceLauncher::DoStartTabCaptureOnDeviceThread, | 
|  131                          DoStartTabCaptureOnDeviceThread, |  104           base::Unretained(this), device_id, params, | 
|  132                      base::Unretained(this), controller->device_id(), params, |  105           base::Passed(std::move(device_client)), | 
|  133                      base::Passed(std::move(device_client)), |  106           std::move(after_start_capture_callback)); | 
|  134                      std::move(after_start_capture_callback)); |  | 
|  135       break; |  107       break; | 
|  136  |  108  | 
|  137     case MEDIA_DESKTOP_VIDEO_CAPTURE: |  109     case MEDIA_DESKTOP_VIDEO_CAPTURE: | 
|  138       start_capture_closure = |  110       start_capture_closure = | 
|  139           base::Bind(&InProcessBuildableVideoCaptureDevice:: |  111           base::Bind(&InProcessVideoCaptureDeviceLauncher:: | 
|  140                          DoStartDesktopCaptureOnDeviceThread, |  112                          DoStartDesktopCaptureOnDeviceThread, | 
|  141                      base::Unretained(this), controller->device_id(), params, |  113                      base::Unretained(this), device_id, params, | 
|  142                      base::Passed(std::move(device_client)), |  114                      base::Passed(std::move(device_client)), | 
|  143                      std::move(after_start_capture_callback)); |  115                      std::move(after_start_capture_callback)); | 
|  144       break; |  116       break; | 
|  145  |  117  | 
|  146     default: { |  118     default: { | 
|  147       NOTIMPLEMENTED(); |  119       NOTIMPLEMENTED(); | 
|  148       return; |  120       return; | 
|  149     } |  121     } | 
|  150   } |  122   } | 
|  151  |  123  | 
|  152   device_task_runner_->PostTask(FROM_HERE, start_capture_closure); |  124   device_task_runner_->PostTask(FROM_HERE, start_capture_closure); | 
|  153   state_ = State::DEVICE_START_IN_PROGRESS; |  125   state_ = State::DEVICE_START_IN_PROGRESS; | 
|  154 } |  126 } | 
|  155  |  127  | 
|  156 void InProcessBuildableVideoCaptureDevice::ReleaseDeviceAsync( |  128 void InProcessVideoCaptureDeviceLauncher::AbortLaunch() { | 
|  157     VideoCaptureController* controller, |  | 
|  158     base::OnceClosure done_cb) { |  | 
|  159   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  129   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
|  160   controller->SetConsumerFeedbackObserver(nullptr); |  130   if (state_ == State::DEVICE_START_IN_PROGRESS) | 
|  161   switch (state_) { |  131     state_ = State::DEVICE_START_ABORTING; | 
 |  132 } | 
 |  133  | 
 |  134 std::unique_ptr<media::VideoCaptureDeviceClient> | 
 |  135 InProcessVideoCaptureDeviceLauncher::CreateDeviceClient( | 
 |  136     int buffer_pool_max_buffer_count, | 
 |  137     base::WeakPtr<media::VideoFrameReceiver> receiver) { | 
 |  138   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
 |  139  | 
 |  140   scoped_refptr<media::VideoCaptureBufferPool> buffer_pool = | 
 |  141       new media::VideoCaptureBufferPoolImpl( | 
 |  142           base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), | 
 |  143           buffer_pool_max_buffer_count); | 
 |  144  | 
 |  145   return base::MakeUnique<media::VideoCaptureDeviceClient>( | 
 |  146       base::MakeUnique<media::VideoFrameReceiverOnTaskRunner>( | 
 |  147           receiver, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)), | 
 |  148       std::move(buffer_pool), | 
 |  149       base::Bind(&CreateGpuJpegDecoder, | 
 |  150                  base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, | 
 |  151                             receiver))); | 
 |  152 } | 
 |  153  | 
 |  154 void InProcessVideoCaptureDeviceLauncher::OnDeviceStarted( | 
 |  155     Callbacks* callbacks, | 
 |  156     base::OnceClosure done_cb, | 
 |  157     std::unique_ptr<media::VideoCaptureDevice> device) { | 
 |  158   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
 |  159   State state_copy = state_; | 
 |  160   state_ = State::READY_TO_LAUNCH; | 
 |  161   if (!device) { | 
 |  162     switch (state_copy) { | 
 |  163       case State::DEVICE_START_IN_PROGRESS: | 
 |  164         callbacks->OnDeviceLaunchFailed(); | 
 |  165         return; | 
 |  166       case State::DEVICE_START_ABORTING: | 
 |  167         callbacks->OnDeviceLaunchAborted(); | 
 |  168         return; | 
 |  169       case State::READY_TO_LAUNCH: | 
 |  170         NOTREACHED(); | 
 |  171         return; | 
 |  172     } | 
 |  173   } | 
 |  174  | 
 |  175   auto launched_device = base::MakeUnique<InProcessLaunchedVideoCaptureDevice>( | 
 |  176       std::move(device), device_task_runner_); | 
 |  177  | 
 |  178   switch (state_copy) { | 
|  162     case State::DEVICE_START_IN_PROGRESS: |  179     case State::DEVICE_START_IN_PROGRESS: | 
|  163       state_ = State::DEVICE_START_ABORTING; |  180       callbacks->OnDeviceLaunched(std::move(launched_device)); | 
|  164       return; |  181       return; | 
|  165     case State::NO_DEVICE: |  | 
|  166     case State::DEVICE_START_ABORTING: |  182     case State::DEVICE_START_ABORTING: | 
 |  183       launched_device.reset(); | 
 |  184       callbacks->OnDeviceLaunchAborted(); | 
|  167       return; |  185       return; | 
|  168     case State::DEVICE_STARTED: |  186     case State::READY_TO_LAUNCH: | 
|  169       media::VideoCaptureDevice* device_ptr = device_.release(); |  187       NOTREACHED(); | 
|  170       bool posting_task_succeeded = device_task_runner_->PostTask( |  | 
|  171           FROM_HERE, |  | 
|  172           base::Bind( |  | 
|  173               &StopAndReleaseDeviceOnDeviceThread, device_ptr, |  | 
|  174               base::Bind([](scoped_refptr<base::SingleThreadTaskRunner>) {}, |  | 
|  175                          device_task_runner_))); |  | 
|  176       if (posting_task_succeeded == false) { |  | 
|  177         // Since posting to the task runner has failed, we attempt doing it on |  | 
|  178         // the calling thread instead. |  | 
|  179         StopAndReleaseDeviceOnDeviceThread(device_ptr, base::Bind([]() {})); |  | 
|  180       } |  | 
|  181       state_ = State::NO_DEVICE; |  | 
|  182       return; |  188       return; | 
|  183   } |  189   } | 
|  184   base::ResetAndReturn(&done_cb).Run(); |  190   base::ResetAndReturn(&done_cb).Run(); | 
|  185 } |  191 } | 
|  186  |  192  | 
|  187 bool InProcessBuildableVideoCaptureDevice::IsDeviceAlive() const { |  193 void InProcessVideoCaptureDeviceLauncher::DoStartDeviceCaptureOnDeviceThread( | 
|  188   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  189   return device_ != nullptr; |  | 
|  190 } |  | 
|  191  |  | 
|  192 void InProcessBuildableVideoCaptureDevice::GetPhotoCapabilities( |  | 
|  193     media::VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) const { |  | 
|  194   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  195   // Unretained() is safe to use here because |device| would be null if it |  | 
|  196   // was scheduled for shutdown and destruction, and because this task is |  | 
|  197   // guaranteed to run before the task that destroys the |device|. |  | 
|  198   device_task_runner_->PostTask( |  | 
|  199       FROM_HERE, |  | 
|  200       base::Bind(&media::VideoCaptureDevice::GetPhotoCapabilities, |  | 
|  201                  base::Unretained(device_.get()), base::Passed(&callback))); |  | 
|  202 } |  | 
|  203  |  | 
|  204 void InProcessBuildableVideoCaptureDevice::SetPhotoOptions( |  | 
|  205     media::mojom::PhotoSettingsPtr settings, |  | 
|  206     media::VideoCaptureDevice::SetPhotoOptionsCallback callback) { |  | 
|  207   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  208   // Unretained() is safe to use here because |device| would be null if it |  | 
|  209   // was scheduled for shutdown and destruction, and because this task is |  | 
|  210   // guaranteed to run before the task that destroys the |device|. |  | 
|  211   device_task_runner_->PostTask( |  | 
|  212       FROM_HERE, base::Bind(&media::VideoCaptureDevice::SetPhotoOptions, |  | 
|  213                             base::Unretained(device_.get()), |  | 
|  214                             base::Passed(&settings), base::Passed(&callback))); |  | 
|  215 } |  | 
|  216  |  | 
|  217 void InProcessBuildableVideoCaptureDevice::TakePhoto( |  | 
|  218     media::VideoCaptureDevice::TakePhotoCallback callback) { |  | 
|  219   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  220   // Unretained() is safe to use here because |device| would be null if it |  | 
|  221   // was scheduled for shutdown and destruction, and because this task is |  | 
|  222   // guaranteed to run before the task that destroys the |device|. |  | 
|  223   device_task_runner_->PostTask( |  | 
|  224       FROM_HERE, |  | 
|  225       base::Bind(&media::VideoCaptureDevice::TakePhoto, |  | 
|  226                  base::Unretained(device_.get()), base::Passed(&callback))); |  | 
|  227 } |  | 
|  228  |  | 
|  229 void InProcessBuildableVideoCaptureDevice::MaybeSuspendDevice() { |  | 
|  230   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  231   // Unretained() is safe to use here because |device| would be null if it |  | 
|  232   // was scheduled for shutdown and destruction, and because this task is |  | 
|  233   // guaranteed to run before the task that destroys the |device|. |  | 
|  234   device_task_runner_->PostTask( |  | 
|  235       FROM_HERE, base::Bind(&media::VideoCaptureDevice::MaybeSuspend, |  | 
|  236                             base::Unretained(device_.get()))); |  | 
|  237 } |  | 
|  238  |  | 
|  239 void InProcessBuildableVideoCaptureDevice::ResumeDevice() { |  | 
|  240   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  241   // Unretained() is safe to use here because |device| would be null if it |  | 
|  242   // was scheduled for shutdown and destruction, and because this task is |  | 
|  243   // guaranteed to run before the task that destroys the |device|. |  | 
|  244   device_task_runner_->PostTask(FROM_HERE, |  | 
|  245                                 base::Bind(&media::VideoCaptureDevice::Resume, |  | 
|  246                                            base::Unretained(device_.get()))); |  | 
|  247 } |  | 
|  248  |  | 
|  249 void InProcessBuildableVideoCaptureDevice::RequestRefreshFrame() { |  | 
|  250   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  251   // Unretained() is safe to use here because |device| would be null if it |  | 
|  252   // was scheduled for shutdown and destruction, and because this task is |  | 
|  253   // guaranteed to run before the task that destroys the |device|. |  | 
|  254   device_task_runner_->PostTask( |  | 
|  255       FROM_HERE, base::Bind(&media::VideoCaptureDevice::RequestRefreshFrame, |  | 
|  256                             base::Unretained(device_.get()))); |  | 
|  257 } |  | 
|  258  |  | 
|  259 void InProcessBuildableVideoCaptureDevice::SetDesktopCaptureWindowIdAsync( |  | 
|  260     gfx::NativeViewId window_id, |  | 
|  261     base::OnceClosure done_cb) { |  | 
|  262   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  263   // Post |device_| to the the |device_task_runner_|. This is safe since the |  | 
|  264   // device is destroyed on the |device_task_runner_| and |done_cb| guarantees |  | 
|  265   // that |this| stays alive. |  | 
|  266   device_task_runner_->PostTask( |  | 
|  267       FROM_HERE, base::Bind(&InProcessBuildableVideoCaptureDevice:: |  | 
|  268                                 SetDesktopCaptureWindowIdOnDeviceThread, |  | 
|  269                             base::Unretained(this), device_.get(), window_id, |  | 
|  270                             base::Passed(&done_cb))); |  | 
|  271 } |  | 
|  272  |  | 
|  273 std::unique_ptr<media::VideoCaptureDeviceClient> |  | 
|  274 InProcessBuildableVideoCaptureDevice::CreateDeviceClient( |  | 
|  275     int buffer_pool_max_buffer_count, |  | 
|  276     base::WeakPtr<media::VideoFrameReceiver> receiver) { |  | 
|  277   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  278  |  | 
|  279   return base::MakeUnique<media::VideoCaptureDeviceClient>( |  | 
|  280       base::MakeUnique<media::VideoFrameReceiverOnTaskRunner>( |  | 
|  281           receiver, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)), |  | 
|  282       new media::VideoCaptureBufferPoolImpl( |  | 
|  283           base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), |  | 
|  284           buffer_pool_max_buffer_count), |  | 
|  285       base::Bind(&CreateGpuJpegDecoder, |  | 
|  286                  base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, |  | 
|  287                             receiver))); |  | 
|  288 } |  | 
|  289  |  | 
|  290 void InProcessBuildableVideoCaptureDevice::OnDeviceStarted( |  | 
|  291     VideoCaptureController* controller, |  | 
|  292     Callbacks* callbacks, |  | 
|  293     base::OnceClosure done_cb, |  | 
|  294     std::unique_ptr<media::VideoCaptureDevice> device) { |  | 
|  295   DCHECK_CURRENTLY_ON(BrowserThread::IO); |  | 
|  296   switch (state_) { |  | 
|  297     case State::DEVICE_START_IN_PROGRESS: |  | 
|  298       if (!device) { |  | 
|  299         state_ = State::NO_DEVICE; |  | 
|  300         callbacks->OnDeviceStartFailed(controller); |  | 
|  301         base::ResetAndReturn(&done_cb).Run(); |  | 
|  302         return; |  | 
|  303       } |  | 
|  304       // Passing raw pointer |device.get()| to the controller is safe, |  | 
|  305       // because we take ownership of |device| and we call |  | 
|  306       // controller->SetConsumerFeedbackObserver(nullptr) before releasing |  | 
|  307       // |device|. |  | 
|  308       controller->SetConsumerFeedbackObserver( |  | 
|  309           base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( |  | 
|  310               device.get(), device_task_runner_)); |  | 
|  311       device_ = std::move(device); |  | 
|  312       state_ = State::DEVICE_STARTED; |  | 
|  313       callbacks->OnDeviceStarted(controller); |  | 
|  314       base::ResetAndReturn(&done_cb).Run(); |  | 
|  315       return; |  | 
|  316     case State::DEVICE_START_ABORTING: |  | 
|  317       if (device) { |  | 
|  318         device_ = std::move(device); |  | 
|  319         state_ = State::DEVICE_STARTED; |  | 
|  320         // We do not move our |done_cb| to this invocation, because |  | 
|  321         // we still need it to stay alive for the remainder of this method |  | 
|  322         // execution. Our implementation of ReleaseDeviceAsync() does not |  | 
|  323         // actually need the context while releasing the device. |  | 
|  324         ReleaseDeviceAsync(controller, base::Bind([]() {})); |  | 
|  325       } |  | 
|  326       state_ = State::NO_DEVICE; |  | 
|  327       callbacks->OnDeviceStartAborted(); |  | 
|  328       base::ResetAndReturn(&done_cb).Run(); |  | 
|  329       return; |  | 
|  330     case State::NO_DEVICE: |  | 
|  331     case State::DEVICE_STARTED: |  | 
|  332       NOTREACHED(); |  | 
|  333       return; |  | 
|  334   } |  | 
|  335 } |  | 
|  336  |  | 
|  337 void InProcessBuildableVideoCaptureDevice::DoStartDeviceCaptureOnDeviceThread( |  | 
|  338     const std::string& device_id, |  194     const std::string& device_id, | 
|  339     const media::VideoCaptureParams& params, |  195     const media::VideoCaptureParams& params, | 
|  340     std::unique_ptr<media::VideoCaptureDeviceClient> device_client, |  196     std::unique_ptr<media::VideoCaptureDeviceClient> device_client, | 
|  341     ReceiveDeviceCallback result_callback) { |  197     ReceiveDeviceCallback result_callback) { | 
|  342   SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |  198   SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 
|  343   DCHECK(device_task_runner_->BelongsToCurrentThread()); |  199   DCHECK(device_task_runner_->BelongsToCurrentThread()); | 
|  344  |  200  | 
|  345   std::unique_ptr<media::VideoCaptureDevice> video_capture_device = |  201   std::unique_ptr<media::VideoCaptureDevice> video_capture_device = | 
|  346       video_capture_system_->CreateDevice(device_id); |  202       video_capture_system_->CreateDevice(device_id); | 
|  347  |  203  | 
|  348   if (!video_capture_device) { |  204   if (!video_capture_device) { | 
|  349     result_callback.Run(nullptr); |  205     result_callback.Run(nullptr); | 
|  350     return; |  206     return; | 
|  351   } |  207   } | 
|  352  |  208  | 
|  353   video_capture_device->AllocateAndStart(params, std::move(device_client)); |  209   video_capture_device->AllocateAndStart(params, std::move(device_client)); | 
|  354   result_callback.Run(std::move(video_capture_device)); |  210   result_callback.Run(std::move(video_capture_device)); | 
|  355 } |  211 } | 
|  356  |  212  | 
|  357 void InProcessBuildableVideoCaptureDevice::DoStartTabCaptureOnDeviceThread( |  213 void InProcessVideoCaptureDeviceLauncher::DoStartTabCaptureOnDeviceThread( | 
|  358     const std::string& id, |  214     const std::string& id, | 
|  359     const media::VideoCaptureParams& params, |  215     const media::VideoCaptureParams& params, | 
|  360     std::unique_ptr<media::VideoCaptureDeviceClient> device_client, |  216     std::unique_ptr<media::VideoCaptureDeviceClient> device_client, | 
|  361     ReceiveDeviceCallback result_callback) { |  217     ReceiveDeviceCallback result_callback) { | 
|  362   SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |  218   SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 
|  363   DCHECK(device_task_runner_->BelongsToCurrentThread()); |  219   DCHECK(device_task_runner_->BelongsToCurrentThread()); | 
|  364  |  220  | 
|  365   std::unique_ptr<media::VideoCaptureDevice> video_capture_device; |  221   std::unique_ptr<media::VideoCaptureDevice> video_capture_device; | 
|  366 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) |  222 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) | 
|  367   video_capture_device = WebContentsVideoCaptureDevice::Create(id); |  223   video_capture_device = WebContentsVideoCaptureDevice::Create(id); | 
|  368 #endif |  224 #endif | 
|  369  |  225  | 
|  370   if (!video_capture_device) { |  226   if (!video_capture_device) { | 
|  371     result_callback.Run(nullptr); |  227     result_callback.Run(nullptr); | 
|  372     return; |  228     return; | 
|  373   } |  229   } | 
|  374  |  230  | 
|  375   video_capture_device->AllocateAndStart(params, std::move(device_client)); |  231   video_capture_device->AllocateAndStart(params, std::move(device_client)); | 
|  376   result_callback.Run(std::move(video_capture_device)); |  232   result_callback.Run(std::move(video_capture_device)); | 
|  377 } |  233 } | 
|  378  |  234  | 
|  379 void InProcessBuildableVideoCaptureDevice::DoStartDesktopCaptureOnDeviceThread( |  235 void InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread( | 
|  380     const std::string& id, |  236     const std::string& id, | 
|  381     const media::VideoCaptureParams& params, |  237     const media::VideoCaptureParams& params, | 
|  382     std::unique_ptr<media::VideoCaptureDeviceClient> device_client, |  238     std::unique_ptr<media::VideoCaptureDeviceClient> device_client, | 
|  383     ReceiveDeviceCallback result_callback) { |  239     ReceiveDeviceCallback result_callback) { | 
|  384   SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |  240   SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 
|  385   DCHECK(device_task_runner_->BelongsToCurrentThread()); |  241   DCHECK(device_task_runner_->BelongsToCurrentThread()); | 
|  386  |  242  | 
|  387   std::unique_ptr<media::VideoCaptureDevice> video_capture_device; |  243   std::unique_ptr<media::VideoCaptureDevice> video_capture_device; | 
|  388 #if defined(ENABLE_SCREEN_CAPTURE) |  244 #if defined(ENABLE_SCREEN_CAPTURE) | 
|  389   DesktopMediaID desktop_id = DesktopMediaID::Parse(id); |  245   DesktopMediaID desktop_id = DesktopMediaID::Parse(id); | 
|  390   if (desktop_id.is_null()) { |  246   if (desktop_id.is_null()) { | 
|  391     DLOG(ERROR) << "Desktop media ID is null"; |  247     DLOG(ERROR) << "Desktop media ID is null"; | 
|  392     result_callback.Run(nullptr); |  248     result_callback.Run(nullptr); | 
|  393     return; |  249     return; | 
|  394   } |  250   } | 
|  395  |  251  | 
|  396   if (desktop_id.type == DesktopMediaID::TYPE_WEB_CONTENTS) { |  252   if (desktop_id.type == DesktopMediaID::TYPE_WEB_CONTENTS) { | 
|  397 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) |  253 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) | 
|  398     video_capture_device = WebContentsVideoCaptureDevice::Create(id); |  254     video_capture_device = WebContentsVideoCaptureDevice::Create(id); | 
|  399     IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED); |  255     IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED); | 
|  400     if (desktop_id.audio_share) |  256     if (desktop_id.audio_share) { | 
|  401       IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITH_AUDIO); |  257       IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITH_AUDIO); | 
|  402     else |  258     } else { | 
|  403       IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITHOUT_AUDIO); |  259       IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITHOUT_AUDIO); | 
 |  260     } | 
|  404 #endif |  261 #endif | 
|  405   } else { |  262   } else { | 
|  406 #if defined(OS_ANDROID) |  263 #if defined(OS_ANDROID) | 
|  407     video_capture_device = base::MakeUnique<ScreenCaptureDeviceAndroid>(); |  264     video_capture_device = base::MakeUnique<ScreenCaptureDeviceAndroid>(); | 
|  408 #else |  265 #else | 
|  409 #if defined(USE_AURA) |  266 #if defined(USE_AURA) | 
|  410     video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id); |  267     video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id); | 
|  411 #endif  // defined(USE_AURA) |  268 #endif  // defined(USE_AURA) | 
|  412 #if BUILDFLAG(ENABLE_WEBRTC) |  269 #if BUILDFLAG(ENABLE_WEBRTC) | 
|  413     if (!video_capture_device) |  270     if (!video_capture_device) | 
|  414       video_capture_device = DesktopCaptureDevice::Create(desktop_id); |  271       video_capture_device = DesktopCaptureDevice::Create(desktop_id); | 
|  415 #endif  // BUILDFLAG(ENABLE_WEBRTC) |  272 #endif  // BUILDFLAG(ENABLE_WEBRTC) | 
|  416 #endif  // defined (OS_ANDROID) |  273 #endif  // defined (OS_ANDROID) | 
|  417   } |  274   } | 
|  418 #endif  // defined(ENABLE_SCREEN_CAPTURE) |  275 #endif  // defined(ENABLE_SCREEN_CAPTURE) | 
|  419  |  276  | 
|  420   if (!video_capture_device) { |  277   if (!video_capture_device) { | 
|  421     result_callback.Run(nullptr); |  278     result_callback.Run(nullptr); | 
|  422     return; |  279     return; | 
|  423   } |  280   } | 
|  424  |  281  | 
|  425   video_capture_device->AllocateAndStart(params, std::move(device_client)); |  282   video_capture_device->AllocateAndStart(params, std::move(device_client)); | 
|  426   result_callback.Run(std::move(video_capture_device)); |  283   result_callback.Run(std::move(video_capture_device)); | 
|  427 } |  284 } | 
|  428  |  285  | 
|  429 void InProcessBuildableVideoCaptureDevice:: |  | 
|  430     SetDesktopCaptureWindowIdOnDeviceThread(media::VideoCaptureDevice* device, |  | 
|  431                                             gfx::NativeViewId window_id, |  | 
|  432                                             base::OnceClosure done_cb) { |  | 
|  433   DCHECK(device_task_runner_->BelongsToCurrentThread()); |  | 
|  434 #if defined(ENABLE_SCREEN_CAPTURE) && BUILDFLAG(ENABLE_WEBRTC) && \ |  | 
|  435     !defined(OS_ANDROID) |  | 
|  436   DesktopCaptureDevice* desktop_device = |  | 
|  437       static_cast<DesktopCaptureDevice*>(device); |  | 
|  438   desktop_device->SetNotificationWindowId(window_id); |  | 
|  439   VLOG(2) << "Screen capture notification window passed on device thread."; |  | 
|  440 #endif |  | 
|  441   base::ResetAndReturn(&done_cb).Run(); |  | 
|  442 } |  | 
|  443  |  | 
|  444 }  // namespace content |  286 }  // namespace content | 
| OLD | NEW |