/* example-begin helloworld.c */ #include GstElement *pipeline = NULL; static void blocked_cb (GstPad *pad, gboolean blocked, gpointer user_data) { gchar *name = gst_pad_get_name (pad); if (blocked) { g_debug ("Pad %s blocked successfully", name); } else { g_debug ("Pad %s unblocked successfully", name); } gst_object_unref (GST_OBJECT (pad)); g_free (name); } /* this function will be called when a block has succeeded, it will unlink the * previous sink element and link the new sink element. * It will remove previous sink from pipeline (bin) and add new_sink_ele pipeline * .----------. .-------------. | decoder | | old_sink_ele | ... src -> sink | '----------'\ '-------------' \ .--------------. \ | new_sink_ele | -> sink | '--------------' */ static void unlink_and_replace (GstPad *decoder_src_pad, gboolean blocked, gpointer user_data_new_sink_ele) { g_debug ("%s: Blocked pad successfully, unlinking and replacing downstream", G_STRFUNC); GstPad *old_sink_ele_sink_pad = NULL; old_sink_ele_sink_pad = gst_pad_get_peer (decoder_src_pad); if (old_sink_ele_sink_pad == NULL) { return; } GstElement *new_sink_ele = (GstElement *)user_data_new_sink_ele; GstElement *old_sink_ele = gst_pad_get_parent_element (old_sink_ele_sink_pad); if (old_sink_ele == NULL) { gst_object_unref (GST_OBJECT (old_sink_ele_sink_pad)); return; } gst_pad_unlink (decoder_src_pad, old_sink_ele_sink_pad); if (new_sink_ele) { GstElement *decoder = NULL; gst_bin_add (GST_BIN (pipeline), new_sink_ele); decoder = gst_pad_get_parent_element (decoder_src_pad); gst_element_link (decoder, new_sink_ele); gst_element_sync_state_with_parent (new_sink_ele); gst_object_unref (GST_OBJECT (decoder)); gst_pad_set_blocked_async (decoder_src_pad, FALSE, blocked_cb, NULL); gst_object_unref (GST_OBJECT (new_sink_ele)); // do we need this ? } gst_bin_remove (GST_BIN (pipeline), old_sink_ele); gst_object_unref (GST_OBJECT (old_sink_ele_sink_pad)); gst_object_unref (GST_OBJECT (old_sink_ele)); } int main (int argc, char *argv[]) { GstElement *filesrc, *decoder, *alsaaudiosink = NULL, *pulseaudiosink = NULL; GstPad *decoder_src = NULL; gst_init(&argc, &argv); if (argc != 2) { g_print ("usage: %s \n", argv[0]); exit (-1); } /* create a new pipeline to hold the elements */ pipeline = gst_pipeline_new ("pipeline"); /* create a disk reader */ filesrc = gst_element_factory_make ("filesrc", "disk_source"); g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL); /* now it's time to get the decoder */ decoder = gst_element_factory_make ("mad", "decoder"); /* and an audio sink */ alsaaudiosink = gst_element_factory_make ("alsasink", "alsa_play_audio"); /* add objects to the main pipeline */ gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, alsaaudiosink, NULL); /* link src to sink */ gst_element_link(filesrc, decoder); gst_element_link(decoder,alsaaudiosink); /* start playing */ gst_element_set_state (pipeline, GST_STATE_PLAYING); static int is_playing = 1; static int is_quiting = 0; static int is_alsasink = 1; while (1) { if(!(gst_bin_iterate_elements (GST_BIN (pipeline)))) break; printf(" q:Quit, p:Pause/Play, t:Test: "); char ch =0 ; ch=getchar(); switch (ch) { case 'p': if(is_playing) { /* pause */ gst_element_set_state (pipeline, GST_STATE_PAUSED); } else { /* start playing */ gst_element_set_state (pipeline, GST_STATE_PLAYING); } is_playing = !is_playing; break; case 't': printf("================================================================\n"); if(is_alsasink) { decoder_src = gst_element_get_pad (decoder, "src"); g_debug ("%s (%d): block decoder src pad\n", __FUNCTION__, __LINE__); pulseaudiosink = gst_element_factory_make ("pulsesink", "pulse_play_audio"); gst_pad_set_blocked_async (decoder_src, TRUE, unlink_and_replace, pulseaudiosink); } else { decoder_src = gst_element_get_pad (decoder, "src"); g_debug ("%s (%d): block decoder src pad\n", __FUNCTION__, __LINE__); alsaaudiosink = gst_element_factory_make ("alsasink", "alsa_play_audio"); gst_pad_set_blocked_async (decoder_src, TRUE, unlink_and_replace, alsaaudiosink); } is_alsasink = !is_alsasink; break; case 'q': is_quiting = 1; break; default: break; } if(is_quiting) break; GstFormat fmt = GST_FORMAT_TIME; gint64 pos, len; if (gst_element_query_position (pipeline, &fmt, &pos) && gst_element_query_duration (pipeline, &fmt, &len)) { g_print ("Time: %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (pos), GST_TIME_ARGS (len)); } sleep(2); } /* stop the pipeline */ gst_element_set_state (pipeline, GST_STATE_NULL); /* we don't need a reference to these objects anymore */ gst_object_unref (GST_OBJECT (pipeline)); /* unreffing the pipeline unrefs the contained elements as well */ exit (0); }