Changing filesink location after a mux with many inputs.

Paddy pat.blanchon at gmail.com
Wed Sep 5 13:33:34 PDT 2012


Thanks for the reply Thiago - your suggestion will help when I get to points
3 & 4. Unfortunately I'm still stuck at point 1, which is where this thread
began. I only receive one callback from the two calls to
gst_pad_set_blocked_async() after which the pipeline stalls.

Here's some code that demonstrates the problem:

#include  <gst/gst.h>
#include  <glib.h>

#define  myprint(_a...)     g_print(__PRETTY_FUNCTION__), g_print("(): "),
g_print(_a), g_print("\n")

static void  pad_block(gboolean  blocked);
static void  pad_block_cb(GstPad  *pad, gboolean  blocked, gpointer 
user_data);
static gboolean pad_block_timer(gpointer  user_data);

static GstPad  *video_q_src_pad = NULL,
                    *audio_q_src_pad = NULL;
static volatile gint  n_video_cb = 0,
                          n_audio_cb = 0;

static gboolean pad_block_timer(gpointer  user_data)
{
    pad_block(TRUE);
    return  TRUE;
}

static void  pad_block(gboolean  blocked)
{
    myprint("%sblocking pads", blocked ? "" : "un");
    n_video_cb = 0;
    n_audio_cb = 0;
    g_assert(gst_pad_set_blocked_async(video_q_src_pad, blocked,
pad_block_cb, NULL));
    g_assert(gst_pad_set_blocked_async(audio_q_src_pad, blocked,
pad_block_cb, NULL));
}

static void  pad_block_cb(GstPad  *pad, gboolean  blocked, gpointer 
user_data)
{
    if (pad == video_q_src_pad) {
        ++n_video_cb;
        myprint("video %sblocked callback rx'd [%d]", blocked ? "" : "un",
n_video_cb);
    } else if (pad == audio_q_src_pad) {
        ++n_audio_cb;
        myprint("audio %sblocked callback rx'd [%d]", blocked ? "" : "un",
n_audio_cb);
    } else {
        myprint("unknown %sblocked callback rx'd [%d]", blocked ? "" : "un",
n_audio_cb);
    }

    if (blocked && n_video_cb && n_audio_cb) {
        myprint("all callbacks rx'd");
        pad_block(FALSE);
    }
}

int  main(int  argc, char  *argv[])
{
    gst_init(NULL, NULL);
    GMainLoop   *loop = g_main_loop_new(NULL, FALSE);
    // Create & configure pipeline elements
    GstElement  *pipeline  = gst_pipeline_new ("block_x2_pipeline"),
                *video_src = gst_element_factory_make("videotestsrc", NULL),
                *video_enc = gst_element_factory_make("x264enc", NULL),
                *video_q   = gst_element_factory_make("queue", "video_q"),
                *audio_src = gst_element_factory_make("audiotestsrc", NULL),
                *audio_enc = gst_element_factory_make("faac", NULL),
                *audio_q   = gst_element_factory_make("queue", "audio_q"),
                *mux       = gst_element_factory_make("matroskamux", NULL),
                *filesink  = gst_element_factory_make("filesink", NULL);
    g_object_set(G_OBJECT(video_src), "is-live", TRUE, NULL);
    g_object_set(G_OBJECT(audio_src), "is-live", TRUE, "wave", 6, NULL);
    g_object_set(G_OBJECT(audio_enc), "bitrate", 8000, NULL);
    g_object_set(G_OBJECT(filesink), "location", "test.mkv", NULL);
    gst_bin_add_many(GST_BIN(pipeline),
                     video_src, video_enc, video_q,
                     audio_src, audio_enc, audio_q,
                     mux, filesink, NULL);

    // Get the pads to (un)block
    video_q_src_pad = gst_element_get_static_pad(video_q, "src");
    audio_q_src_pad = gst_element_get_static_pad(audio_q, "src");

    // Link static pads
    g_assert(gst_element_link_many(video_src, video_enc, video_q, NULL));
    g_assert(gst_element_link_many(audio_src, audio_enc, audio_q, NULL));
    g_assert(gst_element_link(mux, filesink));

    // Link request pads
    GstPad  *sink_pad = gst_element_get_request_pad(mux, "video_%d");
    g_assert(gst_pad_link(video_q_src_pad, sink_pad) == GST_PAD_LINK_OK);
    gst_object_unref(GST_OBJECT(sink_pad));
    sink_pad = gst_element_get_request_pad(mux, "audio_%d");
    g_assert(gst_pad_link(audio_q_src_pad, sink_pad) == GST_PAD_LINK_OK);
    gst_object_unref(GST_OBJECT(sink_pad));

    myprint("Running...");
    (void)gst_element_set_state(pipeline, GST_STATE_PLAYING);
    g_timeout_add_seconds(10, (GSourceFunc)pad_block_timer, NULL);
    g_main_loop_run(loop);
    myprint("Stopping ...");
    g_assert(gst_element_set_state(pipeline, GST_STATE_NULL) !=
GST_STATE_CHANGE_FAILURE);
    gst_object_unref(GST_OBJECT (pipeline));

    return 0;
}

which produces the output:
main(): Running...
pad_block(): blocking pads
pad_block_cb(): video blocked callback rx'd [1]
pad_block(): blocking pads
**
ERROR:block_x2.c:28:pad_block: assertion failed:
(gst_pad_set_blocked_async(video_q_src_pad, blocked, pad_block_cb, NULL))
Aborted (core dumped)

where the second pad_block() call is 10s after the first.

I'm using gstreamer 0.10.36 on Fedora 17.

Any guidance on getting the second callback to happen is very much
appreciated.





--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Changing-filesink-location-after-a-mux-with-many-inputs-tp4656116p4656178.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list