Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: content/browser/media/capture/web_contents_video_capture_device.cc

Issue 258663003: Use texture-backed VideoFrame pipeline for Aura desktop capturing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix a DCHECK failure in base::Bind. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 87
88 // Compute a letterbox region, aligned to even coordinates. 88 // Compute a letterbox region, aligned to even coordinates.
89 gfx::Rect ComputeYV12LetterboxRegion(const gfx::Size& frame_size, 89 gfx::Rect ComputeYV12LetterboxRegion(const gfx::Size& frame_size,
90 const gfx::Size& content_size) { 90 const gfx::Size& content_size) {
91 91
92 gfx::Rect result = media::ComputeLetterboxRegion(gfx::Rect(frame_size), 92 gfx::Rect result = media::ComputeLetterboxRegion(gfx::Rect(frame_size),
93 content_size); 93 content_size);
94 94
95 result.set_x(MakeEven(result.x())); 95 result.set_x(MakeEven(result.x()));
96 result.set_y(MakeEven(result.y())); 96 result.set_y(MakeEven(result.y()));
97 result.set_width(std::max(kMinFrameWidth, MakeEven(result.width())));
98 result.set_height(std::max(kMinFrameHeight, MakeEven(result.height())));
99 97
100 return result; 98 return result;
101 } 99 }
102 100
103 // Wrapper function to invoke ThreadSafeCaptureOracle::CaptureFrameCallback, is
104 // compatible with RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback.
105 void InvokeCaptureFrameCallback(
106 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
107 base::TimeTicks timestamp,
108 bool frame_captured) {
109 capture_frame_cb.Run(timestamp, frame_captured);
110 }
111
112 void DeleteOnWorkerThread(scoped_ptr<base::Thread> render_thread, 101 void DeleteOnWorkerThread(scoped_ptr<base::Thread> render_thread,
113 const base::Closure& callback) { 102 const base::Closure& callback) {
114 render_thread.reset(); 103 render_thread.reset();
115 104
116 // After thread join call the callback on UI thread. 105 // After thread join call the callback on UI thread.
117 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); 106 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
118 } 107 }
119 108
120 // Responsible for logging the effective frame rate. 109 // Responsible for logging the effective frame rate.
121 class VideoFrameDeliveryLog { 110 class VideoFrameDeliveryLog {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 // notification would get posted back to the UI thread and processed later, and 220 // notification would get posted back to the UI thread and processed later, and
232 // this seems disadvantageous. 221 // this seems disadvantageous.
233 class WebContentsCaptureMachine 222 class WebContentsCaptureMachine
234 : public VideoCaptureMachine, 223 : public VideoCaptureMachine,
235 public WebContentsObserver { 224 public WebContentsObserver {
236 public: 225 public:
237 WebContentsCaptureMachine(int render_process_id, int render_view_id); 226 WebContentsCaptureMachine(int render_process_id, int render_view_id);
238 virtual ~WebContentsCaptureMachine(); 227 virtual ~WebContentsCaptureMachine();
239 228
240 // VideoCaptureMachine overrides. 229 // VideoCaptureMachine overrides.
241 virtual bool Start( 230 virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
242 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE; 231 const media::VideoCaptureParams& params) OVERRIDE;
243 virtual void Stop(const base::Closure& callback) OVERRIDE; 232 virtual void Stop(const base::Closure& callback) OVERRIDE;
244 233
245 // Starts a copy from the backing store or the composited surface. Must be run 234 // Starts a copy from the backing store or the composited surface. Must be run
246 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation 235 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation
247 // completes. The copy will occur to |target|. 236 // completes. The copy will occur to |target|.
248 // 237 //
249 // This may be used as a ContentCaptureSubscription::CaptureCallback. 238 // This may be used as a ContentCaptureSubscription::CaptureCallback.
250 void Capture(const base::TimeTicks& start_time, 239 void Capture(const base::TimeTicks& start_time,
251 const scoped_refptr<media::VideoFrame>& target, 240 const scoped_refptr<media::VideoFrame>& target,
252 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& 241 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 const int initial_render_process_id_; 301 const int initial_render_process_id_;
313 const int initial_render_view_id_; 302 const int initial_render_view_id_;
314 303
315 // A dedicated worker thread on which SkBitmap->VideoFrame conversion will 304 // A dedicated worker thread on which SkBitmap->VideoFrame conversion will
316 // occur. Only used when this activity cannot be done on the GPU. 305 // occur. Only used when this activity cannot be done on the GPU.
317 scoped_ptr<base::Thread> render_thread_; 306 scoped_ptr<base::Thread> render_thread_;
318 307
319 // Makes all the decisions about which frames to copy, and how. 308 // Makes all the decisions about which frames to copy, and how.
320 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; 309 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
321 310
311 // Video capture parameters that this machine is started with.
312 media::VideoCaptureParams capture_params_;
313
322 // Routing ID of any active fullscreen render widget or MSG_ROUTING_NONE 314 // Routing ID of any active fullscreen render widget or MSG_ROUTING_NONE
323 // otherwise. 315 // otherwise.
324 int fullscreen_widget_id_; 316 int fullscreen_widget_id_;
325 317
326 // Last known RenderView size. 318 // Last known RenderView size.
327 gfx::Size last_view_size_; 319 gfx::Size last_view_size_;
328 320
329 // Responsible for forwarding events from the active RenderWidgetHost to the 321 // Responsible for forwarding events from the active RenderWidgetHost to the
330 // oracle, and initiating captures accordingly. 322 // oracle, and initiating captures accordingly.
331 scoped_ptr<ContentCaptureSubscription> subscription_; 323 scoped_ptr<ContentCaptureSubscription> subscription_;
332 324
333 // Weak pointer factory used to invalidate callbacks. 325 // Weak pointer factory used to invalidate callbacks.
334 // NOTE: Weak pointers must be invalidated before all other member variables. 326 // NOTE: Weak pointers must be invalidated before all other member variables.
335 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_; 327 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_;
336 328
337 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine); 329 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine);
338 }; 330 };
339 331
340 bool FrameSubscriber::ShouldCaptureFrame( 332 bool FrameSubscriber::ShouldCaptureFrame(
341 base::TimeTicks present_time, 333 base::TimeTicks present_time,
342 scoped_refptr<media::VideoFrame>* storage, 334 scoped_refptr<media::VideoFrame>* storage,
343 DeliverFrameCallback* deliver_frame_cb) { 335 DeliverFrameCallback* deliver_frame_cb) {
344 TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame", 336 TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame",
345 "instance", this); 337 "instance", this);
346 338
347 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; 339 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
348 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( 340 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture(
349 event_type_, present_time, storage, &capture_frame_cb); 341 event_type_, present_time, storage, &capture_frame_cb);
350 342
351 *deliver_frame_cb = base::Bind(&InvokeCaptureFrameCallback, capture_frame_cb); 343 if (!capture_frame_cb.is_null())
344 *deliver_frame_cb = base::Bind(capture_frame_cb, *storage);
352 if (oracle_decision) 345 if (oracle_decision)
353 delivery_log_->ChronicleFrameDelivery(present_time); 346 delivery_log_->ChronicleFrameDelivery(present_time);
354 return oracle_decision; 347 return oracle_decision;
355 } 348 }
356 349
357 ContentCaptureSubscription::ContentCaptureSubscription( 350 ContentCaptureSubscription::ContentCaptureSubscription(
358 const RenderWidgetHost& source, 351 const RenderWidgetHost& source,
359 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, 352 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
360 const CaptureCallback& capture_callback) 353 const CaptureCallback& capture_callback)
361 : render_process_id_(source.GetProcess()->GetID()), 354 : render_process_id_(source.GetProcess()->GetID()),
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 weak_ptr_factory_(this) {} 564 weak_ptr_factory_(this) {}
572 565
573 WebContentsCaptureMachine::~WebContentsCaptureMachine() { 566 WebContentsCaptureMachine::~WebContentsCaptureMachine() {
574 BrowserThread::PostBlockingPoolTask( 567 BrowserThread::PostBlockingPoolTask(
575 FROM_HERE, 568 FROM_HERE,
576 base::Bind(&DeleteOnWorkerThread, base::Passed(&render_thread_), 569 base::Bind(&DeleteOnWorkerThread, base::Passed(&render_thread_),
577 base::Bind(&base::DoNothing))); 570 base::Bind(&base::DoNothing)));
578 } 571 }
579 572
580 bool WebContentsCaptureMachine::Start( 573 bool WebContentsCaptureMachine::Start(
581 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) { 574 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
575 const media::VideoCaptureParams& params) {
582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
583 DCHECK(!started_); 577 DCHECK(!started_);
584 578
585 DCHECK(oracle_proxy.get()); 579 DCHECK(oracle_proxy.get());
586 oracle_proxy_ = oracle_proxy; 580 oracle_proxy_ = oracle_proxy;
581 capture_params_ = params;
587 582
588 render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread")); 583 render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread"));
589 if (!render_thread_->Start()) { 584 if (!render_thread_->Start()) {
590 DVLOG(1) << "Failed to spawn render thread."; 585 DVLOG(1) << "Failed to spawn render thread.";
591 render_thread_.reset(); 586 render_thread_.reset();
592 return false; 587 return false;
593 } 588 }
594 589
595 if (!StartObservingWebContents()) { 590 if (!StartObservingWebContents()) {
596 DVLOG(1) << "Failed to observe web contents."; 591 DVLOG(1) << "Failed to observe web contents.";
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 scoped_ptr<Client> client) { 821 scoped_ptr<Client> client) {
827 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 822 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
828 core_->AllocateAndStart(params, client.Pass()); 823 core_->AllocateAndStart(params, client.Pass());
829 } 824 }
830 825
831 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { 826 void WebContentsVideoCaptureDevice::StopAndDeAllocate() {
832 core_->StopAndDeAllocate(); 827 core_->StopAndDeAllocate();
833 } 828 }
834 829
835 } // namespace content 830 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698