Segfault in libgstvideo shared library trying to stream video

0

While trying to stream video using Gstreamer and its libraries, I encounter the following segfault in libgsvtvideo while converting the video format from RGB to NV12. Frame size is 921600 when collected in RGB format and NV12 I believe is 460800 bytes in size (half of RGB frame)

appsource:src[5702]: segfault at 7fc560028010 ip 00007fc56bd8ee63 sp 00007fc552181428 error 4 in libgstvideo-1.0.so.0.803.0[7fc56bd7a000+7c000]

I do not have the source code for libgstvideo on my machine so that makes it hard to debug.

I have attempted to use debugger but really all I get is a stack which is of no use since I cannot seem to load the debug symbols -

   Thread 79 "appsource:src" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7efd77a3f700 (LWP 5515)]
0x00007efe455d4e63 in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
(gdb) bt
#0  0x00007efe455d4e63 in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#1  0x00007efe455dfc33 in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#2  0x00007efe455dfdba in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#3  0x00007efe455e05c4 in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#4  0x00007efe455dfdba in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#5  0x00007efe455e0d2e in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#6  0x00007efe455dfdba in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#7  0x00007efe455e005b in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#8  0x00007efe45848509 in ?? () from /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvideoconvert.so
#9  0x00007efe455ee21e in ?? () from /usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0
#10 0x00007efe48483ba5 in ?? () from /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0
#11 0x00007efe48483446 in ?? () from /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0
#12 0x00007efe496ec59f in ?? () from /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#13 0x00007efe496f4543 in gst_pad_push () from /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#14 0x00007efe4847ee55 in ?? () from /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0
#15 0x00007efe4971ef31 in ?? () from /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#16 0x00007efe487235ee in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#17 0x00007efe48722c55 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#18 0x00007efe51f776ba in start_thread (arg=0x7efd77a3f700) at pthread_create.c:333
#19 0x00007efe50a2541d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

I also attempted using valgrind to start my application but valgrind did not catch the segfault even thou it occurred.

