GNOME Bugzilla – Bug 740645
race condition in decoder locking
Last modified: 2015-03-06 17:36:03 UTC
Created attachment 291383 [details] [review] vaapidecode: Check the condition after taking the lock In the decoder you have the pattern: while (check condition) { lock; wait; unlock; } You can get into the case wher the condition is changed between checking it and taking the clock, resulting in the GCond never being awoken. Attach patch makes the condition checking function accessible and checks it while holding the lock, preventing the race from hapenning.
adding the attached patch, I still get into a spinlock with the following backtrace:
+ Trace 234368
I should add, it usually happens when there is a lot of frame drops happening, for example when I run 15 mpeg2 hd streams as the following, I usually find 2 one of them getting blocked at the above backtrace. gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink & gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
(In reply to comment #0) > Created an attachment (id=291383) [details] [review] > vaapidecode: Check the condition after taking the lock > > In the decoder you have the pattern: > > while (check condition) { > lock; > wait; > unlock; > } > > You can get into the case wher the condition is changed between checking it and > taking the clock, resulting in the GCond never being awoken. Attach patch makes > the condition checking function accessible and checks it while holding the > lock, preventing the race from hapenning. Sorry for the delay. I didn't reproduce the issue. But what you have explained make sense :) Will push it..
commit fc7e6b19fd8f8b2bf4be2a69099482e051c14f2b Author: Olivier Crete <olivier.crete@collabora.com> Date: Wed Feb 4 18:34:59 2015 +0200 vaapidecode: Check the condition after taking the lock Otherwise the condition could become true before the lock is taken and the g_cond_signal() could be called before the g_cond_wait(), so the g_cond_wait() is never awoken. https://bugzilla.gnome.org/show_bug.cgi?id=740645
(In reply to comment #1) > adding the attached patch, I still get into a spinlock with the following > backtrace: > > Do you still have issues with git master? If so, could you please create another bug for the same?
The vaapidecode has a single thread implementation now. And also there is a new vaapidecodebin element to provide the parallelism. I am closing this now, please reopen if issue persists.