Issues with programatical gstreamer pipeline

Hello,
I’m trying to write a programmatically defined GStreamer pipeline that uses nvarguscamerasrc. I’m facing several problems with that:

  1. The code below works only with both:
g_object_set(G_OBJECT(m_source), "sensor-id", G_TYPE_INT, 0, NULL);
g_object_set(G_OBJECT(m_source), "sensor-mode", G_TYPE_INT, 4, NULL);

uncommented out. If the first line is uncommented but the second still a comment then the app immediately shuts down. With both uncommented I’m getting Seg Fault. When both are as comments then the stream works with some default resolution but I’m logging warnings like:

0:00:01.302470144 30006 0xaaaaabfa6a40 WARN                basesink gstbasesink.c:1209:gst_base_sink_query_latency:<sink> warning: Pipeline construction is invalid, please add queues.
0:00:01.302554528 30006 0xaaaaabfa6a40 WARN                basesink gstbasesink.c:1209:gst_base_sink_query_latency:<sink> warning: Not enough buffering available for  the processing deadline of 0:00:00.015000000, add enough queues to buffer  0:00:00.015000000 additional data. Shortening processing latency to 0:00:00.000000000.
0:00:02.090361216 30006 0xaaaaabfa6060 WARN                basesink gstbasesink.c:3003:gst_base_sink_is_too_late:<sink> warning: A lot of buffers are being dropped.
0:00:02.090446560 30006 0xaaaaabfa6060 WARN                basesink gstbasesink.c:3003:gst_base_sink_is_too_late:<sink> warning: There may be a timestamping problem, or this computer is too slow.

  1. Another issue is adding caps. I’ve been trying to define them in a following way:
m_caps = gst_caps_new_simple(
        "video/x-raw",
        "format", G_TYPE_STRING, "NV12",
        "framerate", GST_TYPE_FRACTION, 60, 1,
        "width", G_TYPE_INT, 1280,
        "height", G_TYPE_INT, 720,
        NULL
    );
GstElement* capsfilter = gst_element_factory_make("capsfilter", "filter");
    if (!capsfilter) {
        g_printerr("Capsfilter element could not be created. Exiting.\n");
        return;
    }
    g_object_set(G_OBJECT(capsfilter), "caps", m_caps, NULL);

where: GstCaps* m_caps;
But later in the code after adding elements to the bin I cannot link capsfilter to trasform element:

    gst_bin_add(GST_BIN(m_pipeline), m_source);
    gst_bin_add(GST_BIN(m_pipeline), m_convert);
    gst_bin_add(GST_BIN(m_pipeline), capsfilter);
    gst_bin_add(GST_BIN(m_pipeline), m_transform);
    gst_bin_add(GST_BIN(m_pipeline), m_sink);

    if (!gst_element_link(m_source, m_convert)) {
        g_printerr("Could not link source to convert. Exiting.\n");
        return;
    }
 
   
    if (!gst_element_link_filtered(m_convert, capsfilter, m_caps)) {
        g_printerr("Could not link convert to capsfilter. Exiting.\n");
        return;
    }

    if (!gst_element_link(capsfilter, m_transform)) {
        g_printerr("Could not link capsfilter to transform. Exiting.\n");
        return;
    }
    
    if (!gst_element_link(m_transform, m_sink)) {
        g_printerr("Could not link transform to sink. Exiting.\n");
        return;
    }

I know I could add to bin many and do similar with linking but for the debugging purposes I chose to do it like that.

  1. If I try to define caps as in the point 2 with "video/x-raw(memory:NVMM)" I can’t because there is an error regarding brackets but I can do it with:
m_caps = gst_caps_from_string(
        "video/x-raw(memory:NVMM),"
        "format=NV12,"
        "framerate=60/1,"
        "width=1280,"
        "height=720"
    );

However I’m getting warnings:

