glimagesink: 1.18.1 deadlock in gst_gl_window_resize
Since the upgrade to gstreamer version 1.18.1 from 1.16.3 we were not able to get the feed displayed.
We're testing with dispmanx on RPI using the legacy drivers.
The simplified pipeline is as follows:
gst-launch-1.0 v4l2src ! video/x-raw,height=240,width=320,format=YUY2 ! videoconvert ! glupload ! glcolorconvert ! glimagesink render-rectangle="<0,0,1920,1080>"
which won't pass beyond Setting pipeline to PAUSED ...
. When digging more into the issue using gdb, the following backtrace shows that the pipeline is blocked on g_cond_wait
inside the function gst_gl_window_resize
.
Backtrace:
Thread 1 (Thread 0x76f33d90 (LWP 2472)):
#0 0x76bd1aec in syscall () from /lib/arm-linux-gnueabihf/libc.so.6
#1 0x76d6f908 in g_cond_wait () from /lib/arm-linux-gnueabihf/libglib-2.0.so.0
#2 0x75ddab58 in gst_gl_window_default_send_message (window=0xa48020 [GstGLWindow|glwindowdispmanxegl0], callback=<optimized out>,
data=<optimized out>) at ../gst-libs/gst/gl/gstglwindow.c:638
#3 0x75ddb518 in gst_gl_window_resize (window=window@entry=0xa48020 [GstGLWindow|glwindowdispmanxegl0], width=width@entry=1920,
height=height@entry=1080) at ../gst-libs/gst/gl/gstglwindow.c:1090
#4 0x75ddfb9c in window_resize (window_egl=window_egl@entry=0xa48020 [GstGLWindowDispmanxEGL|glwindowdispmanxegl0],
width=width@entry=1920, height=1080, height@entry=10780704, visible=visible@entry=1)
at ../gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.c:282
#5 0x75ddfc58 in gst_gl_window_dispmanx_egl_set_render_rectangle (window=window@entry=0xa48020 [GstGLWindow|glwindowdispmanxegl0],
x=x@entry=0, y=y@entry=0, width=width@entry=1920, height=height@entry=1080)
at ../gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.c:299
#6 0x75ddb3dc in gst_gl_window_set_render_rectangle (window=window@entry=0xa48020 [GstGLWindow|glwindowdispmanxegl0], x=0, y=0,
width=1920, height=1080) at ../gst-libs/gst/gl/gstglwindow.c:1020
#7 0x75b581c0 in _ensure_gl_setup (gl_sink=gl_sink@entry=0xa32868 [GstGLImageSink|sink]) at ../ext/gl/gstglimagesink.c:1047
#8 0x75b59b00 in gst_glimage_sink_change_state (element=0xa32868 [GstElement|sink], transition=GST_STATE_CHANGE_NULL_TO_READY)
at ../ext/gl/gstglimagesink.c:1209
#9 0x76e45c2c in gst_element_change_state (element=element@entry=0xa32868 [GstElement|sink],
transition=transition@entry=GST_STATE_CHANGE_NULL_TO_READY) at ../gst/gstelement.c:3046
#10 0x76e46424 in gst_element_set_state_func (element=0xa32868 [GstElement|sink], state=<optimized out>) at ../gst/gstelement.c:3000
#11 0x76e1e348 in gst_bin_element_set_state (next=<optimized out>, current=<optimized out>,
start_time=8570631565862764546 [2380730:59:25.862764546], base_time=45951202265008672 [12764:13:22.265008672],
element=0xa32868 [GstElement|sink], bin=<optimized out>) at ../gst/gstbin.c:2615
--Type <RET> for more, q to quit, c to continue without paging--
#12 gst_bin_change_state_func (element=0xa2d058 [GstElement|glimagesinkbin0], transition=0) at ../gst/gstbin.c:2957
#13 0x76e45c2c in gst_element_change_state (element=element@entry=0xa2d058 [GstElement|glimagesinkbin0],
transition=transition@entry=GST_STATE_CHANGE_NULL_TO_READY) at ../gst/gstelement.c:3046
#14 0x76e46424 in gst_element_set_state_func (element=0xa2d058 [GstElement|glimagesinkbin0], state=<optimized out>)
at ../gst/gstelement.c:3000
#15 0x76e1e348 in gst_bin_element_set_state (next=<optimized out>, current=<optimized out>,
start_time=8570631565862764546 [2380730:59:25.862764546], base_time=45950789948015616 [12764:06:29.948015616],
element=0xa2d058 [GstElement|glimagesinkbin0], bin=<optimized out>) at ../gst/gstbin.c:2615
#16 gst_bin_change_state_func (element=0xa3e0a0 [GstElement|pipeline0], transition=0) at ../gst/gstbin.c:2957
#17 0x76e779c8 in gst_pipeline_change_state (element=0xa3e0a0 [GstElement|pipeline0], transition=GST_STATE_CHANGE_NULL_TO_READY)
at ../gst/gstpipeline.c:525
#18 0x76e45c2c in gst_element_change_state (element=element@entry=0xa3e0a0 [GstElement|pipeline0],
transition=transition@entry=GST_STATE_CHANGE_NULL_TO_READY) at ../gst/gstelement.c:3046
#19 0x76e46424 in gst_element_set_state_func (element=0xa3e0a0 [GstElement|pipeline0], state=<optimized out>) at ../gst/gstelement.c:3000
#20 0x00012ed0 in main (argc=<optimized out>, argv=<optimized out>) at ../tools/gst-launch.c:1204
(gdb)
In addition testing the pipeline without the render-rectangle="<...>"
works perfectly:
gst-launch-1.0 v4l2src ! video/x-raw,height=240,width=320,format=YUY2 ! videoconvert ! glupload ! glcolorconvert ! glimagesink
0:00:00.004485275 2528 0x1630e80 WARN GST_PERFORMANCE gstbuffer.c:496:_priv_gst_buffer_initialize: No 64-bit atomic int defined for this platform/toolchain!
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Got context from element 'sink': gst.gl.GLDisplay=context, gst.gl.GLDisplay=(GstGLDisplay)"\(GstGLDisplayEGL\)\ gldisplayegl0";
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
0:00:00.291148146 2528 0x175ba00 WARN v4l2 gstv4l2object.c:3591:gst_v4l2_object_set_format_full:<v4l2src0:src> Unknown colorimetry transfer 16
0:00:00.717517770 2528 0x1677060 FIXME glslstage gstglslstage.c:530:_compile_shader:<glslstage0> vertex shader info log:Compiled
0:00:00.718994737 2528 0x1677060 FIXME glslstage gstglslstage.c:530:_compile_shader:<glslstage1> fragment shader info log:Compiled
0:00:00.755198862 2528 0x1677060 FIXME glslstage gstglslstage.c:530:_compile_shader:<glslstage2> vertex shader info log:Compiled
0:00:00.755929689 2528 0x1677060 FIXME glslstage gstglslstage.c:530:_compile_shader:<glslstage3> fragment shader info log:Compiled
0:00:00.768795467 2528 0x1677060 FIXME glslstage gstglslstage.c:530:_compile_shader:<glslstage4> vertex shader info log:Compiled
0:00:00.769507805 2528 0x1677060 FIXME glslstage gstglslstage.c:530:_compile_shader:<glslstage5> fragment shader info log:Compiled
^Chandling interrupt. ------> ctrl^c
Interrupt: Stopping pipeline ...
Execution ended after 0:00:02.470928728
Setting pipeline to NULL ...
Freeing pipeline ...
We found that the problem was introduced by commit b887db1e which moves locks and could possible introduce a deadlock from the gstreamer thread with itself.
Reverting this commit prevents the deadlock and is able to display my webcamfeed to the display:
gst-launch-1.0 v4l2src ! video/x-raw,height=240,width=320,format=YUY2 ! videoconvert ! glupload ! glcolorconvert ! glimagesink render-rectangle="<0,0,1920,1080>"
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Got context from element 'sink': gst.gl.GLDisplay=context, gst.gl.GLDisplay=(GstGLDisplay)"\(GstGLDisplayEGL\)\ gldisplayegl0";
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
^Chandling interrupt.
Interrupt: Stopping pipeline ...
Execution ended after 0:00:06.054823633
Setting pipeline to NULL ...
Freeing pipeline ...