summaryrefslogtreecommitdiffstats
path: root/media/test
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-27 00:38:48 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-27 00:38:48 +0000
commit058c690354c76956c56cd979458ba2d399fe0edd (patch)
tree2c1f24d1a2ecb47517f64472de90a60b984d85f7 /media/test
parent278f5eb9398015ca9f021e1daa78263ef631b2dc (diff)
downloadchromium_src-058c690354c76956c56cd979458ba2d399fe0edd.zip
chromium_src-058c690354c76956c56cd979458ba2d399fe0edd.tar.gz
chromium_src-058c690354c76956c56cd979458ba2d399fe0edd.tar.bz2
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 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190807 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/test')
-rw-r--r--media/test/data/rapid_video_change_test.html47
1 files changed, 47 insertions, 0 deletions
diff --git a/media/test/data/rapid_video_change_test.html b/media/test/data/rapid_video_change_test.html
new file mode 100644
index 0000000..81a853b
--- /dev/null
+++ b/media/test/data/rapid_video_change_test.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>HTML 5 Change H.264 Video Test</title>
+ <script>
+ var changeVideoInterval;
+ var changeVideoCounter = 0;
+
+ function changeVideo() {
+ try {
+ if (changeVideoCounter == 40) {
+ alert('40 video changes done. Test over');
+ window.clearInterval(changeVideoInterval);
+ return;
+ }
+ var video = document.getElementById('video');
+ video.pause();
+ video.src = 'bear-1280x720.mp4?counter=' +
+ changeVideoCounter.toString();
+ ++changeVideoCounter;
+ video.play();
+ video.currentTime = 1;
+ }
+
+ catch (e) {
+ }
+ }
+
+ function onLoad() {
+ var video = document.getElementById('video');
+ video.play();
+ video.currentTime = 1;
+ changeVideoInterval = setInterval(changeVideo, 200);
+ }
+ </script>
+ </head>
+
+ <body onload='onLoad();'> <b> This test tests the case where in H.264 H/W
+ decoded videos are added and removed a number of times from the page,
+ while they are playing. <br> This should not cause the browser to hang.
+ <div id='videoDiv'>
+ <video id='video' width=320 height=240 src='bear-1280x720.mp4'
+ controls='controls'>
+ </video>
+ </div>
+ </body>
+</html>