[FFmpeg-devel,02/17] lavc: Add hardware config metadata for decoders supporting hardware output

Submitted by Mark Thompson on Nov. 24, 2017, 12:51 a.m.

Details

Message ID 20171124005134.5683-2-sw@jkqxz.net
State New
Headers show

Commit Message

Mark Thompson Nov. 24, 2017, 12:51 a.m.
This includes a pointer to the associated hwaccel for decoders using
hwaccels - these will be used later to implement the hwaccel setup
without needing a global list.

Also added is a new file listing all hwaccels as external declarations -
this will be used later to generate the hwaccel list at configure time.
---
 libavcodec/cuviddec.c      | 15 ++++++++++
 libavcodec/h263dec.c       | 13 ++++++++
 libavcodec/h264dec.c       | 25 ++++++++++++++++
 libavcodec/hevcdec.c       | 25 ++++++++++++++++
 libavcodec/hwaccel.h       | 50 +++++++++++++++++++++++++++++++
 libavcodec/hwaccels.h      | 74 ++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/mediacodecdec.c | 18 +++++++++++
 libavcodec/mmaldec.c       |  7 +++++
 libavcodec/mpeg12dec.c     | 45 +++++++++++++++++++++++++++-
 libavcodec/mpeg4videodec.c | 16 ++++++++++
 libavcodec/qsvdec.c        | 13 ++++++++
 libavcodec/qsvdec.h        |  3 ++
 libavcodec/qsvdec_h2645.c  |  2 ++
 libavcodec/qsvdec_other.c  |  3 ++
 libavcodec/vc1dec.c        | 43 +++++++++++++++++++++++++++
 libavcodec/vp9.c           | 19 ++++++++++++
 16 files changed, 370 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/hwaccels.h

Comments

Timo Rothenpieler Nov. 24, 2017, 9:18 a.m.
> diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
> index 806dab2074..3bd2409ea2 100644
> --- a/libavcodec/cuviddec.c
> +++ b/libavcodec/cuviddec.c
> @@ -32,6 +32,7 @@
>   
>   #include "avcodec.h"
>   #include "decode.h"
> +#include "hwaccel.h"
>   #include "internal.h"
>   
>   typedef struct CuvidContext
> @@ -1094,6 +1095,19 @@ static const AVOption options[] = {
>       { NULL }
>   };
>   
> +static const AVCodecHWConfigInternal *cuvid_hw_configs[] = {
> +    &(const AVCodecHWConfigInternal) {
> +        .public = {
> +            .pix_fmt     = AV_PIX_FMT_CUDA,
> +            .methods     = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX |
> +                           AV_CODEC_HW_CONFIG_METHOD_INTERNAL,
> +            .device_type = AV_HWDEVICE_TYPE_CUDA
> +        },
> +        .hwaccel = NULL,
> +    },
> +    NULL
> +};
> +
>   #define DEFINE_CUVID_CODEC(x, X) \
>       static const AVClass x##_cuvid_class = { \
>           .class_name = #x "_cuvid", \
> @@ -1127,6 +1141,7 @@ static const AVOption options[] = {
>                                                           AV_PIX_FMT_P010, \
>                                                           AV_PIX_FMT_P016, \
>                                                           AV_PIX_FMT_NONE }, \
> +        .hw_configs     = cuvid_hw_configs, \
>       };
>   
>   #if CONFIG_HEVC_CUVID_DECODER

ok
Philip Langdale Nov. 24, 2017, 5:18 p.m.
On Fri, 24 Nov 2017 00:51:19 +0000
Mark Thompson <sw@jkqxz.net> wrote:

> This includes a pointer to the associated hwaccel for decoders using
> hwaccels - these will be used later to implement the hwaccel setup
> without needing a global list.
> 
> Also added is a new file listing all hwaccels as external
> declarations - this will be used later to generate the hwaccel list
> at configure time. ---
>  libavcodec/cuviddec.c      | 15 ++++++++++
>  libavcodec/h263dec.c       | 13 ++++++++
>  libavcodec/h264dec.c       | 25 ++++++++++++++++
>  libavcodec/hevcdec.c       | 25 ++++++++++++++++
>  libavcodec/hwaccel.h       | 50 +++++++++++++++++++++++++++++++
>  libavcodec/hwaccels.h      | 74
> ++++++++++++++++++++++++++++++++++++++++++++++
> libavcodec/mediacodecdec.c | 18 +++++++++++
> libavcodec/mmaldec.c       |  7 +++++ libavcodec/mpeg12dec.c     | 45
> +++++++++++++++++++++++++++- libavcodec/mpeg4videodec.c | 16
> ++++++++++ libavcodec/qsvdec.c        | 13 ++++++++
>  libavcodec/qsvdec.h        |  3 ++
>  libavcodec/qsvdec_h2645.c  |  2 ++
>  libavcodec/qsvdec_other.c  |  3 ++
>  libavcodec/vc1dec.c        | 43 +++++++++++++++++++++++++++
>  libavcodec/vp9.c           | 19 ++++++++++++
>  16 files changed, 370 insertions(+), 1 deletion(-)
>  create mode 100644 libavcodec/hwaccels.h
> 
> diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
> index 806dab2074..3bd2409ea2 100644
> --- a/libavcodec/cuviddec.c
> +++ b/libavcodec/cuviddec.c
> @@ -32,6 +32,7 @@
>  
>  #include "avcodec.h"
>  #include "decode.h"
> +#include "hwaccel.h"
>  #include "internal.h"
>  
>  typedef struct CuvidContext
> @@ -1094,6 +1095,19 @@ static const AVOption options[] = {
>      { NULL }
>  };
>  
> +static const AVCodecHWConfigInternal *cuvid_hw_configs[] = {
> +    &(const AVCodecHWConfigInternal) {
> +        .public = {
> +            .pix_fmt     = AV_PIX_FMT_CUDA,
> +            .methods     = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX |
> +                           AV_CODEC_HW_CONFIG_METHOD_INTERNAL,
> +            .device_type = AV_HWDEVICE_TYPE_CUDA
> +        },
> +        .hwaccel = NULL,
> +    },
> +    NULL
> +};
> +
>  #define DEFINE_CUVID_CODEC(x, X) \
>      static const AVClass x##_cuvid_class = { \
>          .class_name = #x "_cuvid", \
> @@ -1127,6 +1141,7 @@ static const AVOption options[] = {
>                                                          AV_PIX_FMT_P010,
> \ AV_PIX_FMT_P016, \
>                                                          AV_PIX_FMT_NONE },
> \
> +        .hw_configs     = cuvid_hw_configs, \
>      };
>  
>  #if CONFIG_HEVC_CUVID_DECODER
> diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
> index b222de793b..5608b63245 100644
> --- a/libavcodec/h263dec.c
> +++ b/libavcodec/h263dec.c
> @@ -33,6 +33,7 @@
>  #include "flv.h"
>  #include "h263.h"
>  #include "h263_parser.h"
> +#include "hwaccel.h"
>  #include "internal.h"
>  #include "mpeg_er.h"
>  #include "mpeg4video.h"
> @@ -759,4 +760,16 @@ AVCodec ff_h263p_decoder = {
>      .flush          = ff_mpeg_flush,
>      .max_lowres     = 3,
>      .pix_fmts       = ff_h263_hwaccel_pixfmt_list_420,
> +    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_H263_VAAPI_HWACCEL
> +                        HWACCEL_VAAPI(h263),
> +#endif
> +#if CONFIG_MPEG4_VDPAU_HWACCEL
> +                        HWACCEL_VDPAU(mpeg4),
> +#endif
> +#if CONFIG_H263_VIDEOTOOLBOX_HWACCEL
> +                        HWACCEL_VIDEOTOOLBOX(h263),
> +#endif
> +                        NULL
> +                    },
>  };
> diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
> index be187eb5f4..b03024d4a3 100644
> --- a/libavcodec/h264dec.c
> +++ b/libavcodec/h264dec.c
> @@ -47,6 +47,7 @@
>  #include "h264_mvpred.h"
>  #include "h264_ps.h"
>  #include "golomb.h"
> +#include "hwaccel.h"
>  #include "mathops.h"
>  #include "me_cmp.h"
>  #include "mpegutils.h"
> @@ -1059,6 +1060,30 @@ AVCodec ff_h264_decoder = {
>      .capabilities          = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/
> AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
>                               AV_CODEC_CAP_FRAME_THREADS,
> +    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_H264_DXVA2_HWACCEL
> +                               HWACCEL_DXVA2(h264),
> +#endif
> +#if CONFIG_H264_D3D11VA_HWACCEL
> +                               HWACCEL_D3D11VA(h264),
> +#endif
> +#if CONFIG_H264_D3D11VA2_HWACCEL
> +                               HWACCEL_D3D11VA2(h264),
> +#endif
> +#if CONFIG_H264_NVDEC_HWACCEL
> +                               HWACCEL_NVDEC(h264),
> +#endif
> +#if CONFIG_H264_VAAPI_HWACCEL
> +                               HWACCEL_VAAPI(h264),
> +#endif
> +#if CONFIG_H264_VDPAU_HWACCEL
> +                               HWACCEL_VDPAU(h264),
> +#endif
> +#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL
> +                               HWACCEL_VIDEOTOOLBOX(h264),
> +#endif
> +                               NULL
> +                           },
>      .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE |
> FF_CODEC_CAP_EXPORTS_CROPPING, .flush                 = flush_dpb,
>      .init_thread_copy      =
> ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), diff --git
> a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index
> 75960912b1..5ec6105d2f 100644 --- a/libavcodec/hevcdec.c
> +++ b/libavcodec/hevcdec.c
> @@ -41,6 +41,7 @@
>  #include "hevc_data.h"
>  #include "hevc_parse.h"
>  #include "hevcdec.h"
> +#include "hwaccel.h"
>  #include "profiles.h"
>  
>  const uint8_t ff_hevc_pel_weight[65] = { [2] = 0, [4] = 1, [6] = 2,
> [8] = 3, [12] = 4, [16] = 5, [24] = 6, [32] = 7, [48] = 8, [64] =
> 9 }; @@ -3510,4 +3511,28 @@ AVCodec ff_hevc_decoder =
> { AV_CODEC_CAP_SLICE_THREADS |
> AV_CODEC_CAP_FRAME_THREADS, .caps_internal         =
> FF_CODEC_CAP_INIT_THREADSAFE |
> FF_CODEC_CAP_EXPORTS_CROPPING, .profiles              =
> NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
> +    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_HEVC_DXVA2_HWACCEL
> +                               HWACCEL_DXVA2(hevc),
> +#endif
> +#if CONFIG_HEVC_D3D11VA_HWACCEL
> +                               HWACCEL_D3D11VA(hevc),
> +#endif
> +#if CONFIG_HEVC_D3D11VA2_HWACCEL
> +                               HWACCEL_D3D11VA2(hevc),
> +#endif
> +#if CONFIG_HEVC_NVDEC_HWACCEL
> +                               HWACCEL_NVDEC(hevc),
> +#endif
> +#if CONFIG_HEVC_VAAPI_HWACCEL
> +                               HWACCEL_VAAPI(hevc),
> +#endif
> +#if CONFIG_HEVC_VDPAU_HWACCEL
> +                               HWACCEL_VDPAU(hevc),
> +#endif
> +#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
> +                               HWACCEL_VIDEOTOOLBOX(hevc),
> +#endif
> +                               NULL
> +                           },
>  };
> diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h
> index 0198c7f858..382e0d0264 100644
> --- a/libavcodec/hwaccel.h
> +++ b/libavcodec/hwaccel.h
> @@ -20,6 +20,7 @@
>  #define AVCODEC_HWACCEL_H
>  
>  #include "avcodec.h"
> +#include "hwaccels.h"
>  
>  
>  #define HWACCEL_CAP_ASYNC_SAFE      (1 << 0)
> @@ -39,4 +40,53 @@ typedef struct AVCodecHWConfigInternal {
>  } AVCodecHWConfigInternal;
>  
>  
> +// These macros are used to simplify AVCodecHWConfigInternal
> definitions. +
> +#define HW_CONFIG_HWACCEL(format, device, name) \
> +    &(const AVCodecHWConfigInternal) { \
> +        .public          = { \
> +            .pix_fmt     = AV_PIX_FMT_ ## format, \
> +            .methods     = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX |
> \
> +                           AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, \
> +            .device_type = AV_HWDEVICE_TYPE_ ## device, \
> +        }, \
> +        .hwaccel         = &name, \
> +    }
> +
> +#define HW_CONFIG_INTERNAL(format) \
> +    &(const AVCodecHWConfigInternal) { \
> +        .public          = { \
> +            .pix_fmt     = AV_PIX_FMT_ ## format, \
> +            .methods     = AV_CODEC_HW_CONFIG_METHOD_INTERNAL, \
> +            .device_type = AV_HWDEVICE_TYPE_NONE, \
> +        }, \
> +        .hwaccel         = NULL, \
> +    }
> +
> +#define HW_CONFIG_AD_HOC_HWACCEL(format, name) \
> +    &(const AVCodecHWConfigInternal) { \
> +        .public =      { \
> +            .pix_fmt     = AV_PIX_FMT_ ## format, \
> +            .methods     = AV_CODEC_HW_CONFIG_METHOD_AD_HOC, \
> +            .device_type = AV_HWDEVICE_TYPE_NONE, \
> +        }, \
> +        .hwaccel = &name, \
> +    }
> +
> +#define HWACCEL_DXVA2(codec) \
> +    HW_CONFIG_HWACCEL(DXVA2_VLD, DXVA2,   ff_ ## codec ##
> _dxva2_hwaccel) +#define HWACCEL_D3D11VA2(codec) \
> +    HW_CONFIG_HWACCEL(D3D11,     D3D11VA, ff_ ## codec ##
> _d3d11va2_hwaccel) +#define HWACCEL_NVDEC(codec) \
> +    HW_CONFIG_HWACCEL(CUDA,      CUDA,    ff_ ## codec ##
> _nvdec_hwaccel) +#define HWACCEL_VAAPI(codec) \
> +    HW_CONFIG_HWACCEL(VAAPI,     VAAPI,   ff_ ## codec ##
> _vaapi_hwaccel) +#define HWACCEL_VDPAU(codec) \
> +    HW_CONFIG_HWACCEL(VDPAU,     VDPAU,   ff_ ## codec ##
> _vdpau_hwaccel) +#define HWACCEL_VIDEOTOOLBOX(codec) \
> +    HW_CONFIG_HWACCEL(VIDEOTOOLBOX, VIDEOTOOLBOX, ff_ ## codec ##
> _videotoolbox_hwaccel) +
> +#define HWACCEL_D3D11VA(codec) \
> +    HW_CONFIG_AD_HOC_HWACCEL(D3D11VA_VLD, ff_ ## codec ##
> _d3d11va_hwaccel) +
>  #endif /* AVCODEC_HWACCEL_H */
> diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
> new file mode 100644
> index 0000000000..9a3008a92c
> --- /dev/null
> +++ b/libavcodec/hwaccels.h
> @@ -0,0 +1,74 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#ifndef AVCODEC_HWACCELS_H
> +#define AVCODEC_HWACCELS_H
> +
> +#include "avcodec.h"
> +
> +extern AVHWAccel ff_h263_vaapi_hwaccel;
> +extern AVHWAccel ff_h263_videotoolbox_hwaccel;
> +extern AVHWAccel ff_h264_d3d11va_hwaccel;
> +extern AVHWAccel ff_h264_d3d11va2_hwaccel;
> +extern AVHWAccel ff_h264_dxva2_hwaccel;
> +extern AVHWAccel ff_h264_nvdec_hwaccel;
> +extern AVHWAccel ff_h264_vaapi_hwaccel;
> +extern AVHWAccel ff_h264_vdpau_hwaccel;
> +extern AVHWAccel ff_h264_videotoolbox_hwaccel;
> +extern AVHWAccel ff_hevc_d3d11va_hwaccel;
> +extern AVHWAccel ff_hevc_d3d11va2_hwaccel;
> +extern AVHWAccel ff_hevc_dxva2_hwaccel;
> +extern AVHWAccel ff_hevc_nvdec_hwaccel;
> +extern AVHWAccel ff_hevc_vaapi_hwaccel;
> +extern AVHWAccel ff_hevc_vdpau_hwaccel;
> +extern AVHWAccel ff_hevc_videotoolbox_hwaccel;
> +extern AVHWAccel ff_mpeg1_nvdec_hwaccel;
> +extern AVHWAccel ff_mpeg1_vdpau_hwaccel;
> +extern AVHWAccel ff_mpeg1_videotoolbox_hwaccel;
> +extern AVHWAccel ff_mpeg1_xvmc_hwaccel;
> +extern AVHWAccel ff_mpeg2_d3d11va_hwaccel;
> +extern AVHWAccel ff_mpeg2_d3d11va2_hwaccel;
> +extern AVHWAccel ff_mpeg2_nvdec_hwaccel;
> +extern AVHWAccel ff_mpeg2_dxva2_hwaccel;
> +extern AVHWAccel ff_mpeg2_vaapi_hwaccel;
> +extern AVHWAccel ff_mpeg2_vdpau_hwaccel;
> +extern AVHWAccel ff_mpeg2_videotoolbox_hwaccel;
> +extern AVHWAccel ff_mpeg2_xvmc_hwaccel;
> +extern AVHWAccel ff_mpeg4_nvdec_hwaccel;
> +extern AVHWAccel ff_mpeg4_vaapi_hwaccel;
> +extern AVHWAccel ff_mpeg4_vdpau_hwaccel;
> +extern AVHWAccel ff_mpeg4_videotoolbox_hwaccel;
> +extern AVHWAccel ff_vc1_d3d11va_hwaccel;
> +extern AVHWAccel ff_vc1_d3d11va2_hwaccel;
> +extern AVHWAccel ff_vc1_dxva2_hwaccel;
> +extern AVHWAccel ff_vc1_nvdec_hwaccel;
> +extern AVHWAccel ff_vc1_vaapi_hwaccel;
> +extern AVHWAccel ff_vc1_vdpau_hwaccel;
> +extern AVHWAccel ff_vp9_d3d11va_hwaccel;
> +extern AVHWAccel ff_vp9_d3d11va2_hwaccel;
> +extern AVHWAccel ff_vp9_dxva2_hwaccel;
> +extern AVHWAccel ff_vp9_nvdec_hwaccel;
> +extern AVHWAccel ff_vp9_vaapi_hwaccel;
> +extern AVHWAccel ff_wmv3_d3d11va_hwaccel;
> +extern AVHWAccel ff_wmv3_d3d11va2_hwaccel;
> +extern AVHWAccel ff_wmv3_dxva2_hwaccel;
> +extern AVHWAccel ff_wmv3_nvdec_hwaccel;
> +extern AVHWAccel ff_wmv3_vaapi_hwaccel;
> +extern AVHWAccel ff_wmv3_vdpau_hwaccel;
> +
> +#endif /* AVCODEC_HWACCELS_H */
> diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
> index 0cf9419ea3..feee316140 100644
> --- a/libavcodec/mediacodecdec.c
> +++ b/libavcodec/mediacodecdec.c
> @@ -515,6 +515,18 @@ static void
> mediacodec_decode_flush(AVCodecContext *avctx)
> ff_mediacodec_dec_flush(avctx, s->ctx); }
>  
> +static const AVCodecHWConfigInternal *mediacodec_hw_configs[] = {
> +    &(const AVCodecHWConfigInternal) {
> +        .public          = {
> +            .pix_fmt     = AV_PIX_FMT_MEDIACODEC,
> +            .methods     = AV_CODEC_HW_CONFIG_METHOD_AD_HOC,
> +            .device_type = AV_HWDEVICE_TYPE_NONE,
> +        },
> +        .hwaccel         = NULL,
> +    }
> +    NULL
> +};
> +
>  #if CONFIG_H264_MEDIACODEC_DECODER
>  AVCodec ff_h264_mediacodec_decoder = {
>      .name           = "h264_mediacodec",
> @@ -529,6 +541,7 @@ AVCodec ff_h264_mediacodec_decoder = {
>      .capabilities   = AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_AVOID_PROBING, .caps_internal  =
> FF_CODEC_CAP_SETS_PKT_DTS, .bsfs           = "h264_mp4toannexb",
> +    .hw_configs     = mediacodec_hw_configs,
>  };
>  #endif
>  
> @@ -546,6 +559,7 @@ AVCodec ff_hevc_mediacodec_decoder = {
>      .capabilities   = AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_AVOID_PROBING, .caps_internal  =
> FF_CODEC_CAP_SETS_PKT_DTS, .bsfs           = "hevc_mp4toannexb",
> +    .hw_configs     = mediacodec_hw_configs,
>  };
>  #endif
>  
> @@ -562,6 +576,7 @@ AVCodec ff_mpeg2_mediacodec_decoder = {
>      .close          = mediacodec_decode_close,
>      .capabilities   = AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_AVOID_PROBING, .caps_internal  =
> FF_CODEC_CAP_SETS_PKT_DTS,
> +    .hw_configs     = mediacodec_hw_configs,
>  };
>  #endif
>  
> @@ -578,6 +593,7 @@ AVCodec ff_mpeg4_mediacodec_decoder = {
>      .close          = mediacodec_decode_close,
>      .capabilities   = AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_AVOID_PROBING, .caps_internal  =
> FF_CODEC_CAP_SETS_PKT_DTS,
> +    .hw_configs     = mediacodec_hw_configs,
>  };
>  #endif
>  
> @@ -594,6 +610,7 @@ AVCodec ff_vp8_mediacodec_decoder = {
>      .close          = mediacodec_decode_close,
>      .capabilities   = AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_AVOID_PROBING, .caps_internal  =
> FF_CODEC_CAP_SETS_PKT_DTS,
> +    .hw_configs     = mediacodec_hw_configs,
>  };
>  #endif
>  
> @@ -610,5 +627,6 @@ AVCodec ff_vp9_mediacodec_decoder = {
>      .close          = mediacodec_decode_close,
>      .capabilities   = AV_CODEC_CAP_DELAY |
> AV_CODEC_CAP_AVOID_PROBING, .caps_internal  =
> FF_CODEC_CAP_SETS_PKT_DTS,
> +    .hw_configs     = mediacodec_hw_configs,
>  };
>  #endif
> diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c
> index f2ee3557aa..836d1e20e0 100644
> --- a/libavcodec/mmaldec.c
> +++ b/libavcodec/mmaldec.c
> @@ -34,6 +34,7 @@
>  #include <stdatomic.h>
>  
>  #include "avcodec.h"
> +#include "hwaccel.h"
>  #include "internal.h"
>  #include "libavutil/avassert.h"
>  #include "libavutil/buffer.h"
> @@ -835,6 +836,11 @@ AVHWAccel ff_vc1_mmal_hwaccel = {
>      .pix_fmt    = AV_PIX_FMT_MMAL,
>  };
>  
> +static const AVCodecHWConfigInternal *mmal_hw_configs = {
> +    HW_CONFIG_INTERNAL(MMAL),
> +    NULL
> +};
> +
>  static const AVOption options[]={
>      {"extra_buffers", "extra buffers", offsetof(MMALDecodeContext,
> extra_buffers), AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
> {"extra_decoder_buffers", "extra MMAL internal buffered frames",
> offsetof(MMALDecodeContext, extra_decoder_buffers), AV_OPT_TYPE_INT,
> {.i64 = 10}, 0, 256, 0}, @@ -867,6 +873,7 @@ static const AVOption
> options[]={ .pix_fmts       = (const enum AVPixelFormat[])
> { AV_PIX_FMT_MMAL, \ AV_PIX_FMT_YUV420P, \ AV_PIX_FMT_NONE}, \
> +        .hw_configs     = mmal_hw_configs,
>      };
>  
>  FFMMAL_DEC(h264, AV_CODEC_ID_H264)
> diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
> index 5a51d09bb0..07c68dbabc 100644
> --- a/libavcodec/mpeg12dec.c
> +++ b/libavcodec/mpeg12dec.c
> @@ -36,6 +36,7 @@
>  #include "avcodec.h"
>  #include "bytestream.h"
>  #include "error_resilience.h"
> +#include "hwaccel.h"
>  #include "idctdsp.h"
>  #include "internal.h"
>  #include "mpeg_er.h"
> @@ -2890,7 +2891,22 @@ AVCodec ff_mpeg1video_decoder = {
>      .caps_internal         = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
>      .flush                 = flush,
>      .max_lowres            = 3,
> -    .update_thread_context =
> ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
> +    .update_thread_context =
> ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context),
> +    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_MPEG2_NVDEC_HWACCEL
> +                               HWACCEL_NVDEC(mpeg1),
> +#endif
> +#if CONFIG_MPEG1_VDPAU_HWACCEL
> +                               HWACCEL_VDPAU(mpeg1),
> +#endif
> +#if CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL
> +                               HWACCEL_VIDEOTOOLBOX(mpeg1),
> +#endif
> +#if CONFIG_MPEG1_XVMC_HWACCEL
> +                               HW_CONFIG_AD_HOC_HWACCEL(XVMC, mpeg1),
> +#endif

This doesn't compile because HW_CONFIG_AD_HOC_HWACCEL doesn't construct
the hwaccel struct name - it just takes it as-s. You should define an
HWACCEL_XVMC like for the others. It'll be less confusing.

> +                               NULL
> +                           },
>  };
>  
>  AVCodec ff_mpeg2video_decoder = {
> @@ -2909,6 +2925,33 @@ AVCodec ff_mpeg2video_decoder = {
>      .flush          = flush,
>      .max_lowres     = 3,
>      .profiles       = NULL_IF_CONFIG_SMALL(ff_mpeg2_video_profiles),
> +    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_MPEG2_DXVA2_HWACCEL
> +                        HWACCEL_DXVA2(mpeg2),
> +#endif
> +#if CONFIG_MPEG2_D3D11VA_HWACCEL
> +                        HWACCEL_D3D11VA(mpeg2),
> +#endif
> +#if CONFIG_MPEG2_D3D11VA2_HWACCEL
> +                        HWACCEL_D3D11VA2(mpeg2),
> +#endif
> +#if CONFIG_MPEG2_NVDEC_HWACCEL
> +                        HWACCEL_NVDEC(mpeg2),
> +#endif
> +#if CONFIG_MPEG2_VAAPI_HWACCEL
> +                        HWACCEL_VAAPI(mpeg2),
> +#endif
> +#if CONFIG_MPEG2_VDPAU_HWACCEL
> +                        HWACCEL_VDPAU(mpeg2),
> +#endif
> +#if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL
> +                        HWACCEL_VIDEOTOOLBOX(mpeg2),
> +#endif
> +#if CONFIG_MPEG2_XVMC_HWACCEL
> +                        HW_CONFIG_AD_HOC_HWACCEL(XVMC, mpeg2),
> +#endif

Same here.

> +                        NULL
> +                    },
>  };
>  
>  //legacy decoder
> diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
> index 69f455e226..19fcc1bc8f 100644
> --- a/libavcodec/mpeg4videodec.c
> +++ b/libavcodec/mpeg4videodec.c
> @@ -25,6 +25,7 @@
>  #include "libavutil/internal.h"
>  #include "libavutil/opt.h"
>  #include "error_resilience.h"
> +#include "hwaccel.h"
>  #include "idctdsp.h"
>  #include "internal.h"
>  #include "mpegutils.h"
> @@ -2855,4 +2856,19 @@ AVCodec ff_mpeg4_decoder = {
>      .profiles              =
> NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), .update_thread_context
> = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context), .priv_class =
> &mpeg4_class,
> +    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_MPEG2_NVDEC_HWACCEL
> +                               HWACCEL_NVDEC(mpeg4),
> +#endif
> +#if CONFIG_MPEG4_VAAPI_HWACCEL
> +                               HWACCEL_VAAPI(mpeg4),
> +#endif
> +#if CONFIG_MPEG4_VDPAU_HWACCEL
> +                               HWACCEL_VDPAU(mpeg4),
> +#endif
> +#if CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL
> +                               HWACCEL_VIDEOTOOLBOX(mpeg4),
> +#endif
> +                               NULL
> +                           },
>  };
> diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
> index c00817f1d9..55fe59b531 100644
> --- a/libavcodec/qsvdec.c
> +++ b/libavcodec/qsvdec.c
> @@ -41,6 +41,19 @@
>  #include "qsv_internal.h"
>  #include "qsvdec.h"
>  
> +const AVCodecHWConfigInternal *ff_qsv_hw_configs[] = {
> +    &(const AVCodecHWConfigInternal) {
> +        .public = {
> +            .pix_fmt     = AV_PIX_FMT_QSV,
> +            .methods     = AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX |
> +                           AV_CODEC_HW_CONFIG_METHOD_AD_HOC,
> +            .device_type = AV_HWDEVICE_TYPE_QSV,
> +        },
> +        .hwaccel = NULL,
> +    },
> +    NULL
> +};
> +
>  static int qsv_init_session(AVCodecContext *avctx, QSVContext *q,
> mfxSession session, AVBufferRef *hw_frames_ref, AVBufferRef
> *hw_device_ref) {
> diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h
> index 4e86e4b7f8..5b7b03a48b 100644
> --- a/libavcodec/qsvdec.h
> +++ b/libavcodec/qsvdec.h
> @@ -33,6 +33,7 @@
>  #include "libavutil/pixfmt.h"
>  
>  #include "avcodec.h"
> +#include "hwaccel.h"
>  #include "qsv_internal.h"
>  
>  typedef struct QSVContext {
> @@ -70,6 +71,8 @@ typedef struct QSVContext {
>      int         nb_ext_buffers;
>  } QSVContext;
>  
> +extern const AVCodecHWConfigInternal *ff_qsv_hw_configs[];
> +
>  int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q,
>                          AVFrame *frame, int *got_frame, AVPacket
> *pkt); 
> diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
> index a6b53cce8d..a8a96442df 100644
> --- a/libavcodec/qsvdec_h2645.c
> +++ b/libavcodec/qsvdec_h2645.c
> @@ -220,6 +220,7 @@ AVCodec ff_hevc_qsv_decoder = {
>                                                      AV_PIX_FMT_P010,
>                                                      AV_PIX_FMT_QSV,
>                                                      AV_PIX_FMT_NONE },
> +    .hw_configs     = ff_qsv_hw_configs,
>      .bsfs           = "hevc_mp4toannexb",
>  };
>  #endif
> @@ -262,6 +263,7 @@ AVCodec ff_h264_qsv_decoder = {
>                                                      AV_PIX_FMT_P010,
>                                                      AV_PIX_FMT_QSV,
>                                                      AV_PIX_FMT_NONE },
> +    .hw_configs     = ff_qsv_hw_configs,
>      .bsfs           = "h264_mp4toannexb",
>  };
>  #endif
> diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c
> index b94093d53c..21aa56492f 100644
> --- a/libavcodec/qsvdec_other.c
> +++ b/libavcodec/qsvdec_other.c
> @@ -190,6 +190,7 @@ AVCodec ff_mpeg2_qsv_decoder = {
>      .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
>                                                      AV_PIX_FMT_QSV,
>                                                      AV_PIX_FMT_NONE },
> +    .hw_configs     = ff_qsv_hw_configs,
>  };
>  #endif
>  
> @@ -225,6 +226,7 @@ AVCodec ff_vc1_qsv_decoder = {
>      .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
>                                                      AV_PIX_FMT_QSV,
>                                                      AV_PIX_FMT_NONE },
> +    .hw_configs     = ff_qsv_hw_configs,
>  };
>  #endif
>  
> @@ -260,5 +262,6 @@ AVCodec ff_vp8_qsv_decoder = {
>      .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
>                                                      AV_PIX_FMT_QSV,
>                                                      AV_PIX_FMT_NONE },
> +    .hw_configs     = ff_qsv_hw_configs,
>  };
>  #endif
> diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
> index 96b8bb5364..f479a7625b 100644
> --- a/libavcodec/vc1dec.c
> +++ b/libavcodec/vc1dec.c
> @@ -29,6 +29,7 @@
>  #include "avcodec.h"
>  #include "blockdsp.h"
>  #include "get_bits.h"
> +#include "hwaccel.h"
>  #include "internal.h"
>  #include "mpeg_er.h"
>  #include "mpegvideo.h"
> @@ -1144,6 +1145,27 @@ AVCodec ff_vc1_decoder = {
>      .flush          = ff_mpeg_flush,
>      .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
>      .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
> +    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_VC1_DXVA2_HWACCEL
> +                        HWACCEL_DXVA2(vc1),
> +#endif
> +#if CONFIG_VC1_D3D11VA_HWACCEL
> +                        HWACCEL_D3D11VA(vc1),
> +#endif
> +#if CONFIG_VC1_D3D11VA2_HWACCEL
> +                        HWACCEL_D3D11VA2(vc1),
> +#endif
> +#if CONFIG_VC1_NVDEC_HWACCEL
> +                        HWACCEL_NVDEC(vc1),
> +#endif
> +#if CONFIG_VC1_VAAPI_HWACCEL
> +                        HWACCEL_VAAPI(vc1),
> +#endif
> +#if CONFIG_VC1_VDPAU_HWACCEL
> +                        HWACCEL_VDPAU(vc1),
> +#endif
> +                        NULL
> +                    },
>      .profiles       = NULL_IF_CONFIG_SMALL(ff_vc1_profiles)
>  };
>  
> @@ -1160,6 +1182,27 @@ AVCodec ff_wmv3_decoder = {
>      .flush          = ff_mpeg_flush,
>      .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
>      .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
> +    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_VC1_DXVA2_HWACCEL
> +                        HWACCEL_DXVA2(wmv3),
> +#endif
> +#if CONFIG_VC1_D3D11VA_HWACCEL
> +                        HWACCEL_D3D11VA(wmv3),
> +#endif
> +#if CONFIG_VC1_D3D11VA2_HWACCEL
> +                        HWACCEL_D3D11VA2(wmv3),
> +#endif
> +#if CONFIG_VC1_NVDEC_HWACCEL
> +                        HWACCEL_NVDEC(wmv3),
> +#endif
> +#if CONFIG_VC1_VAAPI_HWACCEL
> +                        HWACCEL_VAAPI(wmv3),
> +#endif
> +#if CONFIG_VC1_VDPAU_HWACCEL
> +                        HWACCEL_VDPAU(wmv3),
> +#endif
> +                        NULL
> +                    },
>      .profiles       = NULL_IF_CONFIG_SMALL(ff_vc1_profiles)
>  };
>  #endif
> diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
> index 6ce9be61bb..1ea2869c4c 100644
> --- a/libavcodec/vp9.c
> +++ b/libavcodec/vp9.c
> @@ -23,6 +23,7 @@
>  
>  #include "avcodec.h"
>  #include "get_bits.h"
> +#include "hwaccel.h"
>  #include "internal.h"
>  #include "profiles.h"
>  #include "thread.h"
> @@ -1794,4 +1795,22 @@ AVCodec ff_vp9_decoder = {
>      .init_thread_copy      =
> ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy), .update_thread_context
> =
> ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context), .profiles
> = NULL_IF_CONFIG_SMALL(ff_vp9_profiles),
> +    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
> +#if CONFIG_VP9_DXVA2_HWACCEL
> +                               HWACCEL_DXVA2(vp9),
> +#endif
> +#if CONFIG_VP9_D3D11VA_HWACCEL
> +                               HWACCEL_D3D11VA(vp9),
> +#endif
> +#if CONFIG_VP9_D3D11VA2_HWACCEL
> +                               HWACCEL_D3D11VA2(vp9),
> +#endif
> +#if CONFIG_VP9_NVDEC_HWACCEL
> +                               HWACCEL_NVDEC(vp9),
> +#endif
> +#if CONFIG_VP9_VAAPI_HWACCEL
> +                               HWACCEL_VAAPI(vp9),
> +#endif
> +                               NULL
> +                           },
>  };