0:00:00.957422848 30857 0xaaaadb89f640 WARN                basesink gstbasesink.c:1209:gst_base_sink_query_latency:<sink> warning: Pipeline construction is invalid, please add queues.
0:00:00.957580832 30857 0xaaaadb89f640 WARN                basesink gstbasesink.c:1209:gst_base_sink_query_latency:<sink> warning: Not enough buffering available for  the processing deadline of 0:00:00.015000000, add enough queues to buffer  0:00:00.015000000 additional data. Shortening processing latency to 0:00:00.000000000.

Overall the pipeline should look like this:

nvarguscamerasrc sensor-id=0 ! video/x-raw(memory:NVMM),width=1280, height=720, framerate=60/1, format=NV12 ! nvvidconv ! nvegltransform ! nveglglessink

And it works fine, if I define it inside a code with: gst_parse_launch()

The whole part of the code that creates the issue looks like that (sorry for a lot of garbage but I was trying different options):

void GstGStreamer::run() {
    m_loop = g_main_loop_new(NULL, FALSE);

    // Start the pipeline in the loop
    startPipeline();
    g_main_loop_run(m_loop);

    // Free resources after the loop returns
    g_main_loop_unref(m_loop);
}

void GstGStreamer::startPipeline() {
    m_pipeline = gst_pipeline_new("GStreamer Pipeline");

    // Define the source and choose the senor
    m_source = gst_element_factory_make("nvarguscamerasrc", "source");
    //g_object_set(G_OBJECT(m_source), "sensor-id", G_TYPE_INT, 0, NULL);
    //g_object_set(G_OBJECT(m_source), "sensor-mode", G_TYPE_INT, 4, NULL);

    // Definition of the rest pipeline's elements
    m_convert = gst_element_factory_make("nvvidconv", "convert");
    m_transform = gst_element_factory_make("nvegltransform", "transform");
    m_sink = gst_element_factory_make("nveglglessink", "sink");
    
    m_caps = gst_caps_new_simple(
        "video/x-raw",
        "format", G_TYPE_STRING, "NV12",
        "framerate", GST_TYPE_FRACTION, 60, 1,
        "width", G_TYPE_INT, 1280,
        "height", G_TYPE_INT, 720,
        NULL
    );
    

    if (!m_pipeline || !m_source || !m_convert || !m_transform || !m_sink || !m_caps) {
        g_printerr("One or more elements could not be created. Exiting.\n");
        return;
    }

    // Create capsfilter element to apply the caps
    
    GstElement* capsfilter = gst_element_factory_make("capsfilter", "filter");
    if (!capsfilter) {
        g_printerr("Capsfilter element could not be created. Exiting.\n");
        return;
    }
    g_object_set(G_OBJECT(capsfilter), "caps", m_caps, NULL);
    
    // gst_bin_add_many(GST_BIN(m_pipeline), m_source, m_convert, capsfilter, m_transform, m_sink, nullptr);

    gst_bin_add(GST_BIN(m_pipeline), m_source);
    gst_bin_add(GST_BIN(m_pipeline), m_convert);
    gst_bin_add(GST_BIN(m_pipeline), capsfilter);
    gst_bin_add(GST_BIN(m_pipeline), m_transform);
    gst_bin_add(GST_BIN(m_pipeline), m_sink);

    if (!gst_element_link(m_source, m_convert)) {
        g_printerr("Could not link source to convert. Exiting.\n");
        return;
    }
    /*
    if (!gst_element_link(m_convert, m_transform)) {
        g_printerr("Could not link source to convert. Exiting.\n");
        return;
    }
    */
    
    if (!gst_element_link_filtered(m_convert, capsfilter, m_caps)) {
        g_printerr("Could not link convert to capsfilter. Exiting.\n");
        return;
    }

    if (!gst_element_link(capsfilter, m_transform)) {
        g_printerr("Could not link capsfilter to transform. Exiting.\n");
        return;
    }
    
    if (!gst_element_link(m_transform, m_sink)) {
        g_printerr("Could not link transform to sink. Exiting.\n");
        return;
    }

    GstBus* bus = gst_element_get_bus(m_pipeline);
    gst_bus_add_watch(bus, &GstGStreamer::onBusMessageStatic, this);
    gst_object_unref(bus);

    gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
}

Please get the source of nvgstcapture-1.0 for your reference.

Thanks

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.