Hi all,<br><br>I'm trying to rip a CD using a simple gstreamer pipeline - something that is already done in several programs,<br>but i'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'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 <glib.h><br>#include <gst/gst.h><br>#include <string.h><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("Got %s message\n", 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, &err, &debug);<br> g_print("Error: %s\n", err->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 < max_rip_track) {<br>
current_rip_track++;<br> g_print("going to next track %d\n", current_rip_track);<br> start_track_rip();<br> } else {<br> g_print("no more tracks, stopping\n");<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, &state, &pending_state, 0);<br> if (state != GST_STATE_PLAYING && pending_state != GST_STATE_PLAYING) {<br>
return FALSE;<br> }<br><br> if (gst_element_query_position(pipeline, &format, &pos)<br> && gst_element_query_duration(pipeline, &format, &len)) {<br> g_print("Time: %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r",<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("rip-pipeline");<br> source = gst_element_factory_make("cdparanoiasrc", "mycdparanoia");<br> filter = gst_element_factory_make("lame", "encoder");<br>
sink = gst_element_factory_make("filesink", "myfilesink");<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("Failed to link pipeline elements!");<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), "device", "/dev/hda", NULL);<br><br> start_track_rip();<br><br> g_print("starting main loop\n");<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), "myfilesink");<br> strcpy(buf, "/tmp/music_");<br> gchar buf2[10];<br> sprintf(buf2, "%02d", current_rip_track);<br>
strcat(buf, buf2);<br> strcat(buf, ".mp3");<br> gst_element_set_state(sink, GST_STATE_NULL);<br> g_object_set(G_OBJECT(sink), "location", buf, NULL);<br><br> // seek to track<br> GstElement *cd = gst_bin_get_by_name(GST_BIN(pipeline), "mycdparanoia");<br>
g_object_set(G_OBJECT(cd), "track", 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("01 state change failed\n");<br> } else if (state_ret == GST_STATE_CHANGE_SUCCESS) {<br> g_print("02 state change successful\n");<br> } else if (state_ret == GST_STATE_CHANGE_ASYNC) {<br>
// what am I supposed to do here?<br> g_print("seek async\n");<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>