--phil

Patch hide | download patch | download mbox

diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
index 806dab2074..3bd2409ea2 100644
--- a/libavcodec/cuviddec.c
+++ b/libavcodec/cuviddec.c
@@ -32,6 +32,7 @@ 
 
 #include "avcodec.h"
 #include "decode.h"
+#include "hwaccel.h"
 #include "internal.h"
 
 typedef struct CuvidContext
@@ -1094,6 +1095,19 @@  static const AVOption options[] = {
     { NULL }
 };
 
+static const AVCodecHWConfigInternal *cuvid_hw_configs[] = {
+    &(const AVCodecHWConfigInternal) {
+        .public = {
+            .pix_fmt     = AV_PIX_FMT_CUDA,
+            .methods     = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX |
+                           AV_CODEC_HW_CONFIG_METHOD_INTERNAL,
+            .device_type = AV_HWDEVICE_TYPE_CUDA
+        },
+        .hwaccel = NULL,
+    },
+    NULL
+};
+
 #define DEFINE_CUVID_CODEC(x, X) \
     static const AVClass x##_cuvid_class = { \
         .class_name = #x "_cuvid", \
@@ -1127,6 +1141,7 @@  static const AVOption options[] = {
                                                         AV_PIX_FMT_P010, \
                                                         AV_PIX_FMT_P016, \
                                                         AV_PIX_FMT_NONE }, \
