decklinkvideosrc gets into unrecoverable state if device is busy
If I try to use decklinkvideosrc
with a busy device (used by another app), the element ends up in unstoppable state. Transition to PLAYING is completed but then refuses to go back to PAUSED state and stays in the transition.
Reproducible
Always
Steps to reproduce the bug
- Make the Decklink capture card busy with another app which uses Decklink API, for example OBS – just open OBS and display the Blackmagic Device; or another instance of
gst-launch
- Run command like
gst-launch-1.0 decklinkvideosrc connection=hdmi ! autovideoconvert ! autovideosink
Expected Behavior
The command starts, fails and ends
Observed Behavior
The command starts, fails and keeps hanging with critical error Trying to dispose element pipeline0, but it is in PAUSED instead of the NULL state
How to fix
The reason is easy to see in the code and I think it is easy to fix. Function gst_decklink_video_src_start_streams()
doesn't offer any success/failure result, so even if starting fails, the element always assumes it is actually started. On the other way, gst_decklink_video_src_change_state()
in branch GST_STATE_CHANGE_PLAYING_TO_PAUSED
evaluates result of StopStreams()
and goes to GST_STATE_CHANGE_FAILURE, which happens only because the streams were not really started.
I think the element should not go to PLAYING if call self->input->input->StartStreams ()
fails. Also, if StopStreams()
fails, it should not be blocker for stopping the element, as this obviously causes more damage than just logging this error (as it is now for StartStreams
).
Setup
- Operating System: Windows
- Device: PC and Decklink Mini Recorder 4K
- GStreamer Version: 1.22.3