GNOME Bugzilla – Bug 587896
"No stream given yet" error from giostreamsrc
Last modified: 2009-07-09 01:30:25 UTC
Please describe the problem: I am trying to move an application from giosrc to giostreamsrc. However, I have not been able to get my giostreamsrc pipeline to work. Everything worked fine when I was using giosrc with a URI. When I run the application with the GST_DEBUG environment variable set, I see the error "No stream given yet." This happens as the application tries to change the pipeline's state to playing. The strange thing is that I added a check right before the state change that reads the stream property from the giostreamsrc element using g_object_get and confirms that it is a G_IS_INPUT_STREAM. The check does not complain. However, something sets the stream back to NULL after I call gst_element_set_state (see "FIRST CHECK" and "SECOND CHECK" below). I've run my application through valgrind and did not see any memory issues, though I have not yet ruled that out entirely. Steps to reproduce: Actual results: Expected results: Does this happen every time? Other information: See also http://sourceforge.net/mailarchive/forum.php?thread_name=C5BEEF96-5ABB-4207-A14F-7ECCAD619E89%40flyn.org&forum_name=gstreamer-devel. My code follows: GInputStream* g_gst_mp3_input_stream_new (GInputStream *src_stream) { GstStateChangeReturn sret; GstState state; GGstMP3InputStream *stream; stream = G_GST_MP3_INPUT_STREAM (g_object_new (TYPE_G_GST_MP3_INPUT_STREAM, NULL)); stream->priv->pipeline = gst_pipeline_new ("pipeline"); stream->priv->src = gst_element_factory_make ("giostreamsrc", "src"); stream->priv->decode = gst_element_factory_make ("decodebin", "decode"); stream->priv->convert = gst_element_factory_make ("audioconvert", "convert"); stream->priv->encode = gst_element_factory_make ("lame", "encode"); stream->priv->sink = gst_element_factory_make ("appsink", "sink"); gst_bin_add_many (GST_BIN (stream->priv->pipeline), stream->priv->src, stream->priv->decode, stream->priv->convert, stream->priv->encode, stream->priv->sink, NULL); if (gst_element_link (stream->priv->src, stream->priv- decode) == FALSE) { g_warning ("Error linking source and decode elements"); } g_assert (G_IS_INPUT_STREAM (src_stream)); g_object_set (G_OBJECT (stream->priv->src), "stream", src_stream, NULL); /* quality=9 is important for fast, realtime transcoding: */ g_object_set (G_OBJECT (stream->priv->encode), "quality", 9, NULL); g_object_set (G_OBJECT (stream->priv->encode), "bitrate", 128, NULL); g_object_set (G_OBJECT (stream->priv->encode), "vbr", 0, NULL); g_signal_connect (stream->priv->decode, "new-decoded-pad", G_CALLBACK (new_decoded_pad_cb), stream); g_object_set (G_OBJECT (stream->priv->sink), "emit-signals", TRUE, "sync", FALSE, NULL); gst_app_sink_set_max_buffers (GST_APP_SINK (stream->priv- sink), GST_APP_MAX_BUFFERS); gst_app_sink_set_drop (GST_APP_SINK (stream->priv->sink), FALSE); g_signal_connect (stream->priv->sink, "new-buffer", G_CALLBACK (g_gst_input_stream_new_buffer_cb), stream); /* MY FIRST CHECK: NO PROBLEM: */ gpointer foo; g_warning ("CHECK 1"); g_object_get (G_OBJECT (stream->priv->src), "stream", &foo, NULL); g_assert (G_IS_INPUT_STREAM (foo)); g_assert (src_stream == foo); sret = gst_element_set_state (stream->priv->pipeline, GST_STATE_PLAYING); if (GST_STATE_CHANGE_ASYNC == sret) { if (GST_STATE_CHANGE_SUCCESS != gst_element_get_state (GST_ELEMENT (stream->priv->pipeline), &state, NULL, 5 * GST_SECOND)) { g_warning ("State change failed for stream."); } } else if (sret != GST_STATE_CHANGE_SUCCESS) { g_warning ("Could not read stream."); } /* MY SECOND CHECK: FAILS, FOO == NULL! */ g_warning ("CHECK 2"); g_object_get (G_OBJECT (stream->priv->src), "stream", &foo, NULL); g_warning ("NULL == foo %d", NULL == foo); g_assert (G_IS_INPUT_STREAM (src_stream)); g_assert (G_IS_INPUT_STREAM (foo)); g_assert (src_stream == foo); g_assert (G_IS_SEEKABLE (stream)); return G_INPUT_STREAM (stream); }
This might be fixed by commit 160b70e8418b23730da94919e82ffd44dcab2cd7 Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Tue Jul 7 20:18:00 2009 +0200 gio: General clean up and simplification The GInputStreams are now requested by a vfunc from the subclasses instead of relying that the subclass sets it until it's needed. This might also fix bug #587896. Can you confirm? If it isn't fixed by that commit, could you attach compilable sample code that shows the problem?
Also note that tests/check/pipelines/gio.c has some code that runs a pipeline on GMemoryInputStream and GMemoryOutputStream and that it works ;)
I did see tests/check/pipelines/gio.c. I installed libgstgio.so from git master. You definitely fixed something, but I still have a problem. The symptoms are different. Now I get this (same code as above): 0:00:22.525218017 29425 0x8a93ba8 WARN gio_base_src gstgiobasesrc.c:197:gst_gio_base_src_get_size:<src> size information retrieval failed: Stream is already closed 0:00:22.526253065 29425 0x8a93ba8 WARN gio_base_src gstgiobasesrc.c:220:gst_gio_base_src_get_size:<src> Seeking to end of stream failed: Stream is already closed 0:00:22.528615656 29425 0x8a93ba8 WARN GST_SCHEDULING gstpad.c:4275:gst_pad_get_range:<src:src> getrange failed unexpected [...] But, I added a test. g_input_stream_is_closed () returns FALSE before the call to gst_element_set_state () and TRUE after. So, it seems something in the state transition is closing the stream. I did a quick modification of tests/check/pipelines/gio.c to test GFileInputStream (instead of GMemoryInputStream). This test worked fine. So, now I am back to looking at my code. The only thing I see that is blatantly different than gio.c is that I don't set up a message handler using gst_bus_add_watch ().
Could you get a debug log with GST_DEBUG=basesrc:5,gio*:5 ? Also it would really help if you could create a small sample application that reproduces this behaviour. The problem seems to be now that for some reason basesrc::stop() is called after basesrc::start() and then basesrc::start() is called again. The stop() will close the stream... it might make sense to not close the stream automatically in the case of giostream{src,sink} though.
Ok, this should be fixed now :) commit 1c0123cf5889c1ba3560ccf67a619f4d44bcba6e Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Wed Jul 8 17:19:29 2009 +0200 gio: Don't close the GIO streams for the giostream{src,sink} elements This makes it possible to do something useful with the streams after the element has stopped. Fixes bug #587896.
Seems fixed. I am still having trouble with my application, but don't think it is this bug anymore (both committed changes in the comments above seem to have their intended affects). I will open a new bug or reopen this bug if necessary after some more testing with my applications.