+        .hw_configs     = cuvid_hw_configs, \
     };
 
 #if CONFIG_HEVC_CUVID_DECODER
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index b222de793b..5608b63245 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -33,6 +33,7 @@ 
 #include "flv.h"
 #include "h263.h"
 #include "h263_parser.h"
+#include "hwaccel.h"
 #include "internal.h"
 #include "mpeg_er.h"
 #include "mpeg4video.h"
@@ -759,4 +760,16 @@  AVCodec ff_h263p_decoder = {
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
     .pix_fmts       = ff_h263_hwaccel_pixfmt_list_420,
+    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_H263_VAAPI_HWACCEL
+                        HWACCEL_VAAPI(h263),
+#endif
+#if CONFIG_MPEG4_VDPAU_HWACCEL
+                        HWACCEL_VDPAU(mpeg4),
+#endif
+#if CONFIG_H263_VIDEOTOOLBOX_HWACCEL
+                        HWACCEL_VIDEOTOOLBOX(h263),
+#endif
+                        NULL
+                    },
 };
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index be187eb5f4..b03024d4a3 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -47,6 +47,7 @@ 
 #include "h264_mvpred.h"
 #include "h264_ps.h"
 #include "golomb.h"
+#include "hwaccel.h"
 #include "mathops.h"
 #include "me_cmp.h"
 #include "mpegutils.h"
