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 538176 - State change trouble with decodebin and empty files
State change trouble with decodebin and empty files
Status: RESOLVED DUPLICATE of bug 505770
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
0.10.18
Other Linux
: Normal normal
: NONE
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2008-06-13 17:50 UTC by Jorn Baayen
Modified: 2009-04-16 22:39 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch to illustrate gst_element_get_state() not returing after loading empty file (1.09 KB, patch)
2008-06-13 17:53 UTC, Jorn Baayen
none Details | Review

Description Jorn Baayen 2008-06-13 17:50:21 UTC
We have a pipeline containing a decodebin linked to a fakesink for metadata retrieval. On every file processed, the previous source element (if any) is replaced by a new source element using gst_element_make_from_uri(). gst_bus_add_signal_watch() is used to get signals off the bus.

This all works well until one tries to load an empty file. Any consequent playback attempts have the following effects:
 1) No tag message is triggered, but no error message either;
 2) Calls to gst_element_get_state with GST_CLOCK_TIME_NONE never return.

Other kinds of erroneous files, like text files and images, are handled without trouble.

A simple test application can be found here:

 http://svn.o-hand.com/repos/misc/trunk/gaku/

The tag reading code is in tag-reader.c which is pretty basic. I can try to condense it into something simpler if that would be helpful.
Comment 1 Jorn Baayen 2008-06-13 17:53:09 UTC
Created attachment 112696 [details] [review]
Patch to illustrate gst_element_get_state() not returing after loading empty file
Comment 2 Tim-Philipp Müller 2008-06-13 18:29:12 UTC
Just some quick comments (have only glanced at the code, not tried it):

  - it's generally a bad idea to use gst_element_get_state (..., NONE)
    in a real application, because it won't ever return if an error
    occurs outside of the state change function (e.g. an error in
    the streaming thread)

  - downward state changes are immediate, you don't need to do a
    _get_state() after a _set_state (pipeline, NULL). (And in
    general, waiting for a state change with get_state usually
    only really needs to be done if _set_change() returned
    STATE_CHANGE_ASYNC, as it will usually only for state
    changes to PAUSED/PLAYING).

 - if you just want the tags, it's easiest to set the pipeline
   to PAUSED state and then do something like:

     msg = gst_bus_poll (pipeline_bus,
                         GST_MESSAGE_TAG |
                         GST_MESSAGE_ASYNC |
                         GST_MESSAGE_EOS |
                         GST_MESSAGE_ERROR);

   in  a loop until you get ASYNC, EOS or ERROR. This will iterate the
   main context though; gst_bus_pop_filtered() does the same thing without
   iterating the default main context.

Comment 3 Tim-Philipp Müller 2008-06-13 18:33:44 UTC
Err, _ASYNC_DONE, I meant.


(gst-launch-0.10 filesrc location=empty ! decodebin ! fakesink does throw an error on an empty file for me btw; make sure you use a recent-ish GStreamer, I know there was an issue with this a while back).

Comment 4 Jorn Baayen 2008-06-13 20:00:13 UTC
(In reply to comment #2)
> Just some quick comments (have only glanced at the code, not tried it):
> 
>   - it's generally a bad idea to use gst_element_get_state (..., NONE)
>     in a real application, because it won't ever return if an error
>     occurs outside of the state change function (e.g. an error in
>     the streaming thread)
> 
>   - downward state changes are immediate, you don't need to do a
>     _get_state() after a _set_state (pipeline, NULL). (And in
>     general, waiting for a state change with get_state usually
>     only really needs to be done if _set_change() returned
>     STATE_CHANGE_ASYNC, as it will usually only for state
>     changes to PAUSED/PLAYING).

Yes, the above patch is only for testing purposes which is why it is not included in the gaku svn trunk.

To elaborate, our real problem is not _get_state() not returning, but rather the pipeline being confused after having met an empty file: no more tags are found for successive streams. _get_state() not returing appears to be a mere symptom of this. I've included it in the bug report as I thought it might help to track down the problem.

>  - if you just want the tags, it's easiest to set the pipeline
>    to PAUSED state and then do something like:
> 
>      msg = gst_bus_poll (pipeline_bus,
>                          GST_MESSAGE_TAG |
>                          GST_MESSAGE_ASYNC |
>                          GST_MESSAGE_EOS |
>                          GST_MESSAGE_ERROR);
> 
>    in  a loop until you get ASYNC, EOS or ERROR. This will iterate the
>    main context though; gst_bus_pop_filtered() does the same thing without
>    iterating the default main context.

Yes but that would block the main loop wouldn't it? Our code is meant to be able to scan for metadata while any UI running in the same thread would stay responsive.

Comment 5 Jorn Baayen 2008-06-13 20:04:07 UTC
(In reply to comment #3)
> Err, _ASYNC_DONE, I meant.
> 
> 
> (gst-launch-0.10 filesrc location=empty ! decodebin ! fakesink does throw an
> error on an empty file for me btw; make sure you use a recent-ish GStreamer, I
> know there was an issue with this a while back).

Yes, it does for me too. In TagReader, an empty file throws an error, as do other kinds of files like plain text. However the problem of successive tag retrieval failing only occurs for empty files, as well as the get_state() issue.
Comment 6 Jussi Kukkonen 2008-06-14 15:10:51 UTC
(In reply to comment #5)
> (In reply to comment #3)
> > (gst-launch-0.10 filesrc location=empty ! decodebin ! fakesink does throw an
> > error on an empty file for me btw; make sure you use a recent-ish GStreamer, I
> > know there was an issue with this a while back).
> 
> Yes, it does for me too. In TagReader, an empty file throws an error, as do
> other kinds of files like plain text. However the problem of successive tag
> retrieval failing only occurs for empty files, as well as the get_state()
> issue.

Testing with gstreamer 0.10.18 and seeing what Jorn reported. It's not just empty files though -- any shortish text file triggers this as well (like gaku AUTHORS or README).

Comment 7 Jussi Kukkonen 2008-06-14 16:25:22 UTC
Happens with 0.10.19 as well.

The error that triggers this behaviour is TYPE_NOT_FOUND, I see at least "Could not determine type of stream" and "Stream contains no data".
Comment 8 Jorn Baayen 2008-06-15 08:25:06 UTC
GStreamer log on loading empty file with patch applied:

  http://folks.o-hand.com/~jorn/538176.log
Comment 9 Jorn Baayen 2008-06-30 09:21:19 UTC
tag-reader.c has moved to

  http://svn.o-hand.com/repos/misc/trunk/libowl-av/libowl-av/owl-tag-reader.c
Comment 10 Wim Taymans 2009-03-18 19:00:48 UTC
Isn't this the same issue that error keep the _get_state() function blocked (while it could be possible to unlock them with an ERROR)?
Comment 11 Tim-Philipp Müller 2009-04-16 22:39:28 UTC

*** This bug has been marked as a duplicate of 505770 ***