diff --git a/ffmpeg.c b/ffmpeg.c
index 6dae6e9078..32d8ba4895 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2833,7 +2833,7 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
             (ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id))
             continue;
 
-        ret = hwaccel->init(s);
+        ret = hwaccel->init(hwaccel, s);
         if (ret < 0) {
             if (ist->hwaccel_id == hwaccel->id) {
                 av_log(NULL, AV_LOG_FATAL,
diff --git a/ffmpeg.h b/ffmpeg.h
index fa81427471..946bcb75f2 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -70,13 +70,20 @@ enum HWAccelID {
     HWACCEL_CUVID,
 };
 
-typedef struct HWAccel {
+typedef struct HWAccel HWAccel;
+
+struct HWAccel {
     const char *name;
-    int (*init)(AVCodecContext *s);
+    int (*init)(const HWAccel *hwaccel, AVCodecContext *s);
     enum HWAccelID id;
     enum AVPixelFormat pix_fmt;
     enum AVHWDeviceType device_type;
-} HWAccel;
+    /*
+     * A dummy hwaccel is one which maps to a separate decoder rather
+     * than plugging into a standard decoder
+     */
+    int is_dummy;
+};
 
 typedef struct HWDevice {
     char *name;
@@ -673,6 +680,6 @@ void hw_device_free_all(void);
 int hw_device_setup_for_decode(InputStream *ist);
 int hw_device_setup_for_encode(OutputStream *ost);
 
-int hwaccel_decode_init(AVCodecContext *avctx);
+int hwaccel_decode_init(const HWAccel *hwaccel, AVCodecContext *avctx);
 
 #endif /* FFMPEG_H */
diff --git a/ffmpeg_dxva2.c b/ffmpeg_dxva2.c
index 1a391f82f3..8cbf5a9dff 100644
--- a/ffmpeg_dxva2.c
+++ b/ffmpeg_dxva2.c
@@ -406,7 +406,7 @@ fail:
     return AVERROR(EINVAL);
 }
 
-int dxva2_init(AVCodecContext *s)
+int dxva2_init(const HWAccel *hwaccel, AVCodecContext *s)
 {
     InputStream *ist = s->opaque;
     int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
diff --git a/ffmpeg_hw.c b/ffmpeg_hw.c
index a4d1cada59..8518f267be 100644
--- a/ffmpeg_hw.c
+++ b/ffmpeg_hw.c
@@ -375,11 +375,14 @@ fail:
     return err;
 }
 
-int hwaccel_decode_init(AVCodecContext *avctx)
+int hwaccel_decode_init(const HWAccel *hwaccel, AVCodecContext *avctx)
 {
     InputStream *ist = avctx->opaque;
 
     ist->hwaccel_retrieve_data = &hwaccel_retrieve_data;
+    if (hwaccel->is_dummy && ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
+        ist->hwaccel_output_format = hwaccel->pix_fmt;
+    }
 
     return 0;
 }
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 6dc4ad43d2..ec89f50cf9 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -68,31 +68,38 @@
 const HWAccel hwaccels[] = {
 #if HAVE_VDPAU_X11
     { "vdpau", hwaccel_decode_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU,
-      AV_HWDEVICE_TYPE_VDPAU },
+      AV_HWDEVICE_TYPE_VDPAU,
+      .is_dummy = 0 },
 #endif
 #if HAVE_DXVA2_LIB
     { "dxva2", dxva2_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD,
-      AV_HWDEVICE_TYPE_NONE },
+      AV_HWDEVICE_TYPE_NONE,
+      .is_dummy = 0 },
 #endif
 #if CONFIG_VDA
     { "vda",   videotoolbox_init,   HWACCEL_VDA,   AV_PIX_FMT_VDA,
-      AV_HWDEVICE_TYPE_NONE },
+      AV_HWDEVICE_TYPE_NONE,
+      .is_dummy = 0 },
 #endif
 #if CONFIG_VIDEOTOOLBOX
     { "videotoolbox",   videotoolbox_init,   HWACCEL_VIDEOTOOLBOX,   AV_PIX_FMT_VIDEOTOOLBOX,
-      AV_HWDEVICE_TYPE_NONE },
+      AV_HWDEVICE_TYPE_NONE,
+      .is_dummy = 0 },
 #endif
 #if CONFIG_LIBMFX
     { "qsv",   qsv_init,   HWACCEL_QSV,   AV_PIX_FMT_QSV,
-      AV_HWDEVICE_TYPE_NONE },
+      AV_HWDEVICE_TYPE_NONE,
+      .is_dummy = 0 },
 #endif
 #if CONFIG_VAAPI
     { "vaapi", hwaccel_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI,
-      AV_HWDEVICE_TYPE_VAAPI },
+      AV_HWDEVICE_TYPE_VAAPI,
+      .is_dummy = 0 },
 #endif
 #if CONFIG_CUVID
     { "cuvid", hwaccel_decode_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA,
-      AV_HWDEVICE_TYPE_CUDA },
+      AV_HWDEVICE_TYPE_CUDA,
+      .is_dummy = 1 },
 #endif
     { 0 },
 };
diff --git a/ffmpeg_qsv.c b/ffmpeg_qsv.c
index 7442750029..4df27e9e6e 100644
--- a/ffmpeg_qsv.c
+++ b/ffmpeg_qsv.c
@@ -68,7 +68,7 @@ err_out:
     return err;
 }
 
-int qsv_init(AVCodecContext *s)
+int qsv_init(const HWAccel *hwaccel, AVCodecContext *s)
 {
     InputStream *ist = s->opaque;
     AVHWFramesContext *frames_ctx;
diff --git a/ffmpeg_videotoolbox.c b/ffmpeg_videotoolbox.c
index e9039654b9..4346145a4a 100644
--- a/ffmpeg_videotoolbox.c
+++ b/ffmpeg_videotoolbox.c
@@ -126,7 +126,7 @@ static void videotoolbox_uninit(AVCodecContext *s)
     av_freep(&ist->hwaccel_ctx);
 }
 
-int videotoolbox_init(AVCodecContext *s)
+int videotoolbox_init(const HWAccel *hwaccel, AVCodecContext *s)
 {
     InputStream *ist = s->opaque;
     int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
