Hello,
I’m trying to write a programmatically defined GStreamer pipeline that uses nvarguscamerasrc. I’m facing several problems with that:
- 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.
- 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.
- 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);
}