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.
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.
User contributions licensed under CC BY-SA 3.0