[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