/* create_filesink_tail function to create a new multisink element * end link it to the pipeline * */ static void create_filesink_tail() { GstPad *srcpad; GstPad *sinkpad; //Create the new multisink element multisink = NULL; multisink = gst_element_factory_make ("filesink", NULL); if(!multisink) { g_print("failed to create new sink element! \n"); return; } //add it to the bin gst_bin_add(GST_BIN (pipeline), multisink); //switch the filename sprintf(name_buf, "image%05d.jpg", counter++); g_print ("File Switching %s\n", name_buf); g_object_set( G_OBJECT( multisink ), "location", name_buf, NULL ); //get and link the pads gst_element_link(multi_queue, multisink); srcpad = gst_element_get_static_pad( multi_queue, "src" ); sinkpad = gst_element_get_static_pad( multisink, "sink" ); gst_element_link_pads (multi_queue, "src", multisink, "sink"); gst_element_set_state (multisink, GST_STATE_PLAYING); } /* * destroy_bin_cb function to remove the multisink element from the pipeline * */ static gboolean destroy_bin_cb (gpointer user_data) { //oldbin is multisink element easy way to destroy it by using pipeline remove GstElement *oldbin = (GstElement *) user_data; g_print("Destroying old bin.\n"); if (pipeline) { //move it to the NULL state and remove it from the pipeline gst_element_set_state (oldbin, GST_STATE_NULL); gst_bin_remove (GST_BIN(pipeline), oldbin); } return FALSE; } /* replace_filesink_blocked_cb Callback function to block the block, unlink pads * */ static void replace_filesink_blocked_cb (GstPad *pad, gboolean blocked, gpointer user_data) { int ret; if (blocked) { GstElement *oldbin; GstPad *sinkpad; g_print("Blocked filesink queue.\n"); g_static_rec_mutex_lock(&mutex); g_print("Locked.\n"); oldbin = multisink; sinkpad = gst_element_get_static_pad(multisink, "sink"); if (!sinkpad) { g_print("replace_filesink_blocked_cb: oldbin doesn't have sink pad.\n"); goto fail; } //Unlink pads gst_pad_unlink(multi_queue_srcpad, sinkpad); g_print("Unlinked.\n"); //send EOS to the multisink sinkpad gst_pad_send_event(sinkpad, gst_event_new_eos()); g_print("Sent event.\n"); g_print("Checked sinks.\n"); g_print("Destroying old bin.\n"); if (pipeline) { //move it to the NULL state and remove it from the pipeline gst_element_set_state (oldbin, GST_STATE_NULL); gst_bin_remove (GST_BIN(pipeline), oldbin); } //call the tail to create the new multisink element create_filesink_tail(); g_print("Created filesink.\n"); g_static_rec_mutex_unlock(&mutex); g_print("Unlocked mutex.\n"); /* And unblock again. */ ret = gst_pad_set_blocked_async(multi_queue_srcpad, gboolean (FALSE), replace_filesink_blocked_cb, NULL); g_print("gst_pad_set_unblocked_async ret : %d \n", ret ); g_print("Done replacing filesink.\n"); } else { g_print("Unblocked filesink queue.\n"); } return; fail: g_print("FAIL!!!\n"); } /*replace_filesink function to replace the multisink element * */ static void replace_filesink() { int ret; if (multi_queue_srcpad == NULL) g_print("replace_filesink while no multi_queue_srcpad yet, waiting for it to appear.\n"); else { ret = gst_pad_set_blocked_async(multi_queue_srcpad, TRUE, replace_filesink_blocked_cb, NULL); g_print("gst_pad_set_blocked_async ret : %d \n", ret ); } }