Index: content/browser/renderer_host/media/web_contents_video_capture_device.cc |
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device.cc b/content/browser/renderer_host/media/web_contents_video_capture_device.cc |
index 0240f8b4498a54e2028611ad07cf54b06fef2e83..58fc2908eeb8cd5cd6e6dc843cf156c4ae507054 100644 |
--- a/content/browser/renderer_host/media/web_contents_video_capture_device.cc |
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device.cc |
@@ -152,6 +152,8 @@ class BackingStoreCopier : public WebContentsObserver { |
BackingStoreCopier(int render_process_id, int render_view_id); |
+ virtual ~BackingStoreCopier(); |
+ |
// If non-NULL, use the given |override| to access the backing store. |
// This is used for unit testing. |
void SetRenderWidgetHostForTesting(RenderWidgetHost* override); |
@@ -163,6 +165,11 @@ class BackingStoreCopier : public WebContentsObserver { |
void StartCopy(int frame_number, int desired_width, int desired_height, |
const DoneCB& done_cb); |
+ // Stops observing an existing WebContents instance, if any. This must be |
+ // called before BackingStoreCopier is destroyed. Must be run on the UI |
+ // BrowserThread. |
+ void StopObservingWebContents(); |
+ |
virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
fullscreen_widget_id_ = routing_id; |
@@ -175,6 +182,8 @@ class BackingStoreCopier : public WebContentsObserver { |
} |
private: |
+ virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; |
+ |
void LookUpAndObserveWebContents(); |
void CopyFromBackingStoreComplete(int frame_number, |
@@ -290,6 +299,25 @@ BackingStoreCopier::BackingStoreCopier(int render_process_id, |
: render_process_id_(render_process_id), render_view_id_(render_view_id), |
fullscreen_widget_id_(MSG_ROUTING_NONE), rwh_for_testing_(NULL) {} |
+BackingStoreCopier::~BackingStoreCopier() { |
+ DCHECK(!web_contents()); |
+} |
+ |
+void BackingStoreCopier::StopObservingWebContents() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ if (web_contents()) { |
+ web_contents()->SetCapturingContents(false); |
+ Observe(NULL); |
+ } |
+} |
+ |
+void BackingStoreCopier::WebContentsDestroyed(WebContents* web_contents) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ web_contents->SetCapturingContents(false); |
+} |
+ |
void BackingStoreCopier::LookUpAndObserveWebContents() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
@@ -309,8 +337,10 @@ void BackingStoreCopier::LookUpAndObserveWebContents() { |
<< render_process_id_ << ", " << render_view_id_ |
<< ") returned NULL."; |
Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL); |
- DVLOG_IF(1, !web_contents()) |
- << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL."; |
+ if (web_contents()) |
+ web_contents()->SetCapturingContents(true); |
+ else |
+ DVLOG(1) << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL."; |
if (fullscreen_widget_id_ == MSG_ROUTING_NONE && web_contents()) { |
fullscreen_widget_id_ = static_cast<WebContentsImpl*>(web_contents())-> |
@@ -721,6 +751,8 @@ class CaptureMachine |
const SkBitmap* frame_buffer); |
void DeliverComplete(const SkBitmap* frame_buffer); |
+ void DoShutdownTasksOnUIThread(); |
+ |
// Specialized RefCounted traits for CaptureMachine, so that operator delete |
// is called from an "outside" thread. See comments for "traits" in |
// base/memory/ref_counted.h. |
@@ -847,6 +879,10 @@ void CaptureMachine::DeAllocate() { |
Stop(); |
} |
if (state_ == kAllocated) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&CaptureMachine::DoShutdownTasksOnUIThread, this)); |
justinlin
2013/02/04 22:16:03
Drive-by: Hmm, couldn't this class get deleted bef
miu
2013/02/04 22:26:25
Nope. CaptureMachine is ref-counted, so the Bind(
|
+ |
TransitionStateTo(kIdle); |
} |
} |
@@ -1027,6 +1063,10 @@ void CaptureMachine::DeliverComplete(const SkBitmap* frame_buffer) { |
renderer_.Release(frame_buffer); |
} |
+void CaptureMachine::DoShutdownTasksOnUIThread() { |
+ copier_.StopObservingWebContents(); |
+} |
+ |
WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice( |
const media::VideoCaptureDevice::Name& name, |
int render_process_id, int render_view_id) |