Framerate issue with v4l2sink
Nicolas Dufresne
nicolas at ndufresne.ca
Tue Mar 24 20:24:49 UTC 2020
Le mardi 24 mars 2020 à 18:10 +0000, Lenz, Mika a écrit :
> We are streaming data from appsrc into a v4l2sink. Therefore, we are
> using v4l2loopback on /dev/videoX. The camera has a fix resolution of
> 640x480 and a variable framerate. The framerate is set up at the
> beginning with a library provided by the manufacturer. The data is 16
> Bit Gray LE.
>
> The problem is, that Gstreamer always wants to put 33 frame per
> second into the sink. So, if we choose 60fps, it’s 33fps and if we
> choose 30fps, it isn’t working. Every value bigger than 33fps is
> working, but only 33fps in real and every value lower than 33 fps is
> not working at all.
>
> Before this, we already set the framerate and pushed data into a
> multifilesink or a udpsink with correct frame rate at the end. So,
> the initialization should not be the problem. Is there anything
> special to remind working with v42sink and v4l2loopback?
Appart that v4l2loopback driver should be rewritten from scratch in
order to make it work properly, no.
On a more serious note, what GStreamer does is list the frame interval
advertise by your driver. So if 33fps is the only thing you manage to
get to negotiate with v4l2sink/v4l2loopback, I'd first analyze the
driver. This driver have had issues from over a decade, including
buffer overflow and all the things you don't want in your product. So I
wouldn't be surprise if more bugs exist in regard to frame interval
handling.
>
> This is from our application, I removed error checks etc:
>
> cb_need_data (GstElement *appsrc,
> guint unused_size,
> gpointer user_data)
> {
> static GstClockTime timestamp = 0;
> GstBuffer *buffer;
> GstFlowReturn ret;
>
> GstMapInfo map;
> eDALProxy640USBErr eReturnCode;
>
> buffer = gst_buffer_new_and_alloc(IRIMAGE_NBPIXELS*2); //allocate 2
> Bytes for every pixel
> if(gst_buffer_map (buffer, &map, GST_MAP_WRITE)) {
> while(true)
> {
> eReturnCode = Proxy640USB_GetImage(m_Handle, (short
> unsigned int*)map.data, paMeta, GETIMAGE_TIMEOUT);
> if (eReturnCode == eProxy640USBSuccess)
> break;
> }
> }
>
> GST_BUFFER_PTS (buffer) = timestamp;
> GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (1,
> GST_SECOND, 33);
>
> timestamp += GST_BUFFER_DURATION (buffer);
> g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
> gst_buffer_unmap(buffer, &map);
> gst_buffer_unref(buffer);
> }
>
>
> gint main (gint argc, gchar *argv[])
> {
> sprintf(DEVICE, "/dev/video0");
> // GStreamer
> GstElement *pipeline, *converter, *videosink, *videosrc, *appsrc;
> gst_init (&argc, &argv);
> loop = g_main_loop_new (NULL, FALSE);
>
> // LWIR device
> m_Handle = NULL;
> eAGCProcessingValue agcVal = eAGCEnhanced;
> eDALProxy640USBErr eReturnCode;
> eReturnCode = Proxy640USB_GetModuleCount(&iCount);
>
> // Connect to LWIR
> eReturnCode = Proxy640USB_ConnectToModule(0, &m_Handle);
>
> // Set Processing depending of parameters
> (NUC/AGC/Shutterless/Framerate)
> Proxy640USB_SetNUCProcessing(m_Handle, bBP, nuc);
> Proxy640USB_SetShutterLessProcessing(m_Handle, bSL);
> Proxy640USB_SetFloatFeature(m_Handle, efFrameRate, FRAMERATE);
> Proxy640USB_SetAGCProcessing(m_Handle, agcVal);
> Proxy640USB_SetUIntFeature(m_Handle, eiVideoUSBOutActivation, 1);
>
> // Setup Pipeline
> pipeline = gst_pipeline_new ("LWIR-streamer");
> appsrc = gst_element_factory_make ("appsrc", "source");
> videosrc = gst_element_factory_make("videotestsrc", "source");
> converter = gst_element_factory_make ("videoconvert", "converter");
> videosink = gst_element_factory_make ("v4l2sink", "videosink");
> g_object_set (videosink, "device", DEVICE, NULL);
>
> // Setting Capabilities
> g_object_set (G_OBJECT (appsrc), "caps",
> gst_caps_new_simple ("video/x-raw",
> "format", G_TYPE_STRING, "GRAY16_LE",
> "width", G_TYPE_INT, IRIMAGE_WIDTH,
> "height", G_TYPE_INT, IRIMAGE_HEIGHT,
> "framerate", GST_TYPE_FRACTION, FRAMERATE, 1,
> NULL), NULL);
>
> gst_bin_add_many (GST_BIN (pipeline), appsrc, converter,
> videosink,NULL);
> gst_element_link_many (appsrc, converter, videosink, NULL);
>
> // Setup appsrc to cd_need_data
> g_object_set (G_OBJECT (appsrc),
> "stream-type", 0,
> "format", GST_FORMAT_TIME, NULL);
> g_signal_connect (appsrc, "need-data", G_CALLBACK (cb_need_data),
> NULL);
>
> /* play */
> gst_element_set_state (pipeline, GST_STATE_PLAYING);
> g_main_loop_run (loop);
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
More information about the gstreamer-devel
mailing list