首页 > 解决方案 > 尝试流式传输视频的 libgstvideo 共享库中的段错误

问题描述

在尝试使用 Gstreamer 及其库流式传输视频时,我在将视频格式从 RGB 转换为 NV12 时遇到了 libgsvtvideo 中的以下段错误。当以 RGB 格式和 NV12 收集时,帧大小为 921600,我相信大小为 460800 字节(RGB 帧的一半)

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

我的机器上没有 libgstvideo 的源代码,因此很难调试。

我曾尝试使用debugger,但实际上我得到的只是一个没有用的堆栈,因为我似乎无法加载调试符号 -

   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

我也尝试使用valgrind来启动我的应用程序,但即使发生了段错误,valgrind 也没有发现它。

以下是在我的应用程序中使用 gstreamer 的一些相关代码 -

        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 );
            }

当我做g_signal_emit_by_name我想的时候会发生段错误。

我确实有通过设置 GST_DEBUG_FILE=6 收集的 GST 日志,这是最后几行的片段 -

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

我希望不会发生段错误并且可以流式传输帧。

标签: csegmentation-faultgdbvideo-streaminggstreamer

解决方案


我们对您的帧缓冲区数据一无所知。它来自哪里,它的寿命是多少?请注意,gst_buffer_new_wrapped函数期望内存缓冲区GstBuffer在该调用之后属于该对象。所以不允许其他人再删除/释放这个缓冲区。此外 - 预计可以通过调用来释放缓冲区free()。如果没有给出它预计会崩溃。如果您的基础设施无法做到这一点,您需要使用gst_buffer_new_allocate和复制数据。


推荐阅读