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

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

Issue 258663003: Use texture-backed VideoFrame pipeline for Aura desktop capturing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased at trunk (r267290 changed ReleaseMailboxCB). Created 6 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/media/capture/desktop_capture_device_aura.h" 5 #include "content/browser/media/capture/desktop_capture_device_aura.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/timer/timer.h" 9 #include "base/timer/timer.h"
10 #include "cc/output/copy_output_request.h" 10 #include "cc/output/copy_output_request.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 class DesktopVideoCaptureMachine 90 class DesktopVideoCaptureMachine
91 : public VideoCaptureMachine, 91 : public VideoCaptureMachine,
92 public aura::WindowObserver, 92 public aura::WindowObserver,
93 public ui::CompositorObserver, 93 public ui::CompositorObserver,
94 public base::SupportsWeakPtr<DesktopVideoCaptureMachine> { 94 public base::SupportsWeakPtr<DesktopVideoCaptureMachine> {
95 public: 95 public:
96 DesktopVideoCaptureMachine(const DesktopMediaID& source); 96 DesktopVideoCaptureMachine(const DesktopMediaID& source);
97 virtual ~DesktopVideoCaptureMachine(); 97 virtual ~DesktopVideoCaptureMachine();
98 98
99 // VideoCaptureFrameSource overrides. 99 // VideoCaptureFrameSource overrides.
100 virtual bool Start( 100 virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
101 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE; 101 const media::VideoCaptureParams& params) OVERRIDE;
102 virtual void Stop(const base::Closure& callback) OVERRIDE; 102 virtual void Stop(const base::Closure& callback) OVERRIDE;
103 103
104 // Implements aura::WindowObserver. 104 // Implements aura::WindowObserver.
105 virtual void OnWindowBoundsChanged(aura::Window* window, 105 virtual void OnWindowBoundsChanged(aura::Window* window,
106 const gfx::Rect& old_bounds, 106 const gfx::Rect& old_bounds,
107 const gfx::Rect& new_bounds) OVERRIDE; 107 const gfx::Rect& new_bounds) OVERRIDE;
108 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; 108 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
109 109
110 // Implements ui::CompositorObserver. 110 // Implements ui::CompositorObserver.
111 virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {} 111 virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {}
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 155
156 // The timer that kicks off period captures. 156 // The timer that kicks off period captures.
157 base::Timer timer_; 157 base::Timer timer_;
158 158
159 // The id of the window being captured. 159 // The id of the window being captured.
160 DesktopMediaID window_id_; 160 DesktopMediaID window_id_;
161 161
162 // Makes all the decisions about which frames to copy, and how. 162 // Makes all the decisions about which frames to copy, and how.
163 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; 163 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
164 164
165 // The capture parameters for this capture.
166 media::VideoCaptureParams capture_params_;
167
165 // YUV readback pipeline. 168 // YUV readback pipeline.
166 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_; 169 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_;
167 170
168 // Cursor state. 171 // Cursor state.
169 ui::Cursor last_cursor_; 172 ui::Cursor last_cursor_;
170 gfx::Point cursor_hot_point_; 173 gfx::Point cursor_hot_point_;
171 SkBitmap scaled_cursor_bitmap_; 174 SkBitmap scaled_cursor_bitmap_;
172 175
173 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine); 176 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine);
174 }; 177 };
175 178
176 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine( 179 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine(
177 const DesktopMediaID& source) 180 const DesktopMediaID& source)
178 : desktop_window_(NULL), 181 : desktop_window_(NULL),
179 desktop_layer_(NULL), 182 desktop_layer_(NULL),
180 timer_(true, true), 183 timer_(true, true),
181 window_id_(source) {} 184 window_id_(source) {}
182 185
183 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {} 186 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {}
184 187
185 bool DesktopVideoCaptureMachine::Start( 188 bool DesktopVideoCaptureMachine::Start(
186 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) { 189 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
190 const media::VideoCaptureParams& params) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
188 192
189 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_); 193 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_);
190 if (!desktop_window_) 194 if (!desktop_window_)
191 return false; 195 return false;
192 196
193 // If the desktop layer is already destroyed then return failure. 197 // If the desktop layer is already destroyed then return failure.
194 desktop_layer_ = desktop_window_->layer(); 198 desktop_layer_ = desktop_window_->layer();
195 if (!desktop_layer_) 199 if (!desktop_layer_)
196 return false; 200 return false;
197 201
198 DCHECK(oracle_proxy.get()); 202 DCHECK(oracle_proxy.get());
199 oracle_proxy_ = oracle_proxy; 203 oracle_proxy_ = oracle_proxy;
204 capture_params_ = params;
200 205
201 // Update capture size. 206 // Update capture size.
202 UpdateCaptureSize(); 207 UpdateCaptureSize();
203 208
204 // Start observing window events. 209 // Start observing window events.
205 desktop_window_->AddObserver(this); 210 desktop_window_->AddObserver(this);
206 211
207 // Start observing compositor updates. 212 // Start observing compositor updates.
208 ui::Compositor* compositor = desktop_layer_->GetCompositor(); 213 ui::Compositor* compositor = desktop_layer_->GetCompositor();
209 if (!compositor) 214 if (!compositor)
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 base::TimeTicks start_time, 292 base::TimeTicks start_time,
288 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 293 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
289 const scoped_refptr<media::VideoFrame>& target, 294 const scoped_refptr<media::VideoFrame>& target,
290 const SkBitmap& cursor_bitmap, 295 const SkBitmap& cursor_bitmap,
291 const gfx::Point& cursor_position, 296 const gfx::Point& cursor_position,
292 scoped_ptr<cc::SingleReleaseCallback> release_callback, 297 scoped_ptr<cc::SingleReleaseCallback> release_callback,
293 bool result) { 298 bool result) {
294 if (!cursor_bitmap.isNull()) 299 if (!cursor_bitmap.isNull())
295 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position); 300 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position);
296 release_callback->Run(0, false); 301 release_callback->Run(0, false);
297 capture_frame_cb.Run(start_time, result); 302 capture_frame_cb.Run(target, start_time, result);
303 }
304
305 void RunSingleReleaseCallback(scoped_ptr<cc::SingleReleaseCallback> cb,
306 const std::vector<uint32>& sync_points) {
307 // TODO(hshi): handle release of multiple sync points.
308 DCHECK_EQ(1u, sync_points.size());
309 cb->Run(sync_points[0], false);
298 } 310 }
299 311
300 void DesktopVideoCaptureMachine::DidCopyOutput( 312 void DesktopVideoCaptureMachine::DidCopyOutput(
301 scoped_refptr<media::VideoFrame> video_frame, 313 scoped_refptr<media::VideoFrame> video_frame,
302 base::TimeTicks start_time, 314 base::TimeTicks start_time,
303 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 315 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
304 scoped_ptr<cc::CopyOutputResult> result) { 316 scoped_ptr<cc::CopyOutputResult> result) {
305 static bool first_call = true; 317 static bool first_call = true;
306 318
307 bool succeeded = ProcessCopyOutputResponse( 319 bool succeeded = ProcessCopyOutputResponse(
(...skipping 19 matching lines...) Expand all
327 } 339 }
328 340
329 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse( 341 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse(
330 scoped_refptr<media::VideoFrame> video_frame, 342 scoped_refptr<media::VideoFrame> video_frame,
331 base::TimeTicks start_time, 343 base::TimeTicks start_time,
332 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 344 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
333 scoped_ptr<cc::CopyOutputResult> result) { 345 scoped_ptr<cc::CopyOutputResult> result) {
334 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) 346 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_)
335 return false; 347 return false;
336 348
349 if (capture_params_.requested_format.pixel_format ==
350 media::PIXEL_FORMAT_TEXTURE) {
351 DCHECK(!video_frame);
352 cc::TextureMailbox texture_mailbox;
353 scoped_ptr<cc::SingleReleaseCallback> release_callback;
354 result->TakeTexture(&texture_mailbox, &release_callback);
355 DCHECK(texture_mailbox.IsTexture());
356 if (!texture_mailbox.IsTexture())
357 return false;
358 video_frame = media::VideoFrame::WrapNativeTexture(
359 make_scoped_ptr(new gpu::MailboxHolder(texture_mailbox.mailbox(),
360 texture_mailbox.target(),
361 texture_mailbox.sync_point())),
362 base::Bind(&RunSingleReleaseCallback, base::Passed(&release_callback)),
363 result->size(),
364 gfx::Rect(result->size()),
365 result->size(),
366 base::TimeDelta(),
367 media::VideoFrame::ReadPixelsCB());
368 capture_frame_cb.Run(video_frame, start_time, true);
369 return true;
370 }
371
337 // Compute the dest size we want after the letterboxing resize. Make the 372 // Compute the dest size we want after the letterboxing resize. Make the
338 // coordinates and sizes even because we letterbox in YUV space 373 // coordinates and sizes even because we letterbox in YUV space
339 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to 374 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
340 // line up correctly. 375 // line up correctly.
341 // The video frame's coded_size() and the result's size() are both physical 376 // The video frame's coded_size() and the result's size() are both physical
342 // pixels. 377 // pixels.
343 gfx::Rect region_in_frame = 378 gfx::Rect region_in_frame =
344 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), 379 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()),
345 result->size()); 380 result->size());
346 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, 381 region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 IncrementDesktopCaptureCounter(source.type == DesktopMediaID::TYPE_SCREEN 510 IncrementDesktopCaptureCounter(source.type == DesktopMediaID::TYPE_SCREEN
476 ? SCREEN_CAPTURER_CREATED 511 ? SCREEN_CAPTURER_CREATED
477 : WINDOW_CATPTURER_CREATED); 512 : WINDOW_CATPTURER_CREATED);
478 return new DesktopCaptureDeviceAura(source); 513 return new DesktopCaptureDeviceAura(source);
479 } 514 }
480 515
481 void DesktopCaptureDeviceAura::AllocateAndStart( 516 void DesktopCaptureDeviceAura::AllocateAndStart(
482 const media::VideoCaptureParams& params, 517 const media::VideoCaptureParams& params,
483 scoped_ptr<Client> client) { 518 scoped_ptr<Client> client) {
484 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 519 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
485 core_->AllocateAndStart(params, client.Pass()); 520 media::VideoCaptureParams new_params = params;
521 // Desktop capture devices ignore the requested size and return the actual
522 // captured desktop size.
523 new_params.requested_format.frame_size.SetSize(0, 0);
524 core_->AllocateAndStart(new_params, client.Pass());
486 } 525 }
487 526
488 void DesktopCaptureDeviceAura::StopAndDeAllocate() { 527 void DesktopCaptureDeviceAura::StopAndDeAllocate() {
489 core_->StopAndDeAllocate(); 528 core_->StopAndDeAllocate();
490 } 529 }
491 530
492 } // namespace content 531 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698