diff -Naur ffmpeg-7.1.2.old/doc/outdevs.texi ffmpeg-7.1.2/doc/outdevs.texi
--- ffmpeg-7.1.2.old/doc/outdevs.texi	2025-10-27 10:07:00.979477433 +0100
+++ ffmpeg-7.1.2/doc/outdevs.texi	2025-10-27 10:07:02.002148270 +0100
@@ -240,6 +240,10 @@
 outgoing VANC data will be dropped.
 Defaults to @samp{1048576}.
 
+@item block_until_available
+Retries output if device appears unavailable. Retry rate is 60 times a second.
+Defaults to @option{0}.
+
 @end table
 
 @subsection Examples
diff -Naur ffmpeg-7.1.2.old/fftools/ffmpeg_sched.c ffmpeg-7.1.2/fftools/ffmpeg_sched.c
--- ffmpeg-7.1.2.old/fftools/ffmpeg_sched.c	2025-10-27 10:07:01.220479559 +0100
+++ ffmpeg-7.1.2/fftools/ffmpeg_sched.c	2025-10-27 10:07:02.002549025 +0100
@@ -22,6 +22,7 @@
 #include <stdatomic.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <unistd.h>
 
 #include "cmdutils.h"
 #include "ffmpeg_sched.h"
diff -Naur ffmpeg-7.1.2.old/libavdevice/decklink_common_c.h ffmpeg-7.1.2/libavdevice/decklink_common_c.h
--- ffmpeg-7.1.2.old/libavdevice/decklink_common_c.h	2025-10-27 10:07:00.829476109 +0100
+++ ffmpeg-7.1.2/libavdevice/decklink_common_c.h	2025-10-27 10:07:02.003002589 +0100
@@ -74,6 +74,7 @@
     int64_t timestamp_align;
     int timing_offset;
     int wait_for_tc;
+    int block_until_available;
     DecklinkSignalLossAction signal_loss_action;
 };
 
diff -Naur ffmpeg-7.1.2.old/libavdevice/decklink_common.cpp ffmpeg-7.1.2/libavdevice/decklink_common.cpp
--- ffmpeg-7.1.2.old/libavdevice/decklink_common.cpp	2025-10-27 10:07:00.828476101 +0100
+++ ffmpeg-7.1.2/libavdevice/decklink_common.cpp	2025-10-27 10:07:02.003115933 +0100
@@ -25,7 +25,7 @@
 #include "libavformat/internal.h"
 }
 
-#include <DeckLinkAPI.h>
+#include <DeckLinkAPI_v14_2_1.h>
 #ifdef _WIN32
 #include <DeckLinkAPI_i.c>
 #else
@@ -53,6 +53,7 @@
 
 #include "decklink_common.h"
 
