- g_object_set(source, "location", path, END);
-
- /* Add the elements to the pipeline. It will take over responsibility for
- * them.
- */
- gst_bin_add_many(GST_BIN(state.pipeline), source, decode, sink, END);
-
- /* Link the elements together as far as we can. Arrange to link the decoder
- * onto our (dummy) sink when it's ready to produce output.
- */
- if(!gst_element_link(source, decode)) {
- disorder_error(0, "error checking `%s': "
- "failed to link GStreamer elements `file' and `decode'",
- path);
- goto end;
- }
- g_signal_connect(decode, "pad-added",
- G_CALLBACK(decoder_pad_arrived), &state);
-
- /* Fetch the bus and listen for messages. */
- bus = gst_pipeline_get_bus(GST_PIPELINE(state.pipeline));
- gst_bus_add_signal_watch(bus);
- g_signal_connect(bus, "message", G_CALLBACK(bus_message), &state);
-
- /* Turn the handle until we have an answer. The message handler will wake us
- * up if: the pipeline reports that the duration has changed (suggesting that
- * something might know what it is); we successfully reach the initial
- * `paused' state; or we hit the end of the stream (by which point we ought
- * to know where we are).
- */
- state.loop = g_main_loop_new(0, FALSE);
- gst_element_set_state(state.pipeline, GST_STATE_PAUSED); running = 1;
- for(;;) {
- g_main_loop_run(state.loop);
- if(!query_track_length(&state, &length)) goto end;
- switch(state.state) {
- case ST_BOTCHED: goto end;
- case ST_EOS:
- disorder_error(0, "error checking `%s': "
- "failed to fetch duration from GStreamer pipeline",
- path);
- goto end;
- case ST_PAUSED:
- gst_element_set_state(state.pipeline, GST_STATE_PLAYING);
- state.state = ST_PLAY;
- break;
- }
- }