GNOME Bugzilla – Bug 726020
avdec_h265: freezes when max-threads != 1
Last modified: 2015-06-05 10:00:44 UTC
The decoder freezes for the h265 codec freezes when the max-threads property is not 1. This can be reproduced with the following pipelines. non-working pipeline: gst-launch-1.0 filesrc location=videotestsrc.265 ! h265parse ! avdec_h265 ! fakesink working pipeline: gst-launch-1.0 filesrc location=videotestsrc.265 ! h265parse ! avdec_h265 max-threads=1 ! fakesink
Created attachment 271403 [details] H265 test sequence
The relevant threads:
+ Trace 233312
Thread 4 (Thread 0x7ffff2b9f700 (LWP 18830))
Video decoder handle_frame is called with the STREAM_LOCK while libav is calling get_buffer that also needs the STREAM_LOCK
So we should release the stream lock while calling avcodec_decode_video2(). Very similar to what we do in androidmedia or gst-omx. Just needs checking after we get the lock again if anything relevant has changed.
(In reply to comment #3) > So we should release the stream lock while calling avcodec_decode_video2(). > Very similar to what we do in androidmedia or gst-omx. > > Just needs checking after we get the lock again if anything relevant has > changed. It seems all of the public API of videodecoder uses the stream lock, isn't it better than to solve this at videodecoder itself?
(In reply to comment #4) > (In reply to comment #3) > > So we should release the stream lock while calling avcodec_decode_video2(). > > Very similar to what we do in androidmedia or gst-omx. > > > > Just needs checking after we get the lock again if anything relevant has > > changed. > > It seems all of the public API of videodecoder uses the stream lock, isn't it > better than to solve this at videodecoder itself? Yes, and this lock currently prevent buffers to come in while pushing. I had in mind that the solution would be to reduce the scope of this lock, and protect the internal list of the decoder with object lock. Though it seemed tricky due to backward compatibility requirement.
(In reply to comment #4) > (In reply to comment #3) > > So we should release the stream lock while calling avcodec_decode_video2(). > > Very similar to what we do in androidmedia or gst-omx. > > > > Just needs checking after we get the lock again if anything relevant has > > changed. > > It seems all of the public API of videodecoder uses the stream lock, isn't it > better than to solve this at videodecoder itself? All the videodecoder code that runs from the streaming thread takes this lock, yes... but you have to unlock it yourself if you do a blocking operation in the streaming thread, and this causes another thread to call into your code and taking the stream lock. Exactly the situation you have here :) Also all Nicolas said is true too, I started looking into it but it seems rather annoying to fix this in the base class now.
Note that also thread_safe_callbacks is not set on the libav context. This causes the streaming thread to wait on the (libav) decoding thread. It should be safe to set the thread_safe_callbacks to true and not block. However for frame based threading libav will then block in the streaming thread till the previous frame is decoded, so there is only little gain.
FWIW a related bug: https://bugzilla.gnome.org/show_bug.cgi?id=715192
*** Bug 750400 has been marked as a duplicate of this bug. ***
This fixes it, nonetheless we should look into improving the situation at the videodecoder level too. That's bug #715192, but it wouldn't have helped in this specific case. commit b81cb99d9fea5dbe0c1d74008186ef328c7f1a13 Author: Sebastian Dröge <sebastian@centricular.com> Date: Fri Jun 5 11:57:37 2015 +0200 avviddec: Release stream lock while calling avcodec_decode_video2() It might call back into us from another thread and try to take the stream lock again, e.g. to allocate a buffer. https://bugzilla.gnome.org/show_bug.cgi?id=726020