After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 797147 - queue deadlocks if it is connected to the second pad of a tee
queue deadlocks if it is connected to the second pad of a tee
Status: RESOLVED NOTABUG
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
1.14.2
Other Linux
: Normal normal
: NONE
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2018-09-14 20:42 UTC by Joel Holdsworth
Modified: 2018-09-17 08:49 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
C demo application (2.72 KB, application/x-xz)
2018-09-14 20:42 UTC, Joel Holdsworth
Details

Description Joel Holdsworth 2018-09-14 20:42:29 UTC
Created attachment 373662 [details]
C demo application

A pipeline is created with the following structure...                 
                                                             
                 +-----------------------------------------+                  
                 |               bin                       |                  
                 |                                         |                  
                 |                      -> ghost_for_queue | -> queue -> fakesink
 videotestsrc -> | sink_ghost -> tee                       |                  
                 |                   -> ghost_for_fakesink | -> fakesink      
                 |                                         |                  
                 +-----------------------------------------+                  

If the queue branch is connected to the first tee request pad, the pipeline will work correctly. If the queue branch is connected to the second tee request pad, the pipeline will deadlock.

This works:

 $ gst-launch-1.0 videotestsrc ! \( tee name="T" \) T. ! queue ! fakesink num-buffers=1 T. ! fakesink num-buffers=1

This deadlocks:

 $ gst-launch-1.0 videotestsrc ! \( tee name="T" \) T. ! fakesink num-buffers=1 T. ! queue ! fakesink num-buffers=1

I've also attached the source for a test application which assembles the same pipeline.
Comment 1 Joel Holdsworth 2018-09-14 20:43:58 UTC
The issue occurs even without the bin and ghost pads...

$ gst-launch-1.0 videotestsrc ! tee name="T" T. ! fakesink num-buffers=1 T. ! queue ! fakesink num-buffers=1
Comment 2 Tim-Philipp Müller 2018-09-14 21:18:18 UTC
This is expected behaviour and not a bug, and it is not the queue that deadlocks.

You need a queue after a tee for each downstream branch. (The fact that it works with only one queue is basically coincidence and assumes the pads will always be iterated in that order.)

The reason it deadlocks if you go straight from tee to fakesink for the first pad is because that's the way GStreamer's preroll mechanism works.

tee will push buffers on each pad from the upstream streaming thread. When it pushes directly to fakesink, fakesink will say "oh good, I'm prerolled now" and block the streaming thread until the pipeline goes to PLAYING state.

Now that streaming thread is blocked/stuck in the fakesink, it can't continue to push buffers to the second fakesink, but the pipeline is waiting for the second fakesink to preroll (get a buffer), and it will wait forever, unless you set async=false on the second fakesink.

This is basically a pipeline construction bug :)