I have a bin inside a pipeline containing a uridecodebin
linked to an autoaudiosink
.
When I set the pipeline to the playing state before adding the bin or its children (point A or B in the following code), and then start, stop, and restart the bin, playback resumes from where it last stopped.
When I set the pipeline to the playing state after adding the bin and its elements (point C), though, playback restarts from the beginning when restarting the bin.
Why is this the case? What is different about the pipeline state when using points A/B and C that causes this difference in behaviour?
#include <gst/gst.h>
void pad_added(GstElement *src, GstPad *src_pad, GstElement *sink) {
GstPad *sink_pad = gst_element_get_static_pad(sink, "sink");
gst_pad_link(src_pad, sink_pad);
gst_object_unref(sink_pad);
}
int main(int argc, char *argv[]) {
gst_init(&argc, &argv);
// Create an empty pipeline.
GstPipeline *pipeline = GST_PIPELINE(gst_pipeline_new(NULL));
// POINT A
// Make sure the pipeline is on to start.
// gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
// Create an empty bin, and add it to the pipeline.
GstBin *bin = GST_BIN(gst_bin_new(NULL));
gst_bin_add(GST_BIN(pipeline), GST_ELEMENT(bin));
// POINT B
// Make sure the pipeline is on to start.
// gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
// Create the elements, add them to the bin, and link them.
GstElement *src = gst_element_factory_make("uridecodebin", NULL);
GstElement *sink = gst_element_factory_make("autoaudiosink", NULL);
gst_bin_add_many(bin, src, sink, NULL);
g_signal_connect(src, "pad-added", G_CALLBACK(pad_added), sink);
// Choose an audio file.
g_object_set(src, "uri", "http://commondatastorage.googleapis.com/codeskulptor-assets/Evillaugh.ogg", NULL);
// POINT C
// Make sure the pipeline is on to start.
// gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
// Start, stop, and restart the bin.
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
g_usleep(3 * G_USEC_PER_SEC);
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
g_usleep(3 * G_USEC_PER_SEC);
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
// Clean up.
g_object_unref(pipeline);
}