Events work in a very similar way as queries. Dispatching, for
example, works exactly the same for events (and also has the same
limitations), and they can similarly be sent to the toplevel pipeline
and it will figure out everything for you. Although there are more
ways in which applications and elements can interact using events,
we will only focus on seeking here. This is done using the seek-event.
A seek-event contains a playback rate, a seek offset format (which is
the unit of the offsets to follow, e.g. time, audio samples, video
frames or bytes), optionally a set of seeking-related flags (e.g.
whether internal buffers should be flushed), a seek method (which
indicates relative to what the offset was given), and seek offsets.
The first offset (cur) is the new position to seek to, while
the second offset (stop) is optional and specifies a position where
streaming is supposed to stop. Usually it is fine to just specify
GST_SEEK_TYPE_NONE and -1 as end_method and end offset. The behaviour
of a seek is also wrapped in the gst_element_seek ()
.
static void seek_to_time (GstElement *pipeline, gint64 time_nanoseconds) { if (!gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time_nanoseconds, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { g_print ("Seek failed!\n"); } }
Seeks should usually be done when the pipeline is in PAUSED or PLAYING state (when it is in PLAYING state the pipeline will pause itself, issue the seek, and then set itself back to PLAYING again itself). returns.
It is important to realise that seeks will not happen instantly in the
sense that they are finished when the function
gst_element_seek ()
returns. Depending on the
specific elements involved, the actual seeking might be done later in
another thread (the streaming thread), and it might take a short time
until buffers from the new seek position will reach downstream elements
such as sinks (if the seek was non-flushing then it might take a bit
longer).
It is possible to do multiple seeks in short time-intervals, such as a direct response to slider movement. After a seek, internally, the pipeline will be paused (if it was playing), the position will be re-set internally, the demuxers and decoders will decode from the new position onwards and this will continue until all sinks have data again. If it was playing originally, it will be set to playing again, too. Since the new position is immediately available in a video output, you will see the new frame, even if your pipeline is not in the playing state.