diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-27 12:20:21 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-27 12:20:21 +0000 |
commit | f8b473471b1d33152e53048c955a96aa7e18df67 (patch) | |
tree | 58782890a1a97cd1c3459b2690a30c24e2dfeb24 /webkit | |
parent | 7961267e99f6c1456c5384215b619bb7814bfc19 (diff) | |
download | chromium_src-f8b473471b1d33152e53048c955a96aa7e18df67.zip chromium_src-f8b473471b1d33152e53048c955a96aa7e18df67.tar.gz chromium_src-f8b473471b1d33152e53048c955a96aa7e18df67.tar.bz2 |
Revert 190863 "Revert 190807 "Fix a Chrome renderer hang which o..."
> Revert 190807 "Fix a Chrome renderer hang which occurs when a We..."
>
> > Fix a Chrome renderer hang which occurs when a WebMediaPlayerImpl instance is shutting down and hangs due to
> > a deadlock between the media pipeline thread and the Renderer main thread.
> >
> > The media pipeline thread waits on a task(RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory) to be
> > executed on the main thread while the main thread waits on the media pipeline thread to exit.
> >
> > The proposed fix is to introduce the following functions on the media::GpuVideoDecoder::Factories interface.
> > 1. Abort:- Called during shutdown.
> > 2. IsAborted:- Called to check if shutdown is in progress.
> >
> > The Abort function is called when the WebMediaPlayerImpl is shutting down. The video decoder factory sets an
> > event in this context. All tasks which complete asynchronously check for this event along with the event
> > which indicates that the async task completed. This ensures that they don't indefinitely wait during shutdown.
> > The asynchronous tasks in the RendererGpuVideoDecoderFactories now use a common event to signal completion
> > and return their results in member variables. This prevents a race between RendererGpuVideoDecoderFactories::Abort
> > being called and these tasks attempting to copy data to the callers stack which may have unwound at this point.
> >
> > While debugging this problem, I also found that there are scenarios where the GVD::Reset never completes
> > thus hanging the renderer. This problem occurs when the GVD is in the kDrainingDecoder state, i.e. waiting
> > for a Flush to complete. The VRB is waiting for the GVD::Reset operation to complete. The VDA is waiting for
> > output picture buffers which the VRB is holding on to. Proposed fix for that was to flush out the ready frames
> > in the VRB::Flush call which unblocks the VDA.
> >
> > I changed the ReadPixelsCB to take in a const SkBitmap& instead of void* to address the refcount issues with the
> > SkBitmap.
> >
> > While running my test case with tip two DCHECK's in VideoFrameStream::OnDecoderStopped fired. The first one
> > is the case where the decoder is stopped while there is a pending read callback. The second one is for the same
> > scenario with a pending reset. These fire when the media pipeline is destroyed on the main renderer thread while
> > these operations are pending. I added code in the GpuVideoDecoder::Stop function to fire these callbacks which
> > seems like the right thing to do.
> >
> > The other change in the GpuVideoDecoder::NotifyResetDone function was to remove the check for a NULL vda as there
> > are scenarios where in the decoder could be destroyed before this callback runs. We need to fire the read and
> > reset callbacks anyway.
> >
> > BUG=179551
> > TEST=The rapid_video_change_test.html file added to media\test\data, when loaded in chrome should hang without
> > this patch. Needs some more work to get something similar running in the Chrome OS autotest suite.
> > Review URL: https://codereview.chromium.org/12634011
>
> TBR=ananta@chromium.org
> Review URL: https://codereview.chromium.org/12942011
TBR=ygorshenin@chromium.org
Review URL: https://codereview.chromium.org/13044009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190912 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/media/webmediaplayer_impl.cc | 6 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.h | 3 |
2 files changed, 9 insertions, 0 deletions
diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc index 0b76985..4008ffc 100644 --- a/webkit/media/webmediaplayer_impl.cc +++ b/webkit/media/webmediaplayer_impl.cc @@ -188,6 +188,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( new media::GpuVideoDecoder( media_thread_.message_loop_proxy(), params.gpu_factories())); + gpu_factories_ = params.gpu_factories(); } // Create default video renderer. @@ -1156,6 +1157,11 @@ void WebMediaPlayerImpl::Destroy() { if (chunk_demuxer_) chunk_demuxer_->Shutdown(); + if (gpu_factories_) { + gpu_factories_->Abort(); + gpu_factories_ = NULL; + } + // Make sure to kill the pipeline so there's no more media threads running. // Note: stopping the pipeline might block for a long time. base::WaitableEvent waiter(false, false); diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h index 3e1799a..68e6f3c 100644 --- a/webkit/media/webmediaplayer_impl.h +++ b/webkit/media/webmediaplayer_impl.h @@ -31,6 +31,7 @@ #include "media/base/audio_renderer_sink.h" #include "media/base/decryptor.h" #include "media/base/pipeline.h" +#include "media/filters/gpu_video_decoder.h" #include "media/filters/skcanvas_video_renderer.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" @@ -359,6 +360,8 @@ class WebMediaPlayerImpl // not NULL while the compositor is actively using this webmediaplayer. cc::VideoFrameProvider::Client* video_frame_provider_client_; + scoped_refptr<media::GpuVideoDecoder::Factories> gpu_factories_; + DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); }; |