[gst-devel] how to link multiple filesinks to a output-selector before playing pipeline
shuyufu
shuyufu at gmail.com
Sat Nov 20 08:42:53 CET 2010
Hi guys,
I was trying to create a pipeline like this
filesink
/
filesrc -- output-selector
\
filesink
But, I can't link both filesinks to the output-selector before the pipeline
is PLAYED.
However, I can link a single filesink to the output-selector and then link
another after the state of pipleline is PLAYING of course.
I use gst-launch to verify this issue but it stucked also. My command like
this,
gst-launch filesrc location=/dev/zero ! output-selector name=selector
selector. ! filesink location=a.dat selector. ! filesink location=b.dat
In the last part of this post is the source code for your reference.
I have tried to google this issue but nothing found. Is there anybody know
what's wrong to my pipeline (code)?
Thanks for your time and sorry for my poor writing.
#include <gst/gst.h>
GstElement *pipeline = NULL;
GstElement *file_src = NULL;
GstElement *output_selector = NULL;
GstElement *file_sink_a = NULL;
GstElement *file_sink_b = NULL;
GstPad *srcpad_a = NULL;
GstPad *srcpad_b = NULL;
static gboolean switch_file_a (gpointer data);
static gboolean switch_file_b (gpointer data);
static gboolean switch_file_a (gpointer data)
{
g_object_set(G_OBJECT(output_selector), "active-pad", srcpad_a, NULL);
g_timeout_add(5 * 1000, (switch_file_b), NULL);
return FALSE;
}
static gboolean switch_file_b (gpointer data)
{
g_object_set(G_OBJECT(output_selector), "active-pad", srcpad_b, NULL);
g_timeout_add(5 * 1000, (switch_file_a), NULL);
return FALSE;
}
static gboolean create_file_b (gpointer data)
{
GstPad *sinkpad = NULL;
GstPadLinkReturn link_ret;
gst_bin_add_many (GST_BIN (pipeline), file_sink_b, NULL);
gst_element_set_state (file_sink_b, GST_STATE_PLAYING);
srcpad_b = gst_element_get_request_pad(output_selector, "src%d");
sinkpad = gst_element_get_static_pad(file_sink_b, "sink");
link_ret = gst_pad_link(srcpad_b, sinkpad);
if (GST_PAD_LINK_FAILED(link_ret)) {
g_print("linking filesink_b failed %d\n", link_ret);
}
gst_object_unref(GST_OBJECT(sinkpad));
g_timeout_add(5 * 1000, switch_file_b, NULL);
return FALSE;
}
static gboolean message_handler (GstBus *bus, GstMessage *message, gpointer
data)
{
switch (GST_MESSAGE_TYPE (message))
{
case GST_MESSAGE_STATE_CHANGED:
{
GstState old_state, new_state;
gst_message_parse_state_changed(message, &old_state, &new_state,
NULL);
g_print("Element %s changed state from %s to %s.\n",
GST_OBJECT_NAME(message->src),
gst_element_state_get_name(old_state),
gst_element_state_get_name(new_state));
if (g_strcmp0("my-pipeline", GST_OBJECT_NAME(message->src)) == 0
&& new_state == GST_STATE_PLAYING)
{
create_file_b(NULL);
return FALSE;
}
break;
}
default:
break;
}
return TRUE;
}
int main (int argc, char** argv)
{
GMainLoop *loop = NULL;
GOptionContext *ctx = NULL;
GError *err = NULL;
GstBus *bus = NULL;
GstPad *sinkpad = NULL;
GstPadLinkReturn link_ret;
if (!g_thread_supported ())
g_thread_init (NULL);
ctx = g_option_context_new (" output-selector test application");
g_option_context_add_group (ctx, gst_init_get_option_group ());
if (!g_option_context_parse (ctx, &argc, &argv, &err))
{
g_print ("Failed to initialize: %s\n", err->message);
g_error_free (err);
return 1;
}
loop = g_main_loop_new (NULL, FALSE);
pipeline = gst_pipeline_new ("my-pipeline");
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
gst_bus_add_watch(bus, message_handler, NULL);
gst_object_unref(bus);
file_src = gst_element_factory_make ("filesrc", NULL);
g_object_set (G_OBJECT (file_src), "location", "/dev/zero", NULL);
output_selector = gst_element_factory_make ("output-selector", NULL);
file_sink_a = gst_element_factory_make ("filesink", NULL);
g_object_set (G_OBJECT (file_sink_a), "location", "/home/bobby/a.dat",
NULL);
file_sink_b = gst_element_factory_make ("filesink", NULL);
g_object_set (G_OBJECT (file_sink_b), "location", "/home/bobby/b.dat",
NULL);
gst_bin_add_many (GST_BIN (pipeline), file_src, output_selector,
file_sink_a, file_sink_b, NULL);
srcpad_a = gst_element_get_request_pad (output_selector, "src%d");
sinkpad = gst_element_get_static_pad (file_sink_a, "sink");
link_ret = gst_pad_link (srcpad_a, sinkpad);
if (GST_PAD_LINK_FAILED (link_ret))
{
g_error ("linking filesink_a fail\n");
}
gst_object_unref (GST_OBJECT (sinkpad));
srcpad_b = gst_element_get_request_pad (output_selector, "src%d");
sinkpad = gst_element_get_static_pad (file_sink_b, "sink");
link_ret = gst_pad_link (srcpad_b, sinkpad);
if (GST_PAD_LINK_FAILED (link_ret))
{
g_error ("linking filesink_b fail\n");
}
gst_object_unref (GST_OBJECT (sinkpad));
gst_element_link_many (file_src, output_selector, NULL);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
return 0;
}
--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/how-to-link-multiple-filesinks-to-a-output-selector-before-playing-pipeline-tp3051323p3051323.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
More information about the gstreamer-devel
mailing list