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

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

Issue 12026029: Allow TabCapture to capture full screen flash widgets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nit Created 7 years, 11 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
« no previous file with comments | « no previous file | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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. Therefore, the process of capturing has been split up into a 7 // performance. Therefore, the process of capturing has been split up into a
8 // pipeline of three stages. Each stage executes on its own thread: 8 // pipeline of three stages. Each stage executes on its own thread:
9 // 9 //
10 // 1. Capture: A bitmap is snapshotted/copied from the RenderView's backing 10 // 1. Capture: A bitmap is snapshotted/copied from the RenderView's backing
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 #include "base/callback_forward.h" 49 #include "base/callback_forward.h"
50 #include "base/debug/trace_event.h" 50 #include "base/debug/trace_event.h"
51 #include "base/logging.h" 51 #include "base/logging.h"
52 #include "base/memory/scoped_ptr.h" 52 #include "base/memory/scoped_ptr.h"
53 #include "base/metrics/histogram.h" 53 #include "base/metrics/histogram.h"
54 #include "base/stringprintf.h" 54 #include "base/stringprintf.h"
55 #include "base/synchronization/lock.h" 55 #include "base/synchronization/lock.h"
56 #include "base/threading/thread.h" 56 #include "base/threading/thread.h"
57 #include "base/time.h" 57 #include "base/time.h"
58 #include "content/browser/renderer_host/media/web_contents_capture_util.h" 58 #include "content/browser/renderer_host/media/web_contents_capture_util.h"
59 #include "content/browser/web_contents/web_contents_impl.h"
59 #include "content/public/browser/browser_thread.h" 60 #include "content/public/browser/browser_thread.h"
60 #include "content/public/browser/render_process_host.h" 61 #include "content/public/browser/render_process_host.h"
61 #include "content/public/browser/render_view_host.h" 62 #include "content/public/browser/render_view_host.h"
62 #include "content/public/browser/render_widget_host_view.h" 63 #include "content/public/browser/render_widget_host_view.h"
63 #include "content/public/browser/web_contents.h" 64 #include "content/public/browser/web_contents.h"
64 #include "content/public/browser/web_contents_observer.h" 65 #include "content/public/browser/web_contents_observer.h"
65 #include "media/base/bind_to_loop.h" 66 #include "media/base/bind_to_loop.h"
66 #include "media/video/capture/video_capture_types.h" 67 #include "media/video/capture/video_capture_types.h"
67 #include "skia/ext/image_operations.h" 68 #include "skia/ext/image_operations.h"
68 #include "skia/ext/platform_canvas.h" 69 #include "skia/ext/platform_canvas.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 // This is used for unit testing. 156 // This is used for unit testing.
156 void SetRenderWidgetHostForTesting(RenderWidgetHost* override); 157 void SetRenderWidgetHostForTesting(RenderWidgetHost* override);
157 158
158 // Starts the copy from the backing store. Must be run on the UI 159 // Starts the copy from the backing store. Must be run on the UI
159 // BrowserThread. |done_cb| is invoked with result status. When successful 160 // BrowserThread. |done_cb| is invoked with result status. When successful
160 // (OK), the bitmap of the capture is transferred to the callback along with 161 // (OK), the bitmap of the capture is transferred to the callback along with
161 // the timestamp at which the capture was completed. 162 // the timestamp at which the capture was completed.
162 void StartCopy(int frame_number, int desired_width, int desired_height, 163 void StartCopy(int frame_number, int desired_width, int desired_height,
163 const DoneCB& done_cb); 164 const DoneCB& done_cb);
164 165
166 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168 fullscreen_widget_id_ = routing_id;
169 }
170
171 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
173 DCHECK_EQ(fullscreen_widget_id_, routing_id);
174 fullscreen_widget_id_ = MSG_ROUTING_NONE;
175 }
176
165 private: 177 private:
166 void LookUpAndObserveWebContents(); 178 void LookUpAndObserveWebContents();
167 179
168 void CopyFromBackingStoreComplete(int frame_number, 180 void CopyFromBackingStoreComplete(int frame_number,
169 scoped_ptr<skia::PlatformBitmap> capture, 181 scoped_ptr<skia::PlatformBitmap> capture,
170 const DoneCB& done_cb, bool success); 182 const DoneCB& done_cb, bool success);
171 183
172 // The "starting point" to find the capture source. 184 // The "starting point" to find the capture source.
173 const int render_process_id_; 185 const int render_process_id_;
174 const int render_view_id_; 186 const int render_view_id_;
175 187
188 // Routing ID of any active fullscreen render widget or MSG_ROUTING_NONE
189 // otherwise.
190 int fullscreen_widget_id_;
191
176 // Last known RenderView size. 192 // Last known RenderView size.
177 gfx::Size last_view_size_; 193 gfx::Size last_view_size_;
178 194
179 // If the following is NULL (normal behavior), the implementation should 195 // If the following is NULL (normal behavior), the implementation should
180 // access RenderWidgetHost via web_contents(). 196 // access RenderWidgetHost via web_contents().
181 RenderWidgetHost* rwh_for_testing_; 197 RenderWidgetHost* rwh_for_testing_;
182 198
183 DISALLOW_COPY_AND_ASSIGN(BackingStoreCopier); 199 DISALLOW_COPY_AND_ASSIGN(BackingStoreCopier);
184 }; 200 };
185 201
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 base::Time last_frame_rate_log_time_; 281 base::Time last_frame_rate_log_time_;
266 int count_frames_rendered_; 282 int count_frames_rendered_;
267 int last_frame_number_; 283 int last_frame_number_;
268 284
269 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliverer); 285 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliverer);
270 }; 286 };
271 287
272 BackingStoreCopier::BackingStoreCopier(int render_process_id, 288 BackingStoreCopier::BackingStoreCopier(int render_process_id,
273 int render_view_id) 289 int render_view_id)
274 : render_process_id_(render_process_id), render_view_id_(render_view_id), 290 : render_process_id_(render_process_id), render_view_id_(render_view_id),
275 rwh_for_testing_(NULL) {} 291 fullscreen_widget_id_(MSG_ROUTING_NONE), rwh_for_testing_(NULL) {}
276 292
277 void BackingStoreCopier::LookUpAndObserveWebContents() { 293 void BackingStoreCopier::LookUpAndObserveWebContents() {
278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
279 295
280 // Look-up the RenderViewHost and, from that, the WebContents that wraps it. 296 // Look-up the RenderViewHost and, from that, the WebContents that wraps it.
281 // If successful, begin observing the WebContents instance. If unsuccessful, 297 // If successful, begin observing the WebContents instance. If unsuccessful,
282 // stop observing and post an error. 298 // stop observing and post an error.
283 // 299 //
284 // Why this can be unsuccessful: The request for mirroring originates in a 300 // Why this can be unsuccessful: The request for mirroring originates in a
285 // render process, and this request is based on the current RenderView 301 // render process, and this request is based on the current RenderView
286 // associated with a tab. However, by the time we get up-and-running here, 302 // associated with a tab. However, by the time we get up-and-running here,
287 // there have been multiple back-and-forth IPCs between processes, as well as 303 // there have been multiple back-and-forth IPCs between processes, as well as
288 // a bit of indirection across threads. It's easily possible that, in the 304 // a bit of indirection across threads. It's easily possible that, in the
289 // meantime, the original RenderView may have gone away. 305 // meantime, the original RenderView may have gone away.
290 RenderViewHost* const rvh = 306 RenderViewHost* const rvh =
291 RenderViewHost::FromID(render_process_id_, render_view_id_); 307 RenderViewHost::FromID(render_process_id_, render_view_id_);
292 DVLOG_IF(1, !rvh) << "RenderViewHost::FromID(" 308 DVLOG_IF(1, !rvh) << "RenderViewHost::FromID("
293 << render_process_id_ << ", " << render_view_id_ 309 << render_process_id_ << ", " << render_view_id_
294 << ") returned NULL."; 310 << ") returned NULL.";
295 Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL); 311 Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
296 DVLOG_IF(1, !web_contents()) 312 DVLOG_IF(1, !web_contents())
297 << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL."; 313 << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL.";
314
315 if (fullscreen_widget_id_ == MSG_ROUTING_NONE && web_contents()) {
316 fullscreen_widget_id_ = static_cast<WebContentsImpl*>(web_contents())->
317 GetFullscreenWidgetRoutingID();
318 }
298 } 319 }
299 320
300 void BackingStoreCopier::SetRenderWidgetHostForTesting( 321 void BackingStoreCopier::SetRenderWidgetHostForTesting(
301 RenderWidgetHost* override) { 322 RenderWidgetHost* override) {
302 rwh_for_testing_ = override; 323 rwh_for_testing_ = override;
303 } 324 }
304 325
305 void BackingStoreCopier::StartCopy(int frame_number, 326 void BackingStoreCopier::StartCopy(int frame_number,
306 int desired_width, int desired_height, 327 int desired_width, int desired_height,
307 const DoneCB& done_cb) { 328 const DoneCB& done_cb) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309 330
310 TRACE_EVENT_ASYNC_BEGIN1("mirroring", "Capture", this, 331 TRACE_EVENT_ASYNC_BEGIN1("mirroring", "Capture", this,
311 "frame_number", frame_number); 332 "frame_number", frame_number);
312 333
313 RenderWidgetHost* rwh; 334 RenderWidgetHost* rwh;
314 if (rwh_for_testing_) { 335 if (rwh_for_testing_) {
315 rwh = rwh_for_testing_; 336 rwh = rwh_for_testing_;
316 } else { 337 } else {
317 if (!web_contents()) { // No source yet. 338 if (!web_contents()) { // No source yet.
318 LookUpAndObserveWebContents(); 339 LookUpAndObserveWebContents();
319 if (!web_contents()) { // No source ever. 340 if (!web_contents()) { // No source ever.
320 done_cb.Run(NO_SOURCE, 341 done_cb.Run(NO_SOURCE,
321 scoped_ptr<skia::PlatformBitmap>(NULL), base::Time()); 342 scoped_ptr<skia::PlatformBitmap>(NULL), base::Time());
322 return; 343 return;
323 } 344 }
324 } 345 }
325 rwh = web_contents()->GetRenderViewHost(); 346
347 if (fullscreen_widget_id_ != MSG_ROUTING_NONE) {
348 RenderProcessHost* process = web_contents()->GetRenderProcessHost();
349 rwh = process ? process->GetRenderWidgetHostByID(fullscreen_widget_id_)
350 : NULL;
351 } else {
352 rwh = web_contents()->GetRenderViewHost();
353 }
354
326 if (!rwh) { 355 if (!rwh) {
327 // Transient failure state (e.g., a RenderView is being replaced). 356 // Transient failure state (e.g., a RenderView is being replaced).
328 done_cb.Run(TRANSIENT_ERROR, 357 done_cb.Run(TRANSIENT_ERROR,
329 scoped_ptr<skia::PlatformBitmap>(NULL), base::Time()); 358 scoped_ptr<skia::PlatformBitmap>(NULL), base::Time());
330 return; 359 return;
331 } 360 }
332 } 361 }
333 362
334 gfx::Size fitted_size; 363 gfx::Size fitted_size;
335 if (RenderWidgetHostView* const view = rwh->GetView()) { 364 if (RenderWidgetHostView* const view = rwh->GetView()) {
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 capturer_->SetConsumer(NULL); 1095 capturer_->SetConsumer(NULL);
1067 capturer_->DeAllocate(); 1096 capturer_->DeAllocate();
1068 } 1097 }
1069 1098
1070 const media::VideoCaptureDevice::Name& 1099 const media::VideoCaptureDevice::Name&
1071 WebContentsVideoCaptureDevice::device_name() { 1100 WebContentsVideoCaptureDevice::device_name() {
1072 return device_name_; 1101 return device_name_;
1073 } 1102 }
1074 1103
1075 } // namespace content 1104 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698