g_signal_connect() strange behaviour

Viewed 42

I try to create gstreamer application for Raspberry Pi 3, which captures mpeg2 data flow from custom usb device and uses appsrc to push this data to pipeline. This is how my pipeline looks in .dot file: Pipeline image

My problem: GstTSDemux in not linked to GstH264Parse.

I use g_singnal_connect() to link demuxer and parser together in callback function. But this function is not called when application starts. Here is my struct with gstreamer elemenets:

struct CustomData {
CustomData():
    pipeline{nullptr},
    videosrc{nullptr},
    videoenc{nullptr},
    muxer{nullptr},
    sink{nullptr},
    parser{nullptr},
    converter{nullptr},
    numSamples{0},
    sourceId{0},
    mainLoop{nullptr},
    timer{nullptr}
{
}

GstElement *pipeline, *videosrc, *videoenc, *muxer, *sink, *parser, *converter;
guint64 numSamples;   /* Number of samples generated so far (for timestamp generation) */
guint sourceId;        /* To control the GSource */
GMainLoop *mainLoop;  /* GLib's Main Loop */
GTimer *timer;
};

I've created static void function linkMuxerParser() to link demuxer and parser:

static void linkMuxerParser(GstElement* element, GstPad* sourcePad, gpointer sinkElement)
{
    GstPad* sinkPad = gst_element_get_static_pad((GstElement*)sinkElement, "sink");
    GstPadLinkReturn ret;

    ret = gst_pad_link(sourcePad, sinkPad);
    if ( ret != GST_PAD_LINK_OK) {
        g_print("link mux -> parser fail\n");
    }
    gst_object_unref(sinkPad);
    g_print("link mux -> parser\n");
}

And this is my initialization code.

gst_init (NULL, NULL);
videoSource.videoData.mainLoop = g_main_loop_new (NULL, FALSE);
videoSource.videoData.pipeline = gst_pipeline_new ("video-player");
videoSource.videoData.videosrc = gst_element_factory_make ("appsrc", "video_source");
videoSource.videoData.muxer = gst_element_factory_make ("tsdemux", "mydemux");
videoSource.videoData.parser = gst_element_factory_make ("h264parse", "parser");
videoSource.videoData.videoenc = gst_element_factory_make ("omxh264dec", "videoenc");
videoSource.videoData.converter = gst_element_factory_make ("videoconvert", "convert");
videoSource.videoData.sink = gst_element_factory_make ("fbdevsink", "sink");

if (!videoSource.videoData.pipeline || !videoSource.videoData.videosrc || !videoSource.videoData.muxer ||
        !videoSource.videoData.parser || !videoSource.videoData.videoenc || !videoSource.videoData.converter || !videoSource.videoData.sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
}

g_print ("Elements are created\n");

bus = gst_pipeline_get_bus (GST_PIPELINE (videoSource.videoData.pipeline));
gst_bus_add_watch (bus, bus_call, videoSource.videoData.mainLoop);
gst_object_unref (bus);

gst_bin_add_many (GST_BIN (videoSource.videoData.pipeline), videoSource.videoData.videosrc, videoSource.videoData.muxer,
                  videoSource.videoData.parser, videoSource.videoData.videoenc, videoSource.videoData.converter, videoSource.videoData.sink, NULL);

g_print ("Added all the Elements into the pipeline\n");

/* we link the elements together */
if (!gst_element_link(videoSource.videoData.videosrc, videoSource.videoData.muxer)) {
    g_print("Failed src -> queue link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

if (!gst_element_link(videoSource.videoData.parser, videoSource.videoData.videoenc)) {
    g_print("Failed parser -> enc link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

if (!gst_element_link(videoSource.videoData.videoenc, videoSource.videoData.converter)) {
    g_print("Failed enc -> conv link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

if (!gst_element_link(videoSource.videoData.converter, videoSource.videoData.sink)) {
    g_print("Failed conv -> sink link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

result = g_signal_connect (videoSource.videoData.muxer, "pad-added", G_CALLBACK (linkMuxerParser), videoSource.videoData.parser);
if (result <= 0 ) {
    g_print("Failed mux -> parser link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}
g_signal_connect (videoSource.videoData.videosrc, "need-data", G_CALLBACK (VideoSource::startFeed), &videoSource.videoData);
g_signal_connect (videoSource.videoData.videosrc, "enough-data", G_CALLBACK (VideoSource::stopFeed), &videoSource.videoData);

videoSource.videoData.timer = g_timer_new();

g_print ("Linked all the Elements together\n");
/* Set the pipeline to "playing" state*/
g_print ("Playing the video\n");
gst_element_set_state (videoSource.videoData.pipeline, GST_STATE_PLAYING);
GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN (videoSource.videoData.pipeline),  GST_DEBUG_GRAPH_SHOW_ALL, "play");

/* Iterate */
g_print ("Running...\n");
g_main_loop_run (videoSource.videoData.mainLoop);

When I start the application I see in console:

Elements are created
Added all the Elements into the pipeline
Linked all the Elements together
Playing the video
Running...

And my callback linkMuxerParser() is not called. Maybe someone can detect what I missed? Thank You in advance.

0 Answers
Related