@@ -1059,6 +1060,30 @@  AVCodec ff_h264_decoder = {
     .capabilities          = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |
                              AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
                              AV_CODEC_CAP_FRAME_THREADS,
+    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_H264_DXVA2_HWACCEL
+                               HWACCEL_DXVA2(h264),
+#endif
+#if CONFIG_H264_D3D11VA_HWACCEL
+                               HWACCEL_D3D11VA(h264),
+#endif
+#if CONFIG_H264_D3D11VA2_HWACCEL
+                               HWACCEL_D3D11VA2(h264),
+#endif
+#if CONFIG_H264_NVDEC_HWACCEL
+                               HWACCEL_NVDEC(h264),
+#endif
+#if CONFIG_H264_VAAPI_HWACCEL
+                               HWACCEL_VAAPI(h264),
+#endif
+#if CONFIG_H264_VDPAU_HWACCEL
+                               HWACCEL_VDPAU(h264),
+#endif
+#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL
+                               HWACCEL_VIDEOTOOLBOX(h264),
+#endif
+                               NULL
+                           },
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING,
     .flush                 = flush_dpb,
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 75960912b1..5ec6105d2f 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -41,6 +41,7 @@ 
 #include "hevc_data.h"
 #include "hevc_parse.h"
 #include "hevcdec.h"