Here is some of the relevant code that uses gstreamer in my application -

        snprintf( str_pipeline, sizeof( str_pipeline ), "appsrc name=appsource ! videoconvert ! " "video/x-raw,width=640,height=480,format=NV12,framerate=60/1 ! vaapih264enc ! h264parse ! rtph264pay ! " "udpsink host=%s port=5600", "xxx.xxx.x.x");

         pipeline = gst_parse_launch( str_pipeline, &gerror );

         if( pipeline )
         {
             appsrc = gst_bin_get_by_name( GST_BIN( pipeline ), "appsource" );
             app_caps = gst_caps_new_simple( "video/x-raw", "format", G_TYPE_STRING, "RGB", "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 480, "framerate", GST_TYPE_FRACTION, 60, 1, NULL );

             gst_app_src_set_caps( GST_APP_SRC( appsrc ), app_caps );

             g_object_set( G_OBJECT( appsrc ), "is-live", TRUE, "format", GST_FORMAT_TIME, NULL );

  gst_element_set_state( pipeline, GST_STATE_PLAYING );

            // get frame_buffer 

            GstBuffer *gstbuffer = gst_buffer_new_wrapped_full( ( GstMemoryFlags )0, frame_buffer, SIZE, 0, SIZE, NULL, NULL );
            g_signal_emit_by_name( appsrc, "push-buffer", gstbuffer, &ret );

            if (ret != GST_FLOW_OK)
            {     
               if ( debug )
                   printf( "error sending frame to gstreamer..: %d\n", ret );
            }

segfault occurs when I do the g_signal_emit_by_name I suppose.

I do have GST logs I collected by setting GST_DEBUG_FILE=6 and here is a snippet of the last few lines -

0:00:00.727642913  5968 0x7f547c226230 DEBUG               GST_META gstmeta.c:192:gst_meta_register: register "GstVideoMeta" implementing "GstVideoMetaAPI" of size 112
0:00:00.727666988  5968 0x7f547c226230 DEBUG             GST_BUFFER gstbuffer.c:2101:gst_buffer_add_meta: alloc metadata 0x7f547c235538 (GstVideoMeta) of size 112
0:00:00.727712527  5968 0x7f547c226230 LOG                videometa gstvideometa.c:305:gst_buffer_add_video_meta_full: plane 0, offset 0, stride 640
0:00:00.727731540  5968 0x7f547c226230 LOG                videometa gstvideometa.c:305:gst_buffer_add_video_meta_full: plane 1, offset 307200, stride 640
0:00:00.727752616  5968 0x7f547c226230 DEBUG             bufferpool gstbufferpool.c:240:mark_meta_pooled:<vaapivideobufferpool0> marking meta 0x7f547c235538 as POOLED in buffer 0x7f547c264850
0:00:00.727772579  5968 0x7f547c226230 DEBUG             bufferpool gstbufferpool.c:240:mark_meta_pooled:<vaapivideobufferpool0> marking meta 0x7f53b8001a48 as POOLED in buffer 0x7f547c264850
0:00:00.727791767  5968 0x7f547c226230 LOG               bufferpool gstbufferpool.c:282:do_alloc_buffer:<vaapivideobufferpool0> allocated buffer 0/0, 0x7f547c264850
0:00:00.727822443  5968 0x7f547c226230 DEBUG          basetransform gstbasetransform.c:1795:default_copy_metadata:<videoconvert0> copying metadata
0:00:00.727853207  5968 0x7f547c226230 LOG               GST_BUFFER gstbuffer.c:443:gst_buffer_copy_into: copy 0x7f547c264740 to 0x7f547c264850, offset 0-921600/921600
0:00:00.727881908  5968 0x7f547c226230 DEBUG          basetransform gstbasetransform.c:2157:default_generate_output:<videoconvert0> using allocated buffer in 0x7f547c264740, out 0x7f547c264850
0:00:00.727901871  5968 0x7f547c226230 DEBUG          basetransform gstbasetransform.c:2177:default_generate_output:<videoconvert0> doing non-inplace transform
0:00:00.727960085  5968 0x7f547c226230 LOG               GST_BUFFER gstbuffer.c:1649:gst_buffer_map_range: buffer 0x7f547c264740, idx 0, length -1, flags 10001
0:00:00.727981611  5968 0x7f547c226230 LOG               GST_BUFFER gstbuffer.c:212:_get_merged_memory: buffer 0x7f547c264740, idx 0, length 1
0:00:00.728010700  5968 0x7f547c226230 DEBUG                  vaapi gstvaapisurface.c:370:gst_vaapi_surface_new_full: size 640x480, format NV12, flags 0x00000000
0:00:00.728086865  5968 0x7f547c226230 DEBUG                  vaapi gstvaapisurface.c:210:gst_vaapi_surface_create_full: surface 0x4000008
0:00:00.728108203  5968 0x7f547c226230 DEBUG                  vaapi gstvaapiimage.c:248:gst_vaapi_image_new: format NV12, size 640x480
0:00:00.728141391  5968 0x7f547c226230 DEBUG                  vaapi gstvaapiimage.c:201:gst_vaapi_image_create: image 0xa000000
0:00:00.728194218  5968 0x7f547c226230 DEBUG        GST_PERFORMANCE gstvideoconvert.c:690:gst_video_convert_transform_frame:<videoconvert0> doing colorspace conversion from RGB -> to NV12
0:00:00.728214781  5968 0x7f547c226230 DEBUG        video-converter video-converter.c:2805:video_converter_generic: setup progressive frame
0:00:00.728237607  5968 0x7f547c226230 DEBUG        video-converter video-converter.c:538:get_border_temp_line: get temp line 0 (0x7f53b8001800 0)
0:00:00.728256133  5968 0x7f547c226230 DEBUG        video-converter video-converter.c:2518:do_unpack_lines: unpack line 0 (0) 0x7f53b8008030

I expect no segfault to occur and the frame to be streamed.

c
segmentation-fault
gdb
video-streaming
gstreamer
asked on Stack Overflow Jul 22, 2019 by jackmack

1 Answer

0

We don't know anything about your frame buffer data. Where does it come from, what is it's lifetime? Note that gst_buffer_new_wrapped functions expect that the memory buffer belongs to the GstBuffer object after that call. So no other is allowed to delete/free this buffer anymore. Also - it is expected that the buffer can be freed via a call to free(). If that's is not given it is expected to crash. If this is not possible from your infrastructure you need to use gst_buffer_new_allocate and copy the data.

answered on Stack Overflow Jul 22, 2019 by Florian Zwoch

User contributions licensed under CC BY-SA 3.0