+
 static IDeckLinkIterator *decklink_create_iterator(AVFormatContext *avctx)
 {
     IDeckLinkIterator *iter;
@@ -512,8 +513,8 @@
         return AVERROR(EIO);
 
     while (ret == 0 && iter->Next(&dl) == S_OK) {
-        IDeckLinkOutput *output_config;
-        IDeckLinkInput *input_config;
+        IDeckLinkOutput_v14_2_1 *output_config;
+        IDeckLinkInput_v14_2_1 *input_config;
         const char *display_name = NULL;
         const char *unique_name = NULL;
         AVDeviceInfo *new_device = NULL;
@@ -527,14 +528,14 @@
             goto next;
 
         if (show_outputs) {
-            if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) {
+            if (dl->QueryInterface(IID_IDeckLinkOutput_v14_2_1, (void **)&output_config) == S_OK) {
                 output_config->Release();
                 add = 1;
             }
         }
 
         if (show_inputs) {
-            if (dl->QueryInterface(IID_IDeckLinkInput, (void **)&input_config) == S_OK) {
+            if (dl->QueryInterface(IID_IDeckLinkInput_v14_2_1, (void **)&input_config) == S_OK) {
                 input_config->Release();
                 add = 1;
             }
diff -Naur ffmpeg-7.1.2.old/libavdevice/decklink_common.h ffmpeg-7.1.2/libavdevice/decklink_common.h
--- ffmpeg-7.1.2.old/libavdevice/decklink_common.h	2025-10-27 10:07:00.831476127 +0100
+++ ffmpeg-7.1.2/libavdevice/decklink_common.h	2025-10-27 10:07:02.003408083 +0100
@@ -93,8 +93,8 @@
 struct decklink_ctx {
     /* DeckLink SDK interfaces */
     IDeckLink *dl;
-    IDeckLinkOutput *dlo;
-    IDeckLinkInput *dli;
+    IDeckLinkOutput_v14_2_1 *dlo;
+    IDeckLinkInput_v14_2_1 *dli;
     IDeckLinkConfiguration *cfg;
     IDeckLinkProfileAttributes *attr;
     decklink_output_callback *output_callback;
@@ -134,7 +134,6 @@
     AVStream *klv_st;
     AVStream *teletext_st;
     uint16_t cdp_sequence_num;
-
     /* Options */
     int list_devices;
     int list_formats;
@@ -149,13 +148,16 @@
     BMDPixelFormat raw_format;
     DecklinkSignalLossAction signal_loss_action;
 
+
     int frames_preroll;
     int frames_buffer;
 
     pthread_mutex_t mutex;
     pthread_cond_t cond;
     int frames_buffer_available_spots;
+    int outstanding_frames;
     int autodetect;
+    int block_until_available;
 
 #if CONFIG_LIBKLVANC
     struct klvanc_context_s *vanc_ctx;
@@ -249,3 +251,4 @@
 int64_t ff_decklink_packet_queue_peekpts(DecklinkPacketQueue *q);
 
 #endif /* AVDEVICE_DECKLINK_COMMON_H */
+
diff -Naur ffmpeg-7.1.2.old/libavdevice/decklink_dec.cpp ffmpeg-7.1.2/libavdevice/decklink_dec.cpp
--- ffmpeg-7.1.2.old/libavdevice/decklink_dec.cpp	2025-10-27 10:07:00.828476101 +0100
+++ ffmpeg-7.1.2/libavdevice/decklink_dec.cpp	2025-10-27 10:07:02.003669356 +0100
@@ -31,7 +31,7 @@
 #include "libavformat/internal.h"
 }
 
-#include <DeckLinkAPI.h>
+#include <DeckLinkAPI_v14_2_1.h>
 
 extern "C" {
 #include "config.h"
@@ -56,6 +56,7 @@
 #include "decklink_common.h"
 #include "decklink_dec.h"
 
+extern bool operator==(const REFIID& me, const REFIID& other);
 #define MAX_WIDTH_VANC 1920
 const BMDDisplayMode AUTODETECT_DEFAULT_MODE = bmdModeNTSC;
 
@@ -105,13 +106,13 @@
     {bmdModeUnknown, 0, -1, -1, -1}
 };
 
-class decklink_allocator : public IDeckLinkMemoryAllocator
+class decklink_allocator : public IDeckLinkMemoryAllocator_v14_2_1
 {
 public:
         decklink_allocator(): _refs(1) { }
         virtual ~decklink_allocator() { }
 
-        // IDeckLinkMemoryAllocator methods
+        // IDeckLinkMemoryAllocator_v14_2_1 methods
         virtual HRESULT STDMETHODCALLTYPE AllocateBuffer(unsigned int bufferSize, void* *allocatedBuffer)
         {
             void *buf = av_malloc(bufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
@@ -129,7 +130,15 @@
         virtual HRESULT STDMETHODCALLTYPE Decommit() { return S_OK; }
 
         // IUnknown methods
-        virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
+        virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) 
+        {
+            if (iid == IID_IDeckLinkMemoryAllocator_v14_2_1) { 
+                *ppv = (IDeckLinkMemoryAllocator_v14_2_1*)this; 
+                AddRef(); 
+                return S_OK; 
+            }
+            return E_NOINTERFACE; 
+        }
         virtual ULONG   STDMETHODCALLTYPE AddRef(void) { return ++_refs; }
         virtual ULONG   STDMETHODCALLTYPE Release(void)
         {
@@ -472,7 +481,7 @@
 }
 
 
-static void handle_klv(AVFormatContext *avctx, decklink_ctx *ctx, IDeckLinkVideoInputFrame *videoFrame, int64_t pts)
+static void handle_klv(AVFormatContext *avctx, decklink_ctx *ctx, IDeckLinkVideoInputFrame_v14_2_1 *videoFrame, int64_t pts)
 {
     const uint8_t KLV_DID = 0x44;
     const uint8_t KLV_IN_VANC_SDID = 0x04;
@@ -574,17 +583,25 @@
     }
 }
 
-class decklink_input_callback : public IDeckLinkInputCallback
+class decklink_input_callback : public IDeckLinkInputCallback_v14_2_1
 {
 public:
         explicit decklink_input_callback(AVFormatContext *_avctx);
         ~decklink_input_callback();
 
-        virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
+        virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv)
+        {
+            if (iid == IID_IDeckLinkInputCallback_v14_2_1) {
+                *ppv = (IDeckLinkInputCallback_v14_2_1*)this;
+                AddRef();
+                return S_OK;
+            }
+            return E_NOINTERFACE; 
+        }
         virtual ULONG STDMETHODCALLTYPE AddRef(void);
         virtual ULONG STDMETHODCALLTYPE  Release(void);
         virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents, IDeckLinkDisplayMode*, BMDDetectedVideoInputFormatFlags);
-        virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*);
+        virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame_v14_2_1*, IDeckLinkAudioInputPacket*);
 
 private:
         std::atomic<int>  _refs;
@@ -593,7 +610,7 @@
         int no_video;
         int64_t initial_video_pts;
         int64_t initial_audio_pts;
-        IDeckLinkVideoInputFrame* last_video_frame;
+        IDeckLinkVideoInputFrame_v14_2_1* last_video_frame;
 };
 
 decklink_input_callback::decklink_input_callback(AVFormatContext *_avctx) : _refs(1)
@@ -625,7 +642,7 @@
     return ret;
 }
 
