Hi,
i’m trying to build an app starting from deepstream-test-2.
I would like my application to input a video stream coming from a USB camera. but I get this error:
ERROR from element src_elem: Internal data stream error.
Error details: gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:dstest2-pipeline/GstBin:source-bin-00/GstV4l2Src:src_elem:
streaming stopped, reason not-negotiated (-4)
And at the beginning i got this warning:
GStreamer-WARNING **: 13:05:53.362: Name 'src_cap_filter' is not unique in bin 'source-bin-00', not adding
I can’t understand what I’m wrong.
To create camera_source_bin I use the following function:
static GstElement *
create_camera_source_bin (guint index, gchar * uri)
{
GstElement *bin = NULL;
GstCaps *caps = NULL;
gboolean ret = FALSE;
gchar bin_name[16] = { };
g_snprintf (bin_name, 15, "source-bin-%02d", index);
bin = gst_bin_new (bin_name);
GstElement *src_elem = gst_element_factory_make ("v4l2src", "src_elem");
if (!src_elem)
{
g_printerr ("Could not create 'src_elem'\n");
return NULL;
}
GstElement *cap_filter = gst_element_factory_make ("capsfilter", "src_cap_filter");
if (!cap_filter){
g_printerr ("Could not create 'src_cap_filter'\n");
return NULL;
}
caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "NV12",
"width", G_TYPE_INT, 480, "height", G_TYPE_INT, 640,
"framerate", GST_TYPE_FRACTION, 30, 1, NULL);
GstElement *nvvidconv1, *nvvidconv2;
GstCapsFeatures *feature = NULL;
nvvidconv1 = gst_element_factory_make ("videoconvert", "nvvidconv1");
if (!nvvidconv1){
g_printerr ("Failed to create 'nvvidcovn1'\n");
return NULL;
}
feature = gst_caps_features_new ("memory:NVMM", NULL);
gst_caps_set_features (caps, 0, feature);
g_object_set (G_OBJECT (cap_filter), "caps", caps, NULL);
nvvidconv2 = gst_element_factory_make ("nvvideoconvert", "nvvidconv2");
if (!nvvidconv2){
g_printerr ("Failed to create 'nvvidcovn2'\n");
return NULL;
}
g_object_set (G_OBJECT (nvvidconv2), "gpu-id", 0, NULL);
gst_bin_add_many (GST_BIN (bin), src_elem, cap_filter, nvvidconv1, nvvidconv2, cap_filter, NULL);
//NVGSTDS_LINK_ELEMENT (src_elem, nvvidconv1);
//NVGSTDS_LINK_ELEMENT (nvvidconv1, nvvidconv2);
//NVGSTDS_LINK_ELEMENT (nvvidconv2, cap_filter);
if (!gst_element_link (src_elem,nvvidconv1)){
g_printerr ("Failed to link 'src_elem, nvvidcovn1'\n");
return NULL;
}
if (!gst_element_link (nvvidconv1,nvvidconv2)){
g_printerr ("Failed to link 'nvvidcovn1, nvvidcovn2'\n");
return NULL;
}
if (!gst_element_link (nvvidconv2, cap_filter)){
g_printerr ("Failed to link 'nvvidcovn2, cap_filter'\n");
return NULL;
}
// NVGSTDS_BIN_ADD_GHOST_PAD (bin, cap_filter, "src");
GstPad *gstpad = gst_element_get_static_pad (cap_filter, "src");
gst_element_add_pad (bin, gst_ghost_pad_new ("src", gstpad));
gst_object_unref(gstpad);
gchar device[64];
g_snprintf (device, sizeof (device), "/dev/video%d", 0);
g_object_set (G_OBJECT (src_elem), "device", device, NULL);
return bin;
}
And i use that function in this way:
GstPad *sinkpad, *srcpad;
gchar pad_name[16] = { };
GstElement *source_bin = create_camera_source_bin (0, argv[1]);
if (!source_bin) {
g_printerr ("Failed to create source bin. Exiting2.\n");
return -1;
}
gst_bin_add (GST_BIN (pipeline), source_bin);
g_snprintf (pad_name, 15, "sink_%u", 1);
sinkpad = gst_element_get_request_pad (streammux, pad_name);
if (!sinkpad) {
g_printerr ("Streammux request sink pad failed. Exiting3.\n");
return -1;
}
srcpad = gst_element_get_static_pad (source_bin, "src");
if (!srcpad) {
g_printerr ("Failed to get src pad of source bin. Exiting4.\n");
return -1;
}
if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK) {
g_printerr ("Failed to link source bin to stream muxer. Exiting5.\n");
return -1;
}
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
For your information, I also attach all the main function
int
main(int argc, char * argv[]) {
GMainLoop * loop = NULL;
GstElement * pipeline = NULL, * streammux = NULL, * sink = NULL, * pgie = NULL, * nvvidconv = NULL,
* nvosd = NULL, * nvtracker = NULL;
#ifdef PLATFORM_TEGRA
GstElement * transform = NULL;
#endif
GstBus * bus = NULL;
guint bus_watch_id = 0;
GstPad * osd_sink_pad = NULL;
/* Check input arguments */
if (argc != 2) {
g_printerr("Usage: %s <elementary H264 filename>\n", argv[0]);
return -1;
}
/* Standard GStreamer initialization */
gst_init( & argc, & argv);
loop = g_main_loop_new(NULL, FALSE);
/* Create gstreamer elements */
/* Create Pipeline element that will be a container of other elements */
pipeline = gst_pipeline_new("dstest2-pipeline");
/* Create nvstreammux instance to form batches from one or more sources. */
streammux = gst_element_factory_make("nvstreammux", "stream-muxer");
if (!pipeline || !streammux) {
g_printerr("One element could not be created. Exiting1.\n");
return -1;
}
gst_bin_add (GST_BIN (pipeline), streammux);
//AAAAAAAAAAA
GstPad *sinkpad, *srcpad;
gchar pad_name[16] = { };
GstElement *source_bin = create_camera_source_bin (0, argv[1]);
if (!source_bin) {
g_printerr ("Failed to create source bin. Exiting2.\n");
return -1;
}
gst_bin_add (GST_BIN (pipeline), source_bin);
g_snprintf (pad_name, 15, "sink_%u", 1);
sinkpad = gst_element_get_request_pad (streammux, pad_name);
if (!sinkpad) {
g_printerr ("Streammux request sink pad failed. Exiting3.\n");
return -1;
}
srcpad = gst_element_get_static_pad (source_bin, "src");
if (!srcpad) {
g_printerr ("Failed to get src pad of source bin. Exiting4.\n");
return -1;
}
if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK) {
g_printerr ("Failed to link source bin to stream muxer. Exiting5.\n");
return -1;
}
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
//AAAAAAAAAAA
/* Use nvinfer to run inferencing on decoder's output,
* behaviour of inferencing is set through config file */
pgie = gst_element_factory_make("nvinfer", "primary-nvinference-engine");
/* We need to have a tracker to track the identified objects */
nvtracker = gst_element_factory_make("nvtracker", "tracker");
g_print("TRACKER ATTIVO!!!\n");
/* Use convertor to convert from NV12 to RGBA as required by nvosd */
nvvidconv = gst_element_factory_make("nvvideoconvert", "nvvideo-converter");
/* Create OSD to draw on the converted RGBA buffer */
nvosd = gst_element_factory_make("nvdsosd", "nv-onscreendisplay");
/* Finally render the osd output */
#ifdef PLATFORM_TEGRA
transform = gst_element_factory_make("nvegltransform", "nvegl-transform");
#endif
sink = gst_element_factory_make("nveglglessink", "nvvideo-renderer");
if (!pgie ||
!nvtracker|| !nvvidconv || !nvosd || !sink) {
g_printerr("One element could not be created. Exiting.6\n");
return -1;
}
#ifdef PLATFORM_TEGRA
if (!transform) {
g_printerr("One tegra element could not be created. Exiting.7\n");
return -1;
}
#endif
/* Set the input filename to the source element */
//g_object_set(G_OBJECT(source), "location", argv[1], NULL);
g_object_set(G_OBJECT(streammux), "batch-size", 1, NULL);
g_object_set(G_OBJECT(streammux), "width", MUXER_OUTPUT_WIDTH, "height",
MUXER_OUTPUT_HEIGHT,
"batched-push-timeout", MUXER_BATCH_TIMEOUT_USEC, NULL);
/* Set all the necessary properties of the nvinfer element,
* the necessary ones are : */
g_object_set(G_OBJECT(pgie), "config-file-path", PGIE_CONFIG_FILE, NULL);
/* Set necessary properties of the tracker element. */
if (!set_tracker_properties(nvtracker)) {
g_printerr("Failed to set tracker properties. Exiting.\n");
return -1;
}
/* we add a message handler */
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);
/* Set up the pipeline */
/* we add all elements into the pipeline */
/* decoder | pgie1 | nvtracker| etc.. */
#ifdef PLATFORM_TEGRA
gst_bin_add_many(GST_BIN(pipeline),
pgie, nvtracker,
nvvidconv, nvosd, transform, sink, NULL);
#else
gst_bin_add_many(GST_BIN(pipeline),
pgie, nvtracker,
nvvidconv, nvosd, sink, NULL);
#endif
#ifdef PLATFORM_TEGRA
if (!gst_element_link_many(streammux, pgie, nvtracker,
nvvidconv, nvosd, transform, sink, NULL)) {
g_printerr("Elements could not be linked. Exiting.\n");
return -1;
}
#else
if (!gst_element_link_many(streammux, pgie, nvtracker,
nvvidconv, nvosd, sink, NULL)) {
g_printerr("Elements could not be linked. Exiting.\n");
return -1;
}
#endif
/* Lets add probe to get informed of the meta data generated, we add probe to
* the sink pad of the osd element, since by that time, the buffer would have
* had got all the metadata. */
osd_sink_pad = gst_element_get_static_pad(nvosd, "sink");
if (!osd_sink_pad)
g_print("Unable to get sink pad\n");
else
gst_pad_add_probe(osd_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
osd_sink_pad_buffer_probe, NULL, NULL);
/* Set the pipeline to "playing" state */
g_print("Now playing: %s\n", argv[1]);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
/* Iterate */
g_print("Running...\n");
g_main_loop_run(loop);
/* Out of the main loop, clean up nicely */
g_print("Returned, stopping playback\n");
gst_element_set_state(pipeline, GST_STATE_NULL);
g_print("Deleting pipeline\n");
gst_object_unref(GST_OBJECT(pipeline));
g_source_remove(bus_watch_id);
g_main_loop_unref(loop);
return 0;
}
Thanks you all