GNOME Bugzilla – Bug 356369
Problems with gst_element_seek
Last modified: 2006-09-17 22:17:17 UTC
Please describe the problem: The following code is used for seeking: bool GstPlayer::seek_relative(gint64 time){ gst_element_set_state (GST_ELEMENT (player), GST_STATE_PAUSED); if (!gst_element_seek (player, //the element 1.0, //new playback rate, same as before GST_FORMAT_TIME, //the format of the time is in microseconds GST_SEEK_FLAG_FLUSH, //don't know really what this means GST_SEEK_TYPE_CUR, // change from the current position time * GST_SECOND,//how much should you change GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { g_print ("Seek failed!\n"); } gst_element_set_state (GST_ELEMENT (player), GST_STATE_PLAYING); } the "player" element was constructed with player = gst_element_factory_make("playbin", "player"); and The plan is that the argument ("time") decides how much you should seek, forwards or backward. If you give "1" as an argument it should seek 1 second forward, if you give "-1" as the argument it should seek 1 second backwards. For a .ogg file this works perfectly. For an .flac file the following error is reported: GStreamer-CRITICAL **: gst_pad_query_convert: assertion `src_val >= 0' failed This happens when the "time" argument is negative. For a .mp3 file forward seeking works, but backwards seeking stop the player. I do not know if this is a but or intended behavior, but I find it strange that different elements give different result. Steps to reproduce: 1. Try my program with different files. 2. Try to seek backwards and forward. 3. Watch and hear the output. Actual results: Seek backwards only work for .ogg files. Expected results: It should work for all files supported by gstreamer. Does this happen every time? Yes Other information: I will try to add the program I hacked up.
Created attachment 72929 [details] test program for reproducing the bug requires gtkmm and gstreamer
The problem can also be solved by changing the code to the following: bool GstPlayer::seek_relative(gint64 time){ gst_element_set_state (GST_ELEMENT (player), GST_STATE_PAUSED); gint64 current_position; GstFormat time_format = GST_FORMAT_TIME; gst_element_query_position(player, &time_format, ¤t_position); if (!gst_element_seek (player, //the element 1.0, //new playback rate, same as before GST_FORMAT_TIME, //the format of the time is in microseconds GST_SEEK_FLAG_FLUSH, //don't know really what this means GST_SEEK_TYPE_SET, // change from the current position current_position + (time * GST_SECOND),//how much should you change GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { g_print ("Seek failed!\n"); } gst_element_set_state (GST_ELEMENT (player), GST_STATE_PLAYING); } So maybe it is not a problem, what do I know......
The second fragment of code is the correct way to do this. GST_SEEK_TYPE_CUR is a little confusing - it doesn't do a seek relative to the current position, but relative to the currently configured playback segment. It's rarely useful. So, closing this as not-a-bug.
Two more notes: - you should also check the return value of _query_position() - the time is in nanoseconds, not microseconds