+#include "hwaccel.h"
 #include "profiles.h"
 
 const uint8_t ff_hevc_pel_weight[65] = { [2] = 0, [4] = 1, [6] = 2, [8] = 3, [12] = 4, [16] = 5, [24] = 6, [32] = 7, [48] = 8, [64] = 9 };
@@ -3510,4 +3511,28 @@  AVCodec ff_hevc_decoder = {
                              AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING,
     .profiles              = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
+    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_HEVC_DXVA2_HWACCEL
+                               HWACCEL_DXVA2(hevc),
+#endif
+#if CONFIG_HEVC_D3D11VA_HWACCEL
+                               HWACCEL_D3D11VA(hevc),
+#endif
+#if CONFIG_HEVC_D3D11VA2_HWACCEL
+                               HWACCEL_D3D11VA2(hevc),
+#endif
+#if CONFIG_HEVC_NVDEC_HWACCEL
+                               HWACCEL_NVDEC(hevc),
+#endif
+#if CONFIG_HEVC_VAAPI_HWACCEL
+                               HWACCEL_VAAPI(hevc),
+#endif
+#if CONFIG_HEVC_VDPAU_HWACCEL
+                               HWACCEL_VDPAU(hevc),
+#endif
+#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
+                               HWACCEL_VIDEOTOOLBOX(hevc),
+#endif
+                               NULL
+                           },
 };
diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h
index 0198c7f858..382e0d0264 100644
--- a/libavcodec/hwaccel.h
+++ b/libavcodec/hwaccel.h
@@ -20,6 +20,7 @@ 
 #define AVCODEC_HWACCEL_H
 
 #include "avcodec.h"
+#include "hwaccels.h"
 
 
 #define HWACCEL_CAP_ASYNC_SAFE      (1 << 0)
@@ -39,4 +40,53 @@  typedef struct AVCodecHWConfigInternal {
 } AVCodecHWConfigInternal;
 
 
