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 |