-static int64_t get_pkt_pts(IDeckLinkVideoInputFrame *videoFrame,
+static int64_t get_pkt_pts(IDeckLinkVideoInputFrame_v14_2_1 *videoFrame,
                            IDeckLinkAudioInputPacket *audioFrame,
                            int64_t wallclock,
                            int64_t abs_wallclock,
@@ -679,7 +696,7 @@
     return pts;
 }
 
-static int get_bmd_timecode(AVFormatContext *avctx, AVTimecode *tc, AVRational frame_rate, BMDTimecodeFormat tc_format, IDeckLinkVideoInputFrame *videoFrame)
+static int get_bmd_timecode(AVFormatContext *avctx, AVTimecode *tc, AVRational frame_rate, BMDTimecodeFormat tc_format, IDeckLinkVideoInputFrame_v14_2_1 *videoFrame)
 {
     IDeckLinkTimecode *timecode;
     int ret = AVERROR(ENOENT);
@@ -701,7 +718,7 @@
     return ret;
 }
 
-static int get_frame_timecode(AVFormatContext *avctx, decklink_ctx *ctx, AVTimecode *tc, IDeckLinkVideoInputFrame *videoFrame)
+static int get_frame_timecode(AVFormatContext *avctx, decklink_ctx *ctx, AVTimecode *tc, IDeckLinkVideoInputFrame_v14_2_1 *videoFrame)
 {
     AVRational frame_rate = ctx->video_st->r_frame_rate;
     int ret;
@@ -726,7 +743,7 @@
 }
 
 HRESULT decklink_input_callback::VideoInputFrameArrived(
-    IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioFrame)
+    IDeckLinkVideoInputFrame_v14_2_1 *videoFrame, IDeckLinkAudioInputPacket *audioFrame)
 {
     void *frameBytes;
     void *audioFrameBytes;
@@ -1141,7 +1158,7 @@
         goto error;
 
     /* Get input device. */
-    if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != S_OK) {
+    if (ctx->dl->QueryInterface(IID_IDeckLinkInput_v14_2_1, (void **) &ctx->dli) != S_OK) {
         av_log(avctx, AV_LOG_ERROR, "Could not open input device from '%s'\n",
                avctx->url);
         ret = AVERROR(EIO);
diff -Naur ffmpeg-7.1.2.old/libavdevice/decklink_enc_c.c ffmpeg-7.1.2/libavdevice/decklink_enc_c.c
--- ffmpeg-7.1.2.old/libavdevice/decklink_enc_c.c	2025-10-27 10:07:00.833476145 +0100
+++ ffmpeg-7.1.2/libavdevice/decklink_enc_c.c	2025-10-27 10:07:02.004050964 +0100
@@ -32,6 +32,7 @@
     { "list_devices", "use ffmpeg -sinks decklink instead", OFFSET(list_devices), AV_OPT_TYPE_BOOL, { .i64 = 0   }, 0, 1, ENC | AV_OPT_FLAG_DEPRECATED},
     { "list_formats", "list supported formats"  , OFFSET(list_formats), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 1, ENC },
     { "preroll"     , "video preroll in seconds", OFFSET(preroll     ), AV_OPT_TYPE_DOUBLE, { .dbl = 0.5 }, 0, 5, ENC },
+    { "block_until_available",     "wait for device to become available instead of raising error", OFFSET(block_until_available), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
     { "vanc_queue_size", "VANC queue buffer size", OFFSET(vanc_queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024)}, 0, INT64_MAX, ENC },
 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
     { "duplex_mode" , "duplex mode"             , OFFSET(duplex_mode ), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 5, ENC, .unit = "duplex_mode"},
diff -Naur ffmpeg-7.1.2.old/libavdevice/decklink_enc.cpp ffmpeg-7.1.2/libavdevice/decklink_enc.cpp
--- ffmpeg-7.1.2.old/libavdevice/decklink_enc.cpp	2025-10-27 10:07:00.832476136 +0100
+++ ffmpeg-7.1.2/libavdevice/decklink_enc.cpp	2025-10-27 10:07:02.004296918 +0100
@@ -20,6 +20,8 @@
  */
 
 #include <atomic>
+#include <unistd.h>
+
 using std::atomic;
 
 /* Include internal.h first to avoid conflict between winsock.h (used by
@@ -28,7 +30,7 @@
 #include "libavformat/internal.h"
 }
 
-#include <DeckLinkAPI.h>
+#include <DeckLinkAPI_v14_2_1.h>
 
 extern "C" {
 #include "libavformat/avformat.h"
@@ -47,8 +49,26 @@
 #include "libklvanc/pixels.h"
 #endif
 
+extern bool operator==(const REFIID& me, const REFIID& other){
+    return me.byte0 == other.byte0 &&
+	   me.byte1 == other.byte1 &&
+	   me.byte2 == other.byte2 &&
+	   me.byte3 == other.byte3 &&
+	   me.byte4 == other.byte4 &&
+	   me.byte5 == other.byte5 &&
+	   me.byte6 == other.byte6 &&
+	   me.byte7 == other.byte7 &&
+	   me.byte8 == other.byte8 &&
+	   me.byte9 == other.byte9 &&
+	   me.byte10 == other.byte10 &&
+	   me.byte11 == other.byte11 &&
+	   me.byte12 == other.byte12 &&
+	   me.byte13 == other.byte13 &&
+	   me.byte14 == other.byte14 &&
+	   me.byte15 == other.byte15;
+}
 /* DeckLink callback class declaration */
-class decklink_frame : public IDeckLinkVideoFrame
+class decklink_frame : public IDeckLinkVideoFrame_v14_2_1
 {
 public:
     decklink_frame(struct decklink_ctx *ctx, AVFrame *avframe, AVCodecID codec_id, int height, int width) :
@@ -111,7 +131,16 @@
         _ancillary->AddRef();
         return S_OK;
     }
-    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
+    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) 
+    {
+        if (iid == IID_IDeckLinkVideoFrame_v14_2_1) 
+        { 
+            *ppv = (IDeckLinkVideoFrame_v14_2_1*)this; 
+            AddRef(); 
+            return S_OK; 
+        }
+        return E_NOINTERFACE; 
+    }
     virtual ULONG   STDMETHODCALLTYPE AddRef(void)                            { return ++_refs; }
     virtual ULONG   STDMETHODCALLTYPE Release(void)
     {
@@ -138,10 +167,10 @@
     std::atomic<int>  _refs;
 };
 
-class decklink_output_callback : public IDeckLinkVideoOutputCallback
+class decklink_output_callback : public IDeckLinkVideoOutputCallback_v14_2_1
 {
 public:
-    virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame *_frame, BMDOutputFrameCompletionResult result)
+    virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame_v14_2_1 *_frame, BMDOutputFrameCompletionResult result)
     {
         decklink_frame *frame = static_cast<decklink_frame *>(_frame);
         struct decklink_ctx *ctx = frame->_ctx;
@@ -155,11 +184,22 @@
         ctx->frames_buffer_available_spots++;
         pthread_cond_broadcast(&ctx->cond);
         pthread_mutex_unlock(&ctx->mutex);
-
+        pthread_mutex_lock(&ctx->mutex);
+        ctx->outstanding_frames--;
+        pthread_mutex_unlock(&ctx->mutex);
         return S_OK;
     }
     virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped(void)       { return S_OK; }