+// These macros are used to simplify AVCodecHWConfigInternal definitions.
+
+#define HW_CONFIG_HWACCEL(format, device, name) \
+    &(const AVCodecHWConfigInternal) { \
+        .public          = { \
+            .pix_fmt     = AV_PIX_FMT_ ## format, \
+            .methods     = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX | \
+                           AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, \
+            .device_type = AV_HWDEVICE_TYPE_ ## device, \
+        }, \
+        .hwaccel         = &name, \
+    }
+
+#define HW_CONFIG_INTERNAL(format) \
+    &(const AVCodecHWConfigInternal) { \
+        .public          = { \
+            .pix_fmt     = AV_PIX_FMT_ ## format, \
+            .methods     = AV_CODEC_HW_CONFIG_METHOD_INTERNAL, \
+            .device_type = AV_HWDEVICE_TYPE_NONE, \
+        }, \
+        .hwaccel         = NULL, \
+    }
+
+#define HW_CONFIG_AD_HOC_HWACCEL(format, name) \
+    &(const AVCodecHWConfigInternal) { \
+        .public =      { \
+            .pix_fmt     = AV_PIX_FMT_ ## format, \
+            .methods     = AV_CODEC_HW_CONFIG_METHOD_AD_HOC, \
+            .device_type = AV_HWDEVICE_TYPE_NONE, \
+        }, \
+        .hwaccel = &name, \
+    }
+
+#define HWACCEL_DXVA2(codec) \
+    HW_CONFIG_HWACCEL(DXVA2_VLD, DXVA2,   ff_ ## codec ## _dxva2_hwaccel)
+#define HWACCEL_D3D11VA2(codec) \
+    HW_CONFIG_HWACCEL(D3D11,     D3D11VA, ff_ ## codec ## _d3d11va2_hwaccel)
+#define HWACCEL_NVDEC(codec) \
+    HW_CONFIG_HWACCEL(CUDA,      CUDA,    ff_ ## codec ## _nvdec_hwaccel)
+#define HWACCEL_VAAPI(codec) \
+    HW_CONFIG_HWACCEL(VAAPI,     VAAPI,   ff_ ## codec ## _vaapi_hwaccel)
+#define HWACCEL_VDPAU(codec) \
+    HW_CONFIG_HWACCEL(VDPAU,     VDPAU,   ff_ ## codec ## _vdpau_hwaccel)
+#define HWACCEL_VIDEOTOOLBOX(codec) \
+    HW_CONFIG_HWACCEL(VIDEOTOOLBOX, VIDEOTOOLBOX, ff_ ## codec ## _videotoolbox_hwaccel)
+
+#define HWACCEL_D3D11VA(codec) \
+    HW_CONFIG_AD_HOC_HWACCEL(D3D11VA_VLD, ff_ ## codec ## _d3d11va_hwaccel)
+
 #endif /* AVCODEC_HWACCEL_H */
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
new file mode 100644
index 0000000000..9a3008a92c
--- /dev/null
+++ b/libavcodec/hwaccels.h
@@ -0,0 +1,74 @@ 
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_HWACCELS_H
+#define AVCODEC_HWACCELS_H
+
+#include "avcodec.h"
+
+extern AVHWAccel ff_h263_vaapi_hwaccel;
+extern AVHWAccel ff_h263_videotoolbox_hwaccel;
+extern AVHWAccel ff_h264_d3d11va_hwaccel;
+extern AVHWAccel ff_h264_d3d11va2_hwaccel;
+extern AVHWAccel ff_h264_dxva2_hwaccel;
+extern AVHWAccel ff_h264_nvdec_hwaccel;
+extern AVHWAccel ff_h264_vaapi_hwaccel;
+extern AVHWAccel ff_h264_vdpau_hwaccel;
+extern AVHWAccel ff_h264_videotoolbox_hwaccel;
+extern AVHWAccel ff_hevc_d3d11va_hwaccel;
+extern AVHWAccel ff_hevc_d3d11va2_hwaccel;
+extern AVHWAccel ff_hevc_dxva2_hwaccel;
+extern AVHWAccel ff_hevc_nvdec_hwaccel;
+extern AVHWAccel ff_hevc_vaapi_hwaccel;
+extern AVHWAccel ff_hevc_vdpau_hwaccel;
+extern AVHWAccel ff_hevc_videotoolbox_hwaccel;
+extern AVHWAccel ff_mpeg1_nvdec_hwaccel;
+extern AVHWAccel ff_mpeg1_vdpau_hwaccel;
+extern AVHWAccel ff_mpeg1_videotoolbox_hwaccel;
+extern AVHWAccel ff_mpeg1_xvmc_hwaccel;
+extern AVHWAccel ff_mpeg2_d3d11va_hwaccel;
+extern AVHWAccel ff_mpeg2_d3d11va2_hwaccel;
+extern AVHWAccel ff_mpeg2_nvdec_hwaccel;
+extern AVHWAccel ff_mpeg2_dxva2_hwaccel;
+extern AVHWAccel ff_mpeg2_vaapi_hwaccel;
+extern AVHWAccel ff_mpeg2_vdpau_hwaccel;
+extern AVHWAccel ff_mpeg2_videotoolbox_hwaccel;
+extern AVHWAccel ff_mpeg2_xvmc_hwaccel;
+extern AVHWAccel ff_mpeg4_nvdec_hwaccel;
+extern AVHWAccel ff_mpeg4_vaapi_hwaccel;
+extern AVHWAccel ff_mpeg4_vdpau_hwaccel;
+extern AVHWAccel ff_mpeg4_videotoolbox_hwaccel;
+extern AVHWAccel ff_vc1_d3d11va_hwaccel;
+extern AVHWAccel ff_vc1_d3d11va2_hwaccel;
+extern AVHWAccel ff_vc1_dxva2_hwaccel;
+extern AVHWAccel ff_vc1_nvdec_hwaccel;
+extern AVHWAccel ff_vc1_vaapi_hwaccel;
+extern AVHWAccel ff_vc1_vdpau_hwaccel;
+extern AVHWAccel ff_vp9_d3d11va_hwaccel;
+extern AVHWAccel ff_vp9_d3d11va2_hwaccel;
+extern AVHWAccel ff_vp9_dxva2_hwaccel;
+extern AVHWAccel ff_vp9_nvdec_hwaccel;
+extern AVHWAccel ff_vp9_vaapi_hwaccel;
+extern AVHWAccel ff_wmv3_d3d11va_hwaccel;
+extern AVHWAccel ff_wmv3_d3d11va2_hwaccel;
+extern AVHWAccel ff_wmv3_dxva2_hwaccel;
+extern AVHWAccel ff_wmv3_nvdec_hwaccel;
+extern AVHWAccel ff_wmv3_vaapi_hwaccel;
+extern AVHWAccel ff_wmv3_vdpau_hwaccel;
+
+#endif /* AVCODEC_HWACCELS_H */
diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
index 0cf9419ea3..feee316140 100644
--- a/libavcodec/mediacodecdec.c
+++ b/libavcodec/mediacodecdec.c
@@ -515,6 +515,18 @@  static void mediacodec_decode_flush(AVCodecContext *avctx)
     ff_mediacodec_dec_flush(avctx, s->ctx);
 }
 
+static const AVCodecHWConfigInternal *mediacodec_hw_configs[] = {
+    &(const AVCodecHWConfigInternal) {
+        .public          = {
+            .pix_fmt     = AV_PIX_FMT_MEDIACODEC,
+            .methods     = AV_CODEC_HW_CONFIG_METHOD_AD_HOC,
+            .device_type = AV_HWDEVICE_TYPE_NONE,
+        },
+        .hwaccel         = NULL,
+    }
+    NULL
+};
+
 #if CONFIG_H264_MEDIACODEC_DECODER
 AVCodec ff_h264_mediacodec_decoder = {
     .name           = "h264_mediacodec",
@@ -529,6 +541,7 @@  AVCodec ff_h264_mediacodec_decoder = {
     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
     .bsfs           = "h264_mp4toannexb",
+    .hw_configs     = mediacodec_hw_configs,
 };
 #endif
 
@@ -546,6 +559,7 @@  AVCodec ff_hevc_mediacodec_decoder = {
     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
     .bsfs           = "hevc_mp4toannexb",
+    .hw_configs     = mediacodec_hw_configs,
 };
 #endif
 
@@ -562,6 +576,7 @@  AVCodec ff_mpeg2_mediacodec_decoder = {
     .close          = mediacodec_decode_close,
     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
+    .hw_configs     = mediacodec_hw_configs,
 };
 #endif
 
@@ -578,6 +593,7 @@  AVCodec ff_mpeg4_mediacodec_decoder = {
     .close          = mediacodec_decode_close,
     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
+    .hw_configs     = mediacodec_hw_configs,
 };
 #endif
 
@@ -594,6 +610,7 @@  AVCodec ff_vp8_mediacodec_decoder = {
     .close          = mediacodec_decode_close,
     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
+    .hw_configs     = mediacodec_hw_configs,
 };
 #endif
 
@@ -610,5 +627,6 @@  AVCodec ff_vp9_mediacodec_decoder = {
     .close          = mediacodec_decode_close,
     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
+    .hw_configs     = mediacodec_hw_configs,
 };
 #endif
diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c
index f2ee3557aa..836d1e20e0 100644
--- a/libavcodec/mmaldec.c
+++ b/libavcodec/mmaldec.c
@@ -34,6 +34,7 @@ 
 #include <stdatomic.h>
 
 #include "avcodec.h"
+#include "hwaccel.h"
 #include "internal.h"
 #include "libavutil/avassert.h"
 #include "libavutil/buffer.h"
@@ -835,6 +836,11 @@  AVHWAccel ff_vc1_mmal_hwaccel = {
     .pix_fmt    = AV_PIX_FMT_MMAL,
 };
 
+static const AVCodecHWConfigInternal *mmal_hw_configs = {
+    HW_CONFIG_INTERNAL(MMAL),
+    NULL
+};
+
 static const AVOption options[]={
     {"extra_buffers", "extra buffers", offsetof(MMALDecodeContext, extra_buffers), AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
     {"extra_decoder_buffers", "extra MMAL internal buffered frames", offsetof(MMALDecodeContext, extra_decoder_buffers), AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
@@ -867,6 +873,7 @@  static const AVOption options[]={
         .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_MMAL, \
                                                          AV_PIX_FMT_YUV420P, \
                                                          AV_PIX_FMT_NONE}, \
+        .hw_configs     = mmal_hw_configs,
     };
 
 FFMMAL_DEC(h264, AV_CODEC_ID_H264)
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 5a51d09bb0..07c68dbabc 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -36,6 +36,7 @@ 
 #include "avcodec.h"
 #include "bytestream.h"
 #include "error_resilience.h"
+#include "hwaccel.h"
 #include "idctdsp.h"
 #include "internal.h"
 #include "mpeg_er.h"
@@ -2890,7 +2891,22 @@  AVCodec ff_mpeg1video_decoder = {
     .caps_internal         = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush                 = flush,
     .max_lowres            = 3,
-    .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context),
+    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_MPEG2_NVDEC_HWACCEL
+                               HWACCEL_NVDEC(mpeg1),
+#endif
+#if CONFIG_MPEG1_VDPAU_HWACCEL
+                               HWACCEL_VDPAU(mpeg1),
+#endif
+#if CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL
+                               HWACCEL_VIDEOTOOLBOX(mpeg1),
+#endif
+#if CONFIG_MPEG1_XVMC_HWACCEL
+                               HW_CONFIG_AD_HOC_HWACCEL(XVMC, mpeg1),
+#endif
+                               NULL
+                           },
 };
 
 AVCodec ff_mpeg2video_decoder = {
@@ -2909,6 +2925,33 @@  AVCodec ff_mpeg2video_decoder = {
     .flush          = flush,
     .max_lowres     = 3,
     .profiles       = NULL_IF_CONFIG_SMALL(ff_mpeg2_video_profiles),
+    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_MPEG2_DXVA2_HWACCEL
+                        HWACCEL_DXVA2(mpeg2),
+#endif
+#if CONFIG_MPEG2_D3D11VA_HWACCEL
+                        HWACCEL_D3D11VA(mpeg2),
+#endif
+#if CONFIG_MPEG2_D3D11VA2_HWACCEL
+                        HWACCEL_D3D11VA2(mpeg2),
+#endif
+#if CONFIG_MPEG2_NVDEC_HWACCEL
+                        HWACCEL_NVDEC(mpeg2),
+#endif
+#if CONFIG_MPEG2_VAAPI_HWACCEL
+                        HWACCEL_VAAPI(mpeg2),
+#endif
+#if CONFIG_MPEG2_VDPAU_HWACCEL
+                        HWACCEL_VDPAU(mpeg2),
+#endif
+#if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL
+                        HWACCEL_VIDEOTOOLBOX(mpeg2),
+#endif
+#if CONFIG_MPEG2_XVMC_HWACCEL
+                        HW_CONFIG_AD_HOC_HWACCEL(XVMC, mpeg2),
+#endif
+                        NULL
+                    },
 };
 
 //legacy decoder
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 69f455e226..19fcc1bc8f 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -25,6 +25,7 @@ 
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "error_resilience.h"
+#include "hwaccel.h"
 #include "idctdsp.h"
 #include "internal.h"
 #include "mpegutils.h"
@@ -2855,4 +2856,19 @@  AVCodec ff_mpeg4_decoder = {
     .profiles              = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context),
     .priv_class = &mpeg4_class,
+    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_MPEG2_NVDEC_HWACCEL
+                               HWACCEL_NVDEC(mpeg4),
+#endif
+#if CONFIG_MPEG4_VAAPI_HWACCEL
+                               HWACCEL_VAAPI(mpeg4),
+#endif
+#if CONFIG_MPEG4_VDPAU_HWACCEL
+                               HWACCEL_VDPAU(mpeg4),
+#endif
+#if CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL
+                               HWACCEL_VIDEOTOOLBOX(mpeg4),
+#endif
+                               NULL
+                           },
 };
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index c00817f1d9..55fe59b531 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -41,6 +41,19 @@ 
 #include "qsv_internal.h"
 #include "qsvdec.h"
 
+const AVCodecHWConfigInternal *ff_qsv_hw_configs[] = {
+    &(const AVCodecHWConfigInternal) {
+        .public = {
+            .pix_fmt     = AV_PIX_FMT_QSV,
+            .methods     = AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX |
+                           AV_CODEC_HW_CONFIG_METHOD_AD_HOC,
+            .device_type = AV_HWDEVICE_TYPE_QSV,
+        },
+        .hwaccel = NULL,
+    },
+    NULL
+};
+
 static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session,
                             AVBufferRef *hw_frames_ref, AVBufferRef *hw_device_ref)
 {
diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h
index 4e86e4b7f8..5b7b03a48b 100644
--- a/libavcodec/qsvdec.h
+++ b/libavcodec/qsvdec.h
@@ -33,6 +33,7 @@ 
 #include "libavutil/pixfmt.h"
 
 #include "avcodec.h"
+#include "hwaccel.h"
 #include "qsv_internal.h"
 
 typedef struct QSVContext {
@@ -70,6 +71,8 @@  typedef struct QSVContext {
     int         nb_ext_buffers;
 } QSVContext;
 
+extern const AVCodecHWConfigInternal *ff_qsv_hw_configs[];
+
 int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q,
                         AVFrame *frame, int *got_frame, AVPacket *pkt);
 
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index a6b53cce8d..a8a96442df 100644
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -220,6 +220,7 @@  AVCodec ff_hevc_qsv_decoder = {
                                                     AV_PIX_FMT_P010,
                                                     AV_PIX_FMT_QSV,
                                                     AV_PIX_FMT_NONE },
+    .hw_configs     = ff_qsv_hw_configs,
     .bsfs           = "hevc_mp4toannexb",
 };
 #endif
@@ -262,6 +263,7 @@  AVCodec ff_h264_qsv_decoder = {
                                                     AV_PIX_FMT_P010,
                                                     AV_PIX_FMT_QSV,
                                                     AV_PIX_FMT_NONE },
+    .hw_configs     = ff_qsv_hw_configs,
     .bsfs           = "h264_mp4toannexb",
 };
 #endif
diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c
index b94093d53c..21aa56492f 100644
--- a/libavcodec/qsvdec_other.c
+++ b/libavcodec/qsvdec_other.c
@@ -190,6 +190,7 @@  AVCodec ff_mpeg2_qsv_decoder = {
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
                                                     AV_PIX_FMT_QSV,
                                                     AV_PIX_FMT_NONE },
+    .hw_configs     = ff_qsv_hw_configs,
 };
 #endif
 
@@ -225,6 +226,7 @@  AVCodec ff_vc1_qsv_decoder = {
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
                                                     AV_PIX_FMT_QSV,
                                                     AV_PIX_FMT_NONE },
+    .hw_configs     = ff_qsv_hw_configs,
 };
 #endif
 
@@ -260,5 +262,6 @@  AVCodec ff_vp8_qsv_decoder = {
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
                                                     AV_PIX_FMT_QSV,
                                                     AV_PIX_FMT_NONE },
+    .hw_configs     = ff_qsv_hw_configs,
 };
 #endif
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 96b8bb5364..f479a7625b 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -29,6 +29,7 @@ 
 #include "avcodec.h"
 #include "blockdsp.h"
 #include "get_bits.h"
+#include "hwaccel.h"
 #include "internal.h"
 #include "mpeg_er.h"
 #include "mpegvideo.h"
@@ -1144,6 +1145,27 @@  AVCodec ff_vc1_decoder = {
     .flush          = ff_mpeg_flush,
     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
+    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_VC1_DXVA2_HWACCEL
+                        HWACCEL_DXVA2(vc1),
+#endif
+#if CONFIG_VC1_D3D11VA_HWACCEL
+                        HWACCEL_D3D11VA(vc1),
+#endif
+#if CONFIG_VC1_D3D11VA2_HWACCEL
+                        HWACCEL_D3D11VA2(vc1),
+#endif
+#if CONFIG_VC1_NVDEC_HWACCEL
+                        HWACCEL_NVDEC(vc1),
+#endif
+#if CONFIG_VC1_VAAPI_HWACCEL
+                        HWACCEL_VAAPI(vc1),
+#endif
+#if CONFIG_VC1_VDPAU_HWACCEL
+                        HWACCEL_VDPAU(vc1),
+#endif
+                        NULL
+                    },
     .profiles       = NULL_IF_CONFIG_SMALL(ff_vc1_profiles)
 };
 
@@ -1160,6 +1182,27 @@  AVCodec ff_wmv3_decoder = {
     .flush          = ff_mpeg_flush,
     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
+    .hw_configs     = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_VC1_DXVA2_HWACCEL
+                        HWACCEL_DXVA2(wmv3),
+#endif
+#if CONFIG_VC1_D3D11VA_HWACCEL
+                        HWACCEL_D3D11VA(wmv3),
+#endif
+#if CONFIG_VC1_D3D11VA2_HWACCEL
+                        HWACCEL_D3D11VA2(wmv3),
+#endif
+#if CONFIG_VC1_NVDEC_HWACCEL
+                        HWACCEL_NVDEC(wmv3),
+#endif
+#if CONFIG_VC1_VAAPI_HWACCEL
+                        HWACCEL_VAAPI(wmv3),
+#endif
+#if CONFIG_VC1_VDPAU_HWACCEL
+                        HWACCEL_VDPAU(wmv3),
+#endif
+                        NULL
+                    },
     .profiles       = NULL_IF_CONFIG_SMALL(ff_vc1_profiles)
 };
 #endif
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 6ce9be61bb..1ea2869c4c 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -23,6 +23,7 @@ 
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "hwaccel.h"
 #include "internal.h"
 #include "profiles.h"
 #include "thread.h"
@@ -1794,4 +1795,22 @@  AVCodec ff_vp9_decoder = {
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context),
     .profiles              = NULL_IF_CONFIG_SMALL(ff_vp9_profiles),
+    .hw_configs            = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_VP9_DXVA2_HWACCEL
+                               HWACCEL_DXVA2(vp9),
+#endif
+#if CONFIG_VP9_D3D11VA_HWACCEL
+                               HWACCEL_D3D11VA(vp9),
+#endif
+#if CONFIG_VP9_D3D11VA2_HWACCEL
+                               HWACCEL_D3D11VA2(vp9),
+#endif
+#if CONFIG_VP9_NVDEC_HWACCEL
+                               HWACCEL_NVDEC(vp9),
+#endif
+#if CONFIG_VP9_VAAPI_HWACCEL
+                               HWACCEL_VAAPI(vp9),
+#endif
+                               NULL
+                           },
 };