GNOME Bugzilla – Bug 755235
gst_element_get_state *always* times out when called from a non-main thread.
Last modified: 2015-09-25 14:25:27 UTC
Created attachment 311648 [details] debug capture with --gst-debug=VAAL:6,GST_STATES:6 I have a video-wall application that allows a user to add and delete entire rows and columns of monitor outputs while its playing a video. To add a bunch of monitors at once, I'm using glib's thread pool functions and spawning a number of threads, each of which builds a "videostream" bin for a single monitor and attaches it to a 'tee' element inside a central 'videostub' bin which distributes whichever visual media we're currently playing. The process is simple: 1) Place the new videostream bin inside the videostub bin. 2) Ask the videostream to sync state with the videostub 3) Wait for a result (successful sync, or failure) and report that to the main pipeline manager of the program. 4) If successful, attach the videostream to the tee at the end of the videostub. The problem I have is that, if the videostub is in playing state, then the wait for result in step 3 ALWAYS times out, no matter how long. The moment the main loop runs again, the state transition completes. If I do a full debug dump with --gst-debug=*:6, then I see that NOTHING is happening during the timeout period. No messages get logged at all. I'm attaching a debug output from my program that shows just the log output from my main program and the GST_STATES logging while it attempts to sync the videostream with the videostub.
Do you have a test program for us to reproduce this with? Have you tried if this still happens with git master / 1.5.91?
I will see if I can test my program under git master on Monday. If it still persists, I'll try to make a minimal program to demonstrate.
Its taken a day and a half to upgrade all the necessary components to run the tests, but I can confirm that the problem persists in the latest git master (v1.5.91). I'm going to try to chop my program down to a minimal reproducible bit. It may take a while...
Thanks, much appreciated.
Created attachment 312077 [details] Program to demonstrate the bug. Compile this example program with: gcc $(pkg-config --cflags --libs gstreamer-1.0) -o bug755235 bug755235.c If run without arguments, it skips the waiting for an async change, to prove that that works. If run with arguments, it waits for a state sync (the use case I have) and always times out.
It can't finish the state change while you're waiting there because you didn't link in the tee before waiting for the state change. As such, the sink was waiting forever to get its first buffer (it would only then finish the async state change). If you move the linking before the get_state() call, it works.
Thanks. For some reason I thought that condition was signalled by a return value of GST_STATE_CHANGE_NO_PREROLL, but re-reading the docs, I see it has just the opposite meaning. I'm tempted to suggest adding a return code of GST_STATE_CHANGE_PREROLL, for this case, but its not clear that would help anyone else but me...