-    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
+    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv)
+    {
+        if (iid == IID_IDeckLinkVideoOutputCallback_v14_2_1) 
+        { 
+            *ppv = (IDeckLinkVideoOutputCallback_v14_2_1*)this; 
+            AddRef(); 
+            return S_OK; 
+        }
+        return E_NOINTERFACE; 
+    }
     virtual ULONG   STDMETHODCALLTYPE AddRef(void)                            { return 1; }
     virtual ULONG   STDMETHODCALLTYPE Release(void)                           { return 1; }
 };
@@ -204,9 +244,14 @@
         av_log(avctx, AV_LOG_WARNING, "Could not enable video output with VANC! Trying without...\n");
         ctx->supports_vanc = 0;
     }
-    if (!ctx->supports_vanc && ctx->dlo->EnableVideoOutput(ctx->bmd_mode, bmdVideoOutputFlagDefault) != S_OK) {
-        av_log(avctx, AV_LOG_ERROR, "Could not enable video output!\n");
-        return -1;
+    while (!ctx->supports_vanc && ctx->dlo->EnableVideoOutput(ctx->bmd_mode, bmdVideoOutputFlagDefault) != S_OK) {
+        if (!ctx->block_until_available) {
+            av_log(avctx, AV_LOG_ERROR, "Could not enable video output!\n");
+            return -1;
+        };
+        av_log(avctx, AV_LOG_WARNING, "Could not enable video output, waiting for device...\n");
+        usleep(1000000 / 60);
+        continue;
     }
 
     /* Set callback. */
@@ -370,6 +415,10 @@
     struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
     struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
 
+    av_log(avctx, AV_LOG_DEBUG, "Wating for %d outstanding frames to return their results\n", ctx->outstanding_frames);
+    while (ctx->outstanding_frames > 0){
+        usleep(1);
+    }
     if (ctx->playback_started) {
         BMDTimeValue actual;
         ctx->dlo->StopScheduledPlayback(ctx->last_pts * ctx->bmd_tb_num,
@@ -739,7 +788,7 @@
         ctx->first_pts = pkt->pts;
 
     /* Schedule frame for playback. */
-    hr = ctx->dlo->ScheduleVideoFrame((class IDeckLinkVideoFrame *) frame,
+    hr = ctx->dlo->ScheduleVideoFrame((class IDeckLinkVideoFrame_v14_2_1 *) frame,
                                       pkt->pts * ctx->bmd_tb_num,
                                       ctx->bmd_tb_num, ctx->bmd_tb_den);
     /* Pass ownership to DeckLink, or release on failure */
@@ -750,6 +799,9 @@
         return AVERROR(EIO);
     }
 
+    pthread_mutex_lock(&ctx->mutex);
+    ctx->outstanding_frames++;
+    pthread_mutex_unlock(&ctx->mutex);
     ctx->dlo->GetBufferedVideoFrameCount(&buffered);
     av_log(avctx, AV_LOG_DEBUG, "Buffered video frames: %d.\n", (int) buffered);
     if (pkt->pts > 2 && buffered <= 2)
@@ -850,6 +902,7 @@
     ctx->list_devices = cctx->list_devices;
     ctx->list_formats = cctx->list_formats;
     ctx->preroll      = cctx->preroll;
+    ctx->block_until_available      = cctx->block_until_available;
     ctx->duplex_mode  = cctx->duplex_mode;
     ctx->first_pts    = AV_NOPTS_VALUE;
     if (cctx->link > 0 && (unsigned int)cctx->link < FF_ARRAY_ELEMS(decklink_link_conf_map))
@@ -874,7 +927,7 @@
         return ret;
 
     /* Get output device. */
-    if (ctx->dl->QueryInterface(IID_IDeckLinkOutput, (void **) &ctx->dlo) != S_OK) {
+    if (ctx->dl->QueryInterface(IID_IDeckLinkOutput_v14_2_1, (void **) &ctx->dlo) != S_OK) {
         av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n",
                avctx->url);
         ret = AVERROR(EIO);
