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