Hi all,<br><br>I&#39;m trying to rip a CD using a simple gstreamer pipeline - something that is already done in several programs,<br>but i&#39;d like to understand myself how it works.<br><br>In the code below, I basically use the EOS event to seek to the next cd track.<br>
But the behavior I see is weird:<br>-the first track is ripped ok<br>-I call the start_track_rip function for track 2<br>-the program blocks here forever.<br><br>I must be doing something really wrong but I can&#39;t see what, even by the looking at the sources of sound juicer for example. <br>
Any help is welcome, <br><br>- pog<br><br>Code below:<br>-----------------<br><br>#include &lt;glib.h&gt;<br>#include &lt;gst/gst.h&gt;<br>#include &lt;string.h&gt;<br><br>guint current_rip_track = 1;<br>guint max_rip_track = 10;<br>
<br>void start_track_rip();<br><br>static GMainLoop *loop;<br>GstElement *pipeline;<br><br>static gboolean<br>my_bus_callback(GstBus * bus, GstMessage * message, gpointer data)<br>{<br>    g_print(&quot;Got %s message\n&quot;, GST_MESSAGE_TYPE_NAME(message));<br>
    switch (GST_MESSAGE_TYPE(message)) {<br>    case GST_MESSAGE_ERROR:{<br>            GError *err;<br>            gchar *debug;<br>            gst_message_parse_error(message, &amp;err, &amp;debug);<br>            g_print(&quot;Error: %s\n&quot;, err-&gt;message);<br>
            g_error_free(err);<br>            g_free(debug);<br>            g_main_loop_quit(loop);<br>            break;<br>        }<br>    case GST_MESSAGE_EOS:<br>        if (current_rip_track &lt; max_rip_track) {<br>
            current_rip_track++;<br>            g_print(&quot;going to next track %d\n&quot;, current_rip_track);<br>            start_track_rip();<br>        } else {<br>            g_print(&quot;no more tracks, stopping\n&quot;);<br>
            return FALSE;<br>        }<br>        break;<br>    default:<br>        /* unhandled message */<br>        break;<br>    }<br>    return TRUE;<br>}<br><br>static gboolean cb_print_position(GstElement * pipeline)<br>
{<br>    GstState state, pending_state;<br>    static GstFormat format = GST_FORMAT_TIME;<br>    gint64 pos, len;<br><br>    gst_element_get_state(pipeline, &amp;state, &amp;pending_state, 0);<br>    if (state != GST_STATE_PLAYING &amp;&amp; pending_state != GST_STATE_PLAYING) {<br>
        return FALSE;<br>    }<br><br>    if (gst_element_query_position(pipeline, &amp;format, &amp;pos)<br>        &amp;&amp; gst_element_query_duration(pipeline, &amp;format, &amp;len)) {<br>        g_print(&quot;Time: %&quot; GST_TIME_FORMAT &quot; / %&quot; GST_TIME_FORMAT &quot;\r&quot;,<br>
            GST_TIME_ARGS(pos), GST_TIME_ARGS(len));<br>    }<br>    /* call me again */<br>    return TRUE;<br>}<br><br>int main()<br>{<br>    gst_init(NULL, NULL);<br><br>    GstElement *source, *filter, *sink;<br>    GstBus *bus;<br>
<br>    // build pipeline<br>    pipeline = gst_pipeline_new(&quot;rip-pipeline&quot;);<br>    source = gst_element_factory_make(&quot;cdparanoiasrc&quot;, &quot;mycdparanoia&quot;);<br>    filter = gst_element_factory_make(&quot;lame&quot;, &quot;encoder&quot;);<br>
    sink = gst_element_factory_make(&quot;filesink&quot;, &quot;myfilesink&quot;);<br>    gst_bin_add_many(GST_BIN(pipeline), source, filter, sink, NULL);<br><br>    if (!gst_element_link_many(source, filter, sink, NULL)) {<br>
        g_warning(&quot;Failed to link pipeline elements!&quot;);<br>    }<br><br>    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));<br>    gst_bus_add_watch(bus, my_bus_callback, NULL);<br>    gst_object_unref(bus);<br>
<br>    g_object_set(G_OBJECT(source), &quot;device&quot;, &quot;/dev/hda&quot;, NULL);<br><br>    start_track_rip();<br><br>    g_print(&quot;starting main loop\n&quot;);<br><br>    GMainLoop *loop = g_main_loop_new(NULL, FALSE);<br>
    g_main_loop_run(loop);<br><br>    /* clean up */<br>    gst_element_set_state(pipeline, GST_STATE_NULL);<br>    gst_object_unref(pipeline);<br>    g_main_loop_unref(loop);<br><br>    return (0);<br>}<br><br>void start_track_rip()<br>
{<br>    gchar buf[2048];<br><br>    GstElement *sink = gst_bin_get_by_name(GST_BIN(pipeline), &quot;myfilesink&quot;);<br>    strcpy(buf, &quot;/tmp/music_&quot;);<br>    gchar buf2[10];<br>    sprintf(buf2, &quot;%02d&quot;, current_rip_track);<br>
    strcat(buf, buf2);<br>    strcat(buf, &quot;.mp3&quot;);<br>    gst_element_set_state(sink, GST_STATE_NULL);<br>    g_object_set(G_OBJECT(sink), &quot;location&quot;, buf, NULL);<br><br>    // seek to track<br>    GstElement *cd = gst_bin_get_by_name(GST_BIN(pipeline), &quot;mycdparanoia&quot;);<br>
    g_object_set(G_OBJECT(cd), &quot;track&quot;, current_rip_track, NULL);<br>    GstStateChangeReturn state_ret =<br>        gst_element_set_state(pipeline, GST_STATE_PLAYING);<br><br>    if (state_ret == GST_STATE_CHANGE_FAILURE) {<br>
        g_print(&quot;01 state change failed\n&quot;);<br>    } else if (state_ret == GST_STATE_CHANGE_SUCCESS) {<br>        g_print(&quot;02 state change successful\n&quot;);<br>    } else if (state_ret == GST_STATE_CHANGE_ASYNC) {<br>
        // what am I supposed to do here?<br>        g_print(&quot;seek async\n&quot;);<br>        state_ret =<br>            gst_element_get_state(pipeline, NULL, NULL, GST_SECOND / 2);<br>    }<br><br>    g_timeout_add_seconds(1, (GSourceFunc) cb_print_position, pipeline);<br>
}<br>