Assert when display is unavailable in vaapisink when query the caps.
Some failure pipeline like: gst-launch-1.0 -f -e -vvv filesrc location=~/hevc_scc/some_scc_file ! h265parse ! vaapih265dec ! vaapisink
get a assert:
GStreamer-CRITICAL **: 14:56:34.226: gst_object_ref: assertion 'object != NULL' failed
gstvaapidisplay.c:1666:gst_vaapi_display_get_image_formats: assertion failed: (display != NULL)
This is failure pipeline because I forget to add the SCC support, so it fails soon with:
0:00:00.025003782 30167 0x564a637fa4a0 WARN baseparse gstbaseparse.c:3712:gst_base_parse_loop:<h265parse0> error: streaming stopped, reason not-negotiated (-4)
I core dump it and log is:
(gdb) i thread
Id Target Id Frame
* 1 Thread 0x7f197e67e700 (LWP 30168) __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
2 Thread 0x7f19827e53c0 (LWP 30167) __lll_lock_wait (futex=futex@entry=0x564a638c8ad0, private=0) at lowlevellock.c:52
3 Thread 0x7f197de7d700 (LWP 30169) 0x00007f1982ad6c2f in __GI___poll (fds=0x564a638aa870, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
(gdb) bt
#0 0x00007f1982a073eb in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007f19829e6899 in __GI_abort () at abort.c:79
#2 0x00007f1982c4fb23 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3 0x00007f1982cac39f in g_assertion_message_expr () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4 0x00007f1981b68f01 in gst_vaapi_display_get_image_formats (display=display@entry=0x0 [GstVaapiDisplay]) at ../gst-libs/gst/vaapi/gstvaapidisplay.c:1666
#5 0x00007f1981b2cdf9 in ensure_allowed_raw_caps (plugin=plugin@entry=0x564a63974600, format=format@entry=GST_VIDEO_FORMAT_UNKNOWN, direction=direction@entry=GST_PAD_SINK)
at ../gst/vaapi/gstvaapipluginbase.c:1500
#6 0x00007f1981b2ec07 in ensure_allowed_raw_caps (direction=GST_PAD_SINK, format=GST_VIDEO_FORMAT_UNKNOWN, plugin=0x564a63974600) at ../gst/vaapi/gstvaapipluginbase.c:1536
#7 0x00007f1981b2ec07 in gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (plugin=plugin@entry=0x564a63974600) at ../gst/vaapi/gstvaapipluginbase.c:1536
#8 0x00007f1981b3a2f4 in gst_vaapisink_get_caps_impl (base_sink=0x564a63974600 [GstBaseSink|vaapisink0]) at ../gst/vaapi/gstvaapisink.c:1296
#9 0x00007f1981b3a2f4 in gst_vaapisink_get_caps (base_sink=0x564a63974600 [GstBaseSink|vaapisink0], filter=0x564a637fa5e0) at ../gst/vaapi/gstvaapisink.c:1319
#10 0x00007f1981ea93ac in gst_base_sink_query_caps (bsink=bsink@entry=0x564a63974600 [GstBaseSink|vaapisink0], pad=<optimized out>, filter=0x564a637fa5e0) at ../libs/gst/base/gstbasesink.c:637
#11 0x00007f1981eb471f in gst_base_sink_default_query (basesink=0x564a63974600 [GstBaseSink|vaapisink0], query=0x564a637fa720) at ../libs/gst/base/gstbasesink.c:5575
#12 0x00007f1982def3a8 in gst_pad_query (pad=pad@entry=0x564a63850ca0 [GstPad|sink], query=query@entry=0x564a637fa720) at ../gst/gstpad.c:4144
#13 0x00007f1982defbbb in gst_pad_peer_query (pad=pad@entry=0x564a63850a50 [GstPad|src], query=query@entry=0x564a637fa720) at ../gst/gstpad.c:4276
#14 0x00007f1982e32ed0 in gst_pad_peer_query_caps (pad=pad@entry=0x564a63850a50 [GstPad|src], filter=filter@entry=0x564a637fa5e0) at ../gst/gstutils.c:3152
#15 0x00007f1981d111d9 in __gst_video_element_proxy_getcaps
(element=element@entry=0x564a63979690 [GstElement|vaapidecode_h265-0], sinkpad=<optimized out>, srcpad=0x564a63850a50 [GstPad|src], initial_caps=initial_caps@entry=0x7f1978001a30, filter=filter@entry=0x7f1978001a80) at ../gst-libs/gst/video/gstvideoutilsprivate.c:108
#16 0x00007f1981cfdf1d in gst_video_decoder_proxy_getcaps (decoder=decoder@entry=0x564a63979690 [GstVideoDecoder|vaapidecode_h265-0], caps=caps@entry=0x7f1978001a30, filter=filter@entry=0x7f1978001a80)
at ../gst-libs/gst/video/gstvideodecoder.c:1835
#17 0x00007f1981b27cd3 in gst_vaapidecode_sink_getcaps (vdec=<optimized out>, filter=0x7f1978001a80) at ../gst/vaapi/gstvaapidecode.c:1355
#18 0x00007f1981cfdfee in gst_video_decoder_sink_getcaps (filter=<optimized out>, decoder=0x564a63979690 [GstVideoDecoder|vaapidecode_h265-0]) at ../gst-libs/gst/video/gstvideodecoder.c:1849
#19 0x00007f1981cfdfee in gst_video_decoder_sink_query_default (decoder=0x564a63979690 [GstVideoDecoder|vaapidecode_h265-0], query=0x7f1978001800) at ../gst-libs/gst/video/gstvideodecoder.c:1898
#20 0x00007f1982def3a8 in gst_pad_query (pad=pad@entry=0x564a63850800 [GstPad|sink], query=query@entry=0x7f1978001800) at ../gst/gstpad.c:4144
#21 0x00007f1982e303f0 in gst_pad_query_caps (pad=0x564a63850800 [GstPad|sink], filter=0x7f1978001a80) at ../gst/gstutils.c:3106
#22 0x00007f1981cfe2c1 in gst_video_decoder_sink_query_default (decoder=0x564a63979690 [GstVideoDecoder|vaapidecode_h265-0], query=0x564a637fa770) at ../gst-libs/gst/video/gstvideodecoder.c:1922
#23 0x00007f1982def3a8 in gst_pad_query (pad=pad@entry=0x564a63850800 [GstPad|sink], query=query@entry=0x564a637fa770) at ../gst/gstpad.c:4144
#24 0x00007f1982e330d8 in gst_pad_query_accept_caps (pad=pad@entry=0x564a63850800 [GstPad|sink], caps=<optimized out>) at ../gst/gstutils.c:3189
#25 0x00007f1982de7222 in pre_eventfunc_check (event=0x564a638f4250, pad=0x564a63850800 [GstPad|sink]) at ../gst/gstpad.c:5689
#26 0x00007f1982de7222 in gst_pad_send_event_unchecked (pad=pad@entry=0x564a63850800 [GstPad|sink], event=event@entry=0x564a638f4250, type=<optimized out>, type@entry=GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM)
at ../gst/gstpad.c:5835
#27 0x00007f1982de78f7 in gst_pad_push_event_unchecked (pad=pad@entry=0x564a638505b0 [GstPad|src], event=0x564a638f4250, type=<optimized out>, type@entry=GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM)
at ../gst/gstpad.c:5488
#28 0x00007f1982de7ec8 in push_sticky (pad=0x564a638505b0 [GstPad|src], ev=0x7f197e67dc60, user_data=0x7f197e67dcd0) at ../gst/gstevent.h:451
#29 0x00007f1982de52d0 in events_foreach (pad=pad@entry=0x564a638505b0 [GstPad|src], func=func@entry=0x7f1982de8200 <sticky_changed>, user_data=user_data@entry=0x7f197e67dcd0) at ../gst/gstpad.c:608
#30 0x00007f1982de7c42 in gst_pad_push_event_unchecked (pad=pad@entry=0x564a638505b0 [GstPad|src], event=0x564a638f4330, type=type@entry=GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) at ../gst/gstpad.c:5464
#31 0x00007f1982df1e4d in check_sticky (event=0x564a638f4330, pad=0x564a638505b0 [GstPad|src]) at ../gst/gstevent.h:451
#32 0x00007f1982df1e4d in gst_pad_push_event (pad=0x564a638505b0 [GstPad|src], event=event@entry=0x564a638f4330) at ../gst/gstpad.c:5619
#33 0x00007f1981ea1593 in gst_base_parse_loop (pad=<optimized out>) at ../libs/gst/base/gstbaseparse.c:3728
#34 0x00007f1982e232ff in gst_task_func (task=0x564a63854290 [GstTask|h265parse0:sink]) at ../gst/gsttask.c:328
#35 0x00007f1982cad8c4 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#36 0x00007f1982cad181 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#37 0x00007f1982bbb669 in start_thread (arg=<optimized out>) at pthread_create.c:479
#38 0x00007f1982ae3323 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) t 2
[Switching to thread 2 (Thread 0x7f19827e53c0 (LWP 30167))]
#0 __lll_lock_wait (futex=futex@entry=0x564a638c8ad0, private=0) at lowlevellock.c:52
52 lowlevellock.c: No such file or directory.
(gdb) bt
#0 0x00007f1982bc60b0 in __lll_lock_wait (futex=futex@entry=0x564a638c8ad0, private=0) at lowlevellock.c:52
#1 0x00007f1982bbe1f1 in __GI___pthread_mutex_lock (mutex=0x564a638c8ad0) at ../nptl/pthread_mutex_lock.c:115
#2 0x00007f1982dec732 in post_activate (new_mode=GST_PAD_MODE_NONE, pad=0x564a63850800 [GstPad|sink]) at ../gst/gstpad.c:1046
#3 0x00007f1982dec732 in activate_mode_internal
(pad=pad@entry=0x564a63850800 [GstPad|sink], parent=parent@entry=0x564a63979690 [GstObject|vaapidecode_h265-0], mode=mode@entry=GST_PAD_MODE_PUSH, active=active@entry=0) at ../gst/gstpad.c:1224
#4 0x00007f1982ded0b9 in gst_pad_set_active (pad=pad@entry=0x564a63850800 [GstPad|sink], active=0) at ../gst/gstpad.c:1115
#5 0x00007f1982dc52a5 in activate_pads (vpad=<optimized out>, ret=0x7ffc92383c90, active=0x7ffc92383cec) at ../gst/gstelement.c:3121
#6 0x00007f1982ddb7bc in gst_iterator_fold (it=it@entry=0x564a63734db0, func=func@entry=0x7f1982dc5280 <activate_pads>, ret=ret@entry=0x7ffc92383c90, user_data=user_data@entry=0x7ffc92383cec)
at ../gst/gstiterator.c:617
#7 0x00007f1982dc5d16 in iterator_activate_fold_with_resync (iter=iter@entry=0x564a63734db0, user_data=user_data@entry=0x7ffc92383cec, func=0x7f1982dc5280 <activate_pads>) at ../gst/gstelement.c:3145
#8 0x00007f1982dc8136 in gst_element_pads_activate (element=element@entry=0x564a63979690 [GstElement|vaapidecode_h265-0], active=<optimized out>, active@entry=0) at ../gst/gstelement.c:3189
#9 0x00007f1982dc8491 in gst_element_change_state_func (element=0x564a63979690 [GstElement|vaapidecode_h265-0], transition=<optimized out>) at ../gst/gstelement.c:3255
#10 0x00007f1981cfd68f in gst_video_decoder_change_state (element=0x564a63979690 [GstElement|vaapidecode_h265-0], transition=GST_STATE_CHANGE_PAUSED_TO_READY)
at ../gst-libs/gst/video/gstvideodecoder.c:2602
#11 0x00007f1982dca8b2 in gst_element_change_state (element=element@entry=0x564a63979690 [GstElement|vaapidecode_h265-0], transition=transition@entry=GST_STATE_CHANGE_PAUSED_TO_READY)
at ../gst/gstelement.c:3033
#12 0x00007f1982dcaefd in gst_element_set_state_func (element=0x564a63979690 [GstElement|vaapidecode_h265-0], state=GST_STATE_NULL) at ../gst/gstelement.c:2987
#13 0x00007f1982da5a0c in gst_bin_element_set_state
(next=GST_STATE_NULL, current=GST_STATE_READY, start_time=0 [0:00:00.000000000], base_time=0 [0:00:00.000000000], element=0x564a63979690 [GstElement|vaapidecode_h265-0], bin=0x564a6386e1a0 [GstBin|pipe
line0]) at ../gst/gstbin.c:2615
#14 0x00007f1982da5a0c in gst_bin_change_state_func (element=0x564a6386e1a0 [GstElement|pipeline0], transition=GST_STATE_CHANGE_READY_TO_NULL) at ../gst/gstbin.c:2957
#15 0x00007f1982df571f in gst_pipeline_change_state (element=0x564a6386e1a0 [GstElement|pipeline0], transition=GST_STATE_CHANGE_READY_TO_NULL) at ../gst/gstpipeline.c:525
#16 0x00007f1982dca8b2 in gst_element_change_state (element=element@entry=0x564a6386e1a0 [GstElement|pipeline0], transition=transition@entry=GST_STATE_CHANGE_READY_TO_NULL) at ../gst/gstelement.c:3033
#17 0x00007f1982dcaefd in gst_element_set_state_func (element=0x564a6386e1a0 [GstElement|pipeline0], state=GST_STATE_NULL) at ../gst/gstelement.c:2987
#18 0x0000564a6254d944 in main (argc=<optimized out>, argv=<optimized out>) at ../tools/gst-launch.c:1278
(gdb)
And I add a print:
0:00:00.025172307 30167 0x564a637f7d50 ERROR vaapisink gstvaapipluginbase.c:358:gst_vaapi_plugin_base_close: Replaced display 0x564a63836a80 to NULL
So the reason is thread race condition.
The sink element is already in NULL state and releases the display, but the filesrc still query sink's caps, while the display has already gone.
I notice:
static GstCaps *
gst_vaapisink_get_caps_impl (GstBaseSink * base_sink)
{
....
if (!GST_VAAPI_PLUGIN_BASE_DISPLAY (sink))
return gst_static_pad_template_get_caps (&gst_vaapisink_sink_factory);
out_caps = gst_caps_from_string (surface_caps_str);
raw_caps =
gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps (GST_VAAPI_PLUGIN_BASE
(sink));
...
}
There, just check the display, but display may be disposed during the period of calling gst_vaapi_plugin_base_get_allowed_sinkpad_raw_caps.