GNOME Bugzilla – Bug 749676
playbin: failed to get end-of-stream event when visualization flag is enabled
Last modified: 2015-06-12 16:44:49 UTC
If visualization flags is enabled then pipeline failed to exit cleanly. Below pipeline failed to reach EOS: gst-launch-1.0 playbin uri=file:///home/brijesh/gst-player/tests/media/audio-short.ogg flags=audio+vis
Did git bisect and found that the below commit is causing this issue. commit 9f81931716b7f8fd29862f0bfa1a3891cb414bdc Author: Song Bing <b06498@freescale.com> Date: Mon Jan 12 16:08:33 2015 +0800 streamsynchronizer: Send GAP event to finish preroll when change state from PLAYING to PAUSED Wait in the event function when EOS is received until all pads are EOS and then forward the EOS event from each pads own event function. Also send a new GAP event for EOS pads from the event function whenever going from PLAYING->PAUSED by shortly waking up the GCond. This is needed to allow sinks to pre-roll again, as they did not receive EOS yet because we blocked that, but also will never get data again. https://bugzilla.gnome.org/show_bug.cgi?id=736655
Looks like a queue is missing. Audiotee pushes EOS into streamsynchronizer and then it blocks waiting for EOS on other pads. As there is no queue before streamsynchronizer it locks up the pipeline as audiotee will never push the EOS on the visualizer branch.
Yeah, I think there's also a comment about this in playsink's code somewhere. The above commit probably should've come together with adding queues :)
Indeed. Quickly added a queue here and it fixed the problem. Will work on the proper patch and attach it here.
Created attachment 303999 [details] [review] playsink: use queue to avoid lock in audiotee audio branches This part of pipeline is: tee name=t ! visualizationbin ! streamsynchronizer name=s t. ! s. streamsynchronizer might block and it could starve the visualization branch of the pipeline when it is enabled. The visualization bin has queues internally but the other branch that links the audiotee directly to the synchronizer is vulnerable to block. Adding a queue between "t. ! s." fixes deadlocks.
I tried the patch and it works well in both gst-launch as well as gst-player lib.
Comment on attachment 303999 [details] [review] playsink: use queue to avoid lock in audiotee audio branches Does this only add the queue if vis is enabled? If so, please push, looks good :)
(In reply to Sebastian Dröge (slomo) from comment #7) > Comment on attachment 303999 [details] [review] [review] > playsink: use queue to avoid lock in audiotee audio branches > > Does this only add the queue if vis is enabled? If so, please push, looks > good :) It is always adding the queue, I'll update and push. From the code it seems vis can't be enabled/disabled during playback so it should be simple.
Vis can be enabled/disabled during playback IIRC. That will trigger the reconfigure thing inside playsink then.
Ah, that is done called from playbin and not internally from playsink. Will check that.
Thanks for the review, patch pushed commit 12ac087807232df52392bfb21cdff7f89c393606 Author: Thiago Santos <thiagoss@osg.samsung.com> Date: Tue May 26 08:06:50 2015 -0300 playsink: use queue to avoid lock in audiotee audio branches This part of pipeline is: tee name=t ! visualizationbin ! streamsynchronizer name=s t. ! s. streamsynchronizer might block and it could starve the visualization branch of the pipeline when it is enabled. The visualization bin has queues internally but the other branch that links the audiotee directly to the synchronizer is vulnerable to block. Adding a queue between "t. ! s." fixes deadlocks. https://bugzilla.gnome.org/show_bug.cgi?id=749676
I have tried looping a short audio file with vis enabled and after 10 min of loop (~ 250+ iteration) i get the following messages on the console (gtk-play:25751): GStreamer-CRITICAL **: gst_poll_write_control: assertion 'set != NULL' failed The looping is still working. If i disable the vis then i do not see this message. It seems like this patch fixed the main issue but exposed something else .. I am using gst-player lib https://github.com/sdroege/gst-player to reproduce the problems.
You can reproduce the issue with minor modification in gst-play-1.0. I just hacked gst-play to add loop and enable vis. See the code below. The test audio file is available here: https://github.com/sdroege/gst-player/blob/master/tests/media/audio-short.ogg brijesh@brijesh-M11BB:~/gst-plugins-base/tools$ git diff . diff --git a/tools/gst-play.c b/tools/gst-play.c index f2b8ad6..c1a6275 100644 --- a/tools/gst-play.c +++ b/tools/gst-play.c @@ -131,6 +131,7 @@ play_new (gchar ** uris, const gchar * audio_sink, const gchar * video_sink, { GstElement *sink; GstPlay *play; + guint flags; play = g_new0 (GstPlay, 1); @@ -163,6 +164,10 @@ play_new (gchar ** uris, const gchar * audio_sink, const gchar * video_sink, g_warning ("Couldn't create specified video sink '%s'", video_sink); } + g_object_get (play->playbin, "flags", &flags, NULL); + flags |= 0x8; + g_object_set (play->playbin, "flags", flags, NULL); + play->loop = g_main_loop_new (NULL, FALSE); play->bus_watch = gst_bus_add_watch (GST_ELEMENT_BUS (play->playbin), @@ -533,7 +538,8 @@ static gboolean play_next (GstPlay * play) { if ((play->cur_idx + 1) >= play->num_uris) - return FALSE; + play->cur_idx = -1; +// return FALSE; play_uri (play, play->uris[++play->cur_idx]); return TRUE;
I had that running for about 5 minutes without problems, it also didn't look like any bigger amount of memory is leaked. Can you run in a debugger and get a backtrace? If you set G_DEBUG=fatal_warnings in the environment, the debugger will stop on the critical warning.
Sometime it just takes a bit longer to see it, I am using Ubuntu 15.04 with latest gstreamer code from git tree. Here is backtrack generate from the corefile. ---------------- [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `gst-play-1.0 gst-player/tests/media/audio-short.ogg'. Program terminated with signal SIGTRAP, Trace/breakpoint trap.
+ Trace 235112
That seems like we're running out of fds at some point, there must be an fd leak somewhere. Maybe a buffer pool.
I let it running here for 1h (8805 iterations) and it didn't crash. Is there anything particular with your setup? I'm using latest git master, no hardware decoders and the default video sink is xvimagesink. Debian sid.
That is interesting. I just updated to latest gstreamer, gst-plugins-good and gst-plugins-base and still able to reproduce it. I am using Ubuntu 15.04 with all latest updates etc. I will try to follow Sebastian's recommendation and run lsof in background to see if i see any fd leaks
Run a few iterations in valgrind and let it exit then, IIRC valgrind can also tell you about fd leaks.
I have tried with latest gstreamer release 1.5.1 and no longer able to reproduce this. We can close this bug.
Do you know what changed as you had tested with git? 1.5.1 shouldn't be much different from git of a couple days ago.
I think the main difference was, in past i was updating gst-plugin-base git but was still using somewhat a older version of gstreamer and gst-plugins-good. And this time i did git pull on all (gstreamer, gst-plugins-base and gst-plugins-good) and now do not see this issue anymore.
Ok, let's mark this as fixed again. Thanks for confirming.