| 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 // Implementation notes: This needs to work on a variety of hardware | 5 // Implementation notes: This needs to work on a variety of hardware |
| 6 // configurations where the speed of the CPU and GPU greatly affect overall | 6 // configurations where the speed of the CPU and GPU greatly affect overall |
| 7 // performance. Spanning several threads, the process of capturing has been | 7 // performance. Spanning several threads, the process of capturing has been |
| 8 // split up into four conceptual stages: | 8 // split up into four conceptual stages: |
| 9 // | 9 // |
| 10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's | 10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 #include "base/location.h" | 56 #include "base/location.h" |
| 57 #include "base/logging.h" | 57 #include "base/logging.h" |
| 58 #include "base/memory/scoped_ptr.h" | 58 #include "base/memory/scoped_ptr.h" |
| 59 #include "base/memory/weak_ptr.h" | 59 #include "base/memory/weak_ptr.h" |
| 60 #include "base/metrics/histogram.h" | 60 #include "base/metrics/histogram.h" |
| 61 #include "base/sequenced_task_runner.h" | 61 #include "base/sequenced_task_runner.h" |
| 62 #include "base/single_thread_task_runner.h" | 62 #include "base/single_thread_task_runner.h" |
| 63 #include "base/threading/thread.h" | 63 #include "base/threading/thread.h" |
| 64 #include "base/threading/thread_checker.h" | 64 #include "base/threading/thread_checker.h" |
| 65 #include "base/time/time.h" | 65 #include "base/time/time.h" |
| 66 #include "content/browser/media/capture/content_video_capture_device_core.h" | |
| 67 #include "content/browser/media/capture/video_capture_oracle.h" | |
| 68 #include "content/browser/media/capture/web_contents_capture_util.h" | 66 #include "content/browser/media/capture/web_contents_capture_util.h" |
| 69 #include "content/browser/media/capture/web_contents_tracker.h" | 67 #include "content/browser/media/capture/web_contents_tracker.h" |
| 70 #include "content/browser/renderer_host/render_widget_host_impl.h" | 68 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 71 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 69 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
| 72 #include "content/public/browser/browser_thread.h" | 70 #include "content/public/browser/browser_thread.h" |
| 73 #include "content/public/browser/render_process_host.h" | 71 #include "content/public/browser/render_process_host.h" |
| 74 #include "content/public/browser/render_widget_host_view.h" | 72 #include "content/public/browser/render_widget_host_view.h" |
| 75 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 73 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 76 #include "content/public/browser/web_contents.h" | 74 #include "content/public/browser/web_contents.h" |
| 77 #include "media/base/video_capture_types.h" | 75 #include "media/base/video_capture_types.h" |
| 78 #include "media/base/video_util.h" | 76 #include "media/base/video_util.h" |
| 77 #include "media/capture/screen_capture_device_core.h" |
| 78 #include "media/capture/thread_safe_capture_oracle.h" |
| 79 #include "media/capture/video_capture_oracle.h" |
| 79 #include "skia/ext/image_operations.h" | 80 #include "skia/ext/image_operations.h" |
| 80 #include "third_party/skia/include/core/SkBitmap.h" | 81 #include "third_party/skia/include/core/SkBitmap.h" |
| 81 #include "third_party/skia/include/core/SkColor.h" | 82 #include "third_party/skia/include/core/SkColor.h" |
| 82 #include "ui/gfx/display.h" | 83 #include "ui/gfx/display.h" |
| 83 #include "ui/gfx/geometry/size_conversions.h" | 84 #include "ui/gfx/geometry/size_conversions.h" |
| 84 #include "ui/gfx/screen.h" | 85 #include "ui/gfx/screen.h" |
| 85 | 86 |
| 86 namespace content { | 87 namespace content { |
| 87 | 88 |
| 88 namespace { | 89 namespace { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 109 base::TimeTicks last_frame_rate_log_time_; | 110 base::TimeTicks last_frame_rate_log_time_; |
| 110 int count_frames_rendered_; | 111 int count_frames_rendered_; |
| 111 | 112 |
| 112 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliveryLog); | 113 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliveryLog); |
| 113 }; | 114 }; |
| 114 | 115 |
| 115 // FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible | 116 // FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible |
| 116 // with RenderWidgetHostViewFrameSubscriber. We create one per event type. | 117 // with RenderWidgetHostViewFrameSubscriber. We create one per event type. |
| 117 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { | 118 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { |
| 118 public: | 119 public: |
| 119 FrameSubscriber(VideoCaptureOracle::Event event_type, | 120 FrameSubscriber(media::VideoCaptureOracle::Event event_type, |
| 120 const scoped_refptr<ThreadSafeCaptureOracle>& oracle, | 121 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle, |
| 121 VideoFrameDeliveryLog* delivery_log) | 122 VideoFrameDeliveryLog* delivery_log) |
| 122 : event_type_(event_type), | 123 : event_type_(event_type), |
| 123 oracle_proxy_(oracle), | 124 oracle_proxy_(oracle), |
| 124 delivery_log_(delivery_log) {} | 125 delivery_log_(delivery_log) {} |
| 125 | 126 |
| 126 bool ShouldCaptureFrame( | 127 bool ShouldCaptureFrame( |
| 127 const gfx::Rect& damage_rect, | 128 const gfx::Rect& damage_rect, |
| 128 base::TimeTicks present_time, | 129 base::TimeTicks present_time, |
| 129 scoped_refptr<media::VideoFrame>* storage, | 130 scoped_refptr<media::VideoFrame>* storage, |
| 130 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* | 131 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* |
| 131 deliver_frame_cb) override; | 132 deliver_frame_cb) override; |
| 132 | 133 |
| 133 private: | 134 private: |
| 134 const VideoCaptureOracle::Event event_type_; | 135 const media::VideoCaptureOracle::Event event_type_; |
| 135 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; | 136 scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_; |
| 136 VideoFrameDeliveryLog* const delivery_log_; | 137 VideoFrameDeliveryLog* const delivery_log_; |
| 137 }; | 138 }; |
| 138 | 139 |
| 139 // ContentCaptureSubscription is the relationship between a RenderWidgetHost | 140 // ContentCaptureSubscription is the relationship between a RenderWidgetHost |
| 140 // whose content is updating, a subscriber that is deciding which of these | 141 // whose content is updating, a subscriber that is deciding which of these |
| 141 // updates to capture (and where to deliver them to), and a callback that | 142 // updates to capture (and where to deliver them to), and a callback that |
| 142 // knows how to do the capture and prepare the result for delivery. | 143 // knows how to do the capture and prepare the result for delivery. |
| 143 // | 144 // |
| 144 // In practice, this means (a) installing a RenderWidgetHostFrameSubscriber in | 145 // In practice, this means (a) installing a RenderWidgetHostFrameSubscriber in |
| 145 // the RenderWidgetHostView, to process compositor updates, and (b) running a | 146 // the RenderWidgetHostView, to process compositor updates, and (b) running a |
| 146 // timer to possibly initiate forced, non-event-driven captures needed by | 147 // timer to possibly initiate forced, non-event-driven captures needed by |
| 147 // downstream consumers that require frame repeats of unchanged content. | 148 // downstream consumers that require frame repeats of unchanged content. |
| 148 // | 149 // |
| 149 // All of this happens on the UI thread, although the | 150 // All of this happens on the UI thread, although the |
| 150 // RenderWidgetHostViewFrameSubscriber we install may be dispatching updates | 151 // RenderWidgetHostViewFrameSubscriber we install may be dispatching updates |
| 151 // autonomously on some other thread. | 152 // autonomously on some other thread. |
| 152 class ContentCaptureSubscription { | 153 class ContentCaptureSubscription { |
| 153 public: | 154 public: |
| 154 typedef base::Callback< | 155 typedef base::Callback< |
| 155 void(const base::TimeTicks&, | 156 void(const base::TimeTicks&, |
| 156 const scoped_refptr<media::VideoFrame>&, | 157 const scoped_refptr<media::VideoFrame>&, |
| 157 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&)> | 158 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&)> |
| 158 CaptureCallback; | 159 CaptureCallback; |
| 159 | 160 |
| 160 // Create a subscription. Whenever a manual capture is required, the | 161 // Create a subscription. Whenever a manual capture is required, the |
| 161 // subscription will invoke |capture_callback| on the UI thread to do the | 162 // subscription will invoke |capture_callback| on the UI thread to do the |
| 162 // work. | 163 // work. |
| 163 ContentCaptureSubscription( | 164 ContentCaptureSubscription( |
| 164 const RenderWidgetHost& source, | 165 const RenderWidgetHost& source, |
| 165 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 166 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, |
| 166 const CaptureCallback& capture_callback); | 167 const CaptureCallback& capture_callback); |
| 167 ~ContentCaptureSubscription(); | 168 ~ContentCaptureSubscription(); |
| 168 | 169 |
| 169 private: | 170 private: |
| 170 void OnTimer(); | 171 void OnTimer(); |
| 171 | 172 |
| 172 // Maintain a weak reference to the RenderWidgetHost (via its routing ID), | 173 // Maintain a weak reference to the RenderWidgetHost (via its routing ID), |
| 173 // since the instance could be destroyed externally during the lifetime of | 174 // since the instance could be destroyed externally during the lifetime of |
| 174 // |this|. | 175 // |this|. |
| 175 const int render_process_id_; | 176 const int render_process_id_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 191 // This software implementation should be used only when GPU acceleration of | 192 // This software implementation should be used only when GPU acceleration of |
| 192 // these activities is not possible. This operation may be expensive (tens to | 193 // these activities is not possible. This operation may be expensive (tens to |
| 193 // hundreds of milliseconds), so the caller should ensure that it runs on a | 194 // hundreds of milliseconds), so the caller should ensure that it runs on a |
| 194 // thread where such a pause would cause UI jank. | 195 // thread where such a pause would cause UI jank. |
| 195 void RenderVideoFrame(const SkBitmap& input, | 196 void RenderVideoFrame(const SkBitmap& input, |
| 196 const scoped_refptr<media::VideoFrame>& output, | 197 const scoped_refptr<media::VideoFrame>& output, |
| 197 const base::Callback<void(bool)>& done_cb); | 198 const base::Callback<void(bool)>& done_cb); |
| 198 | 199 |
| 199 // Renews capture subscriptions based on feedback from WebContentsTracker, and | 200 // Renews capture subscriptions based on feedback from WebContentsTracker, and |
| 200 // also executes copying of the backing store on the UI BrowserThread. | 201 // also executes copying of the backing store on the UI BrowserThread. |
| 201 class WebContentsCaptureMachine : public VideoCaptureMachine { | 202 class WebContentsCaptureMachine : public media::VideoCaptureMachine { |
| 202 public: | 203 public: |
| 203 WebContentsCaptureMachine(int render_process_id, int main_render_frame_id); | 204 WebContentsCaptureMachine(int render_process_id, int main_render_frame_id); |
| 204 ~WebContentsCaptureMachine() override; | 205 ~WebContentsCaptureMachine() override; |
| 205 | 206 |
| 206 // VideoCaptureMachine overrides. | 207 // VideoCaptureMachine overrides. |
| 207 bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 208 void Start(const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, |
| 208 const media::VideoCaptureParams& params) override; | 209 const media::VideoCaptureParams& params, |
| 210 const base::Callback<void(bool)> callback) override; |
| 209 void Stop(const base::Closure& callback) override; | 211 void Stop(const base::Closure& callback) override; |
| 210 | 212 |
| 211 // Starts a copy from the backing store or the composited surface. Must be run | 213 // Starts a copy from the backing store or the composited surface. Must be run |
| 212 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation | 214 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation |
| 213 // completes. The copy will occur to |target|. | 215 // completes. The copy will occur to |target|. |
| 214 // | 216 // |
| 215 // This may be used as a ContentCaptureSubscription::CaptureCallback. | 217 // This may be used as a ContentCaptureSubscription::CaptureCallback. |
| 216 void Capture(const base::TimeTicks& start_time, | 218 void Capture(const base::TimeTicks& start_time, |
| 217 const scoped_refptr<media::VideoFrame>& target, | 219 const scoped_refptr<media::VideoFrame>& target, |
| 218 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 220 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
| 219 deliver_frame_cb); | 221 deliver_frame_cb); |
| 220 | 222 |
| 221 private: | 223 private: |
| 224 bool InternalStart( |
| 225 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, |
| 226 const media::VideoCaptureParams& params); |
| 227 void InternalStop(const base::Closure& callback); |
| 222 bool IsStarted() const; | 228 bool IsStarted() const; |
| 223 | 229 |
| 224 // Computes the preferred size of the target RenderWidget for optimal capture. | 230 // Computes the preferred size of the target RenderWidget for optimal capture. |
| 225 gfx::Size ComputeOptimalTargetSize() const; | 231 gfx::Size ComputeOptimalTargetSize() const; |
| 226 | 232 |
| 227 // Response callback for RenderWidgetHost::CopyFromBackingStore(). | 233 // Response callback for RenderWidgetHost::CopyFromBackingStore(). |
| 228 void DidCopyFromBackingStore( | 234 void DidCopyFromBackingStore( |
| 229 const base::TimeTicks& start_time, | 235 const base::TimeTicks& start_time, |
| 230 const scoped_refptr<media::VideoFrame>& target, | 236 const scoped_refptr<media::VideoFrame>& target, |
| 231 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 237 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
| (...skipping 21 matching lines...) Expand all Loading... |
| 253 | 259 |
| 254 // Tracks events and calls back to RenewFrameSubscription() to maintain | 260 // Tracks events and calls back to RenewFrameSubscription() to maintain |
| 255 // capture on the correct RenderWidgetHost. | 261 // capture on the correct RenderWidgetHost. |
| 256 const scoped_refptr<WebContentsTracker> tracker_; | 262 const scoped_refptr<WebContentsTracker> tracker_; |
| 257 | 263 |
| 258 // A dedicated worker thread on which SkBitmap->VideoFrame conversion will | 264 // A dedicated worker thread on which SkBitmap->VideoFrame conversion will |
| 259 // occur. Only used when this activity cannot be done on the GPU. | 265 // occur. Only used when this activity cannot be done on the GPU. |
| 260 scoped_ptr<base::Thread> render_thread_; | 266 scoped_ptr<base::Thread> render_thread_; |
| 261 | 267 |
| 262 // Makes all the decisions about which frames to copy, and how. | 268 // Makes all the decisions about which frames to copy, and how. |
| 263 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; | 269 scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_; |
| 264 | 270 |
| 265 // Video capture parameters that this machine is started with. | 271 // Video capture parameters that this machine is started with. |
| 266 media::VideoCaptureParams capture_params_; | 272 media::VideoCaptureParams capture_params_; |
| 267 | 273 |
| 268 // Last known RenderView size. | 274 // Last known RenderView size. |
| 269 gfx::Size last_view_size_; | 275 gfx::Size last_view_size_; |
| 270 | 276 |
| 271 // Responsible for forwarding events from the active RenderWidgetHost to the | 277 // Responsible for forwarding events from the active RenderWidgetHost to the |
| 272 // oracle, and initiating captures accordingly. | 278 // oracle, and initiating captures accordingly. |
| 273 scoped_ptr<ContentCaptureSubscription> subscription_; | 279 scoped_ptr<ContentCaptureSubscription> subscription_; |
| 274 | 280 |
| 275 // Weak pointer factory used to invalidate callbacks. | 281 // Weak pointer factory used to invalidate callbacks. |
| 276 // NOTE: Weak pointers must be invalidated before all other member variables. | 282 // NOTE: Weak pointers must be invalidated before all other member variables. |
| 277 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_; | 283 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_; |
| 278 | 284 |
| 279 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine); | 285 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine); |
| 280 }; | 286 }; |
| 281 | 287 |
| 282 bool FrameSubscriber::ShouldCaptureFrame( | 288 bool FrameSubscriber::ShouldCaptureFrame( |
| 283 const gfx::Rect& damage_rect, | 289 const gfx::Rect& damage_rect, |
| 284 base::TimeTicks present_time, | 290 base::TimeTicks present_time, |
| 285 scoped_refptr<media::VideoFrame>* storage, | 291 scoped_refptr<media::VideoFrame>* storage, |
| 286 DeliverFrameCallback* deliver_frame_cb) { | 292 DeliverFrameCallback* deliver_frame_cb) { |
| 287 TRACE_EVENT1("gpu.capture", "FrameSubscriber::ShouldCaptureFrame", | 293 TRACE_EVENT1("gpu.capture", "FrameSubscriber::ShouldCaptureFrame", |
| 288 "instance", this); | 294 "instance", this); |
| 289 | 295 |
| 290 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; | 296 media::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; |
| 291 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( | 297 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( |
| 292 event_type_, damage_rect, present_time, storage, &capture_frame_cb); | 298 event_type_, damage_rect, present_time, storage, &capture_frame_cb); |
| 293 | 299 |
| 294 if (!capture_frame_cb.is_null()) | 300 if (!capture_frame_cb.is_null()) |
| 295 *deliver_frame_cb = base::Bind(capture_frame_cb, *storage); | 301 *deliver_frame_cb = base::Bind(capture_frame_cb, *storage); |
| 296 if (oracle_decision) | 302 if (oracle_decision) |
| 297 delivery_log_->ChronicleFrameDelivery(present_time); | 303 delivery_log_->ChronicleFrameDelivery(present_time); |
| 298 return oracle_decision; | 304 return oracle_decision; |
| 299 } | 305 } |
| 300 | 306 |
| 301 ContentCaptureSubscription::ContentCaptureSubscription( | 307 ContentCaptureSubscription::ContentCaptureSubscription( |
| 302 const RenderWidgetHost& source, | 308 const RenderWidgetHost& source, |
| 303 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 309 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, |
| 304 const CaptureCallback& capture_callback) | 310 const CaptureCallback& capture_callback) |
| 305 : render_process_id_(source.GetProcess()->GetID()), | 311 : render_process_id_(source.GetProcess()->GetID()), |
| 306 render_widget_id_(source.GetRoutingID()), | 312 render_widget_id_(source.GetRoutingID()), |
| 307 delivery_log_(), | 313 delivery_log_(), |
| 308 timer_subscriber_(VideoCaptureOracle::kTimerPoll, oracle_proxy, | 314 timer_subscriber_(media::VideoCaptureOracle::kTimerPoll, oracle_proxy, |
| 309 &delivery_log_), | 315 &delivery_log_), |
| 310 capture_callback_(capture_callback), | 316 capture_callback_(capture_callback), |
| 311 timer_(true, true) { | 317 timer_(true, true) { |
| 312 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 318 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 313 | 319 |
| 314 RenderWidgetHostView* const view = source.GetView(); | 320 RenderWidgetHostView* const view = source.GetView(); |
| 315 | 321 |
| 316 // Subscribe to compositor updates. These will be serviced directly by the | 322 // Subscribe to compositor updates. These will be serviced directly by the |
| 317 // oracle. | 323 // oracle. |
| 318 if (view) { | 324 if (view) { |
| 319 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber( | 325 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber( |
| 320 new FrameSubscriber(VideoCaptureOracle::kCompositorUpdate, | 326 new FrameSubscriber(media::VideoCaptureOracle::kCompositorUpdate, |
| 321 oracle_proxy, &delivery_log_)); | 327 oracle_proxy, &delivery_log_)); |
| 322 view->BeginFrameSubscription(subscriber.Pass()); | 328 view->BeginFrameSubscription(subscriber.Pass()); |
| 323 } | 329 } |
| 324 | 330 |
| 325 // Subscribe to timer events. This instance will service these as well. | 331 // Subscribe to timer events. This instance will service these as well. |
| 326 timer_.Start(FROM_HERE, | 332 timer_.Start(FROM_HERE, |
| 327 std::max(oracle_proxy->min_capture_period(), | 333 std::max(oracle_proxy->min_capture_period(), |
| 328 base::TimeDelta::FromMilliseconds( | 334 base::TimeDelta::FromMilliseconds(media |
| 329 VideoCaptureOracle::kMinTimerPollPeriodMillis)), | 335 ::VideoCaptureOracle::kMinTimerPollPeriodMillis)), |
| 330 base::Bind(&ContentCaptureSubscription::OnTimer, | 336 base::Bind(&ContentCaptureSubscription::OnTimer, |
| 331 base::Unretained(this))); | 337 base::Unretained(this))); |
| 332 } | 338 } |
| 333 | 339 |
| 334 ContentCaptureSubscription::~ContentCaptureSubscription() { | 340 ContentCaptureSubscription::~ContentCaptureSubscription() { |
| 335 // If the BrowserThreads have been torn down, then the browser is in the final | 341 // If the BrowserThreads have been torn down, then the browser is in the final |
| 336 // stages of exiting and it is dangerous to take any further action. We must | 342 // stages of exiting and it is dangerous to take any further action. We must |
| 337 // return early. http://crbug.com/396413 | 343 // return early. http://crbug.com/396413 |
| 338 if (!BrowserThread::IsMessageLoopValid(BrowserThread::UI)) | 344 if (!BrowserThread::IsMessageLoopValid(BrowserThread::UI)) |
| 339 return; | 345 return; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 tracker_(new WebContentsTracker(true)), | 482 tracker_(new WebContentsTracker(true)), |
| 477 weak_ptr_factory_(this) {} | 483 weak_ptr_factory_(this) {} |
| 478 | 484 |
| 479 WebContentsCaptureMachine::~WebContentsCaptureMachine() {} | 485 WebContentsCaptureMachine::~WebContentsCaptureMachine() {} |
| 480 | 486 |
| 481 bool WebContentsCaptureMachine::IsStarted() const { | 487 bool WebContentsCaptureMachine::IsStarted() const { |
| 482 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 488 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 483 return weak_ptr_factory_.HasWeakPtrs(); | 489 return weak_ptr_factory_.HasWeakPtrs(); |
| 484 } | 490 } |
| 485 | 491 |
| 486 bool WebContentsCaptureMachine::Start( | 492 void WebContentsCaptureMachine::Start( |
| 487 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 493 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, |
| 494 const media::VideoCaptureParams& params, |
| 495 const base::Callback<void(bool)> callback) { |
| 496 // Starts the capture machine asynchronously. |
| 497 BrowserThread::PostTaskAndReplyWithResult( |
| 498 BrowserThread::UI, |
| 499 FROM_HERE, |
| 500 base::Bind(&WebContentsCaptureMachine::InternalStart, |
| 501 base::Unretained(this), |
| 502 oracle_proxy, |
| 503 params), |
| 504 callback); |
| 505 } |
| 506 |
| 507 bool WebContentsCaptureMachine::InternalStart( |
| 508 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, |
| 488 const media::VideoCaptureParams& params) { | 509 const media::VideoCaptureParams& params) { |
| 489 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 510 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 490 DCHECK(!IsStarted()); | 511 DCHECK(!IsStarted()); |
| 491 | 512 |
| 492 DCHECK(oracle_proxy.get()); | 513 DCHECK(oracle_proxy.get()); |
| 493 oracle_proxy_ = oracle_proxy; | 514 oracle_proxy_ = oracle_proxy; |
| 494 capture_params_ = params; | 515 capture_params_ = params; |
| 495 | 516 |
| 496 render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread")); | 517 render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread")); |
| 497 if (!render_thread_->Start()) { | 518 if (!render_thread_->Start()) { |
| 498 DVLOG(1) << "Failed to spawn render thread."; | 519 DVLOG(1) << "Failed to spawn render thread."; |
| 499 render_thread_.reset(); | 520 render_thread_.reset(); |
| 500 return false; | 521 return false; |
| 501 } | 522 } |
| 502 | 523 |
| 503 // Note: Creation of the first WeakPtr in the following statement will cause | 524 // Note: Creation of the first WeakPtr in the following statement will cause |
| 504 // IsStarted() to return true from now on. | 525 // IsStarted() to return true from now on. |
| 505 tracker_->SetResizeChangeCallback( | 526 tracker_->SetResizeChangeCallback( |
| 506 base::Bind(&WebContentsCaptureMachine::UpdateCaptureSize, | 527 base::Bind(&WebContentsCaptureMachine::UpdateCaptureSize, |
| 507 weak_ptr_factory_.GetWeakPtr())); | 528 weak_ptr_factory_.GetWeakPtr())); |
| 508 tracker_->Start(initial_render_process_id_, initial_main_render_frame_id_, | 529 tracker_->Start(initial_render_process_id_, initial_main_render_frame_id_, |
| 509 base::Bind(&WebContentsCaptureMachine::RenewFrameSubscription, | 530 base::Bind(&WebContentsCaptureMachine::RenewFrameSubscription, |
| 510 weak_ptr_factory_.GetWeakPtr())); | 531 weak_ptr_factory_.GetWeakPtr())); |
| 511 | 532 |
| 512 return true; | 533 return true; |
| 513 } | 534 } |
| 514 | 535 |
| 515 void WebContentsCaptureMachine::Stop(const base::Closure& callback) { | 536 void WebContentsCaptureMachine::Stop(const base::Closure& callback) { |
| 537 // Stops the capture machine asynchronously. |
| 538 BrowserThread::PostTask( |
| 539 BrowserThread::UI, FROM_HERE, base::Bind( |
| 540 &WebContentsCaptureMachine::InternalStop, |
| 541 base::Unretained(this), |
| 542 callback)); |
| 543 } |
| 544 |
| 545 void WebContentsCaptureMachine::InternalStop(const base::Closure& callback) { |
| 516 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 546 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 517 | 547 |
| 518 if (!IsStarted()) { | 548 if (!IsStarted()) { |
| 519 callback.Run(); | 549 callback.Run(); |
| 520 return; | 550 return; |
| 521 } | 551 } |
| 522 | 552 |
| 523 // The following cancels any outstanding callbacks and causes IsStarted() to | 553 // The following cancels any outstanding callbacks and causes IsStarted() to |
| 524 // return false from here onward. | 554 // return false from here onward. |
| 525 weak_ptr_factory_.InvalidateWeakPtrs(); | 555 weak_ptr_factory_.InvalidateWeakPtrs(); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 RenderWidgetHostView* const view = rwh ? rwh->GetView() : nullptr; | 734 RenderWidgetHostView* const view = rwh ? rwh->GetView() : nullptr; |
| 705 if (!view) | 735 if (!view) |
| 706 return; | 736 return; |
| 707 oracle_proxy_->UpdateCaptureSize(view->GetViewBounds().size()); | 737 oracle_proxy_->UpdateCaptureSize(view->GetViewBounds().size()); |
| 708 } | 738 } |
| 709 | 739 |
| 710 } // namespace | 740 } // namespace |
| 711 | 741 |
| 712 WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice( | 742 WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice( |
| 713 int render_process_id, int main_render_frame_id) | 743 int render_process_id, int main_render_frame_id) |
| 714 : core_(new ContentVideoCaptureDeviceCore(scoped_ptr<VideoCaptureMachine>( | 744 : core_(new media::ScreenCaptureDeviceCore( |
| 715 new WebContentsCaptureMachine( | 745 scoped_ptr<media::VideoCaptureMachine>(new WebContentsCaptureMachine( |
| 716 render_process_id, main_render_frame_id)))) {} | 746 render_process_id, main_render_frame_id)))) {} |
| 717 | 747 |
| 718 WebContentsVideoCaptureDevice::~WebContentsVideoCaptureDevice() { | 748 WebContentsVideoCaptureDevice::~WebContentsVideoCaptureDevice() { |
| 719 DVLOG(2) << "WebContentsVideoCaptureDevice@" << this << " destroying."; | 749 DVLOG(2) << "WebContentsVideoCaptureDevice@" << this << " destroying."; |
| 720 } | 750 } |
| 721 | 751 |
| 722 // static | 752 // static |
| 723 media::VideoCaptureDevice* WebContentsVideoCaptureDevice::Create( | 753 media::VideoCaptureDevice* WebContentsVideoCaptureDevice::Create( |
| 724 const std::string& device_id) { | 754 const std::string& device_id) { |
| 725 // Parse device_id into render_process_id and main_render_frame_id. | 755 // Parse device_id into render_process_id and main_render_frame_id. |
| 726 int render_process_id = -1; | 756 int render_process_id = -1; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 739 scoped_ptr<Client> client) { | 769 scoped_ptr<Client> client) { |
| 740 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); | 770 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); |
| 741 core_->AllocateAndStart(params, client.Pass()); | 771 core_->AllocateAndStart(params, client.Pass()); |
| 742 } | 772 } |
| 743 | 773 |
| 744 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { | 774 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { |
| 745 core_->StopAndDeAllocate(); | 775 core_->StopAndDeAllocate(); |
| 746 } | 776 } |
| 747 | 777 |
| 748 } // namespace content | 778 } // namespace content |
| OLD | NEW |