From 720cf4e6e7dcaa4032b9448cb6b6cc4671a6f108 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:39 +0100 Subject: [PATCH 1/9] lavc: Add codec metadata to indicate hardware support --- doc/APIchanges | 3 ++ libavcodec/avcodec.h | 74 ++++++++++++++++++++++++++++++++++++++++++++ libavcodec/hwaccel.h | 18 +++++++++++ libavcodec/utils.c | 12 +++++++ libavcodec/version.h | 2 +- 5 files changed, 108 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index a7ecbcdaae..f5f15c49a1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2017-03-23 API changes, most recent first: +2017-xx-xx - xxxxxxx - lavc 58.6.0 - avcodec.h + Add AVCodecHWConfig and avcodec_get_hw_config(). + 2017-xx-xx - xxxxxxx - lavu 56.7.0 - stereo3d.h Add view field to AVStereo3D structure and AVStereo3DView enum. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index ec952dd0e8..cf9f9dfe84 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -35,6 +35,7 @@ #include "libavutil/cpu.h" #include "libavutil/dict.h" #include "libavutil/frame.h" +#include "libavutil/hwcontext.h" #include "libavutil/log.h" #include "libavutil/pixfmt.h" #include "libavutil/rational.h" @@ -2748,6 +2749,61 @@ typedef struct AVProfile { const char *name; ///< short name for the profile } AVProfile; +enum { + /** + * The codec supports this format via the hw_device_ctx interface. + * + * When selecting this format, AVCodecContext.hw_device_ctx should + * have been set to a device of the specified type before calling + * avcodec_open2(). + */ + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01, + /** + * The codec supports this format via the hw_frames_ctx interface. + * + * When selecting this format for a decoder, + * AVCodecContext.hw_frames_ctx should be set to a suitable frames + * context inside the get_format() callback. The frames context + * must have been created on a device of the specified type. + */ + AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02, + /** + * The codec supports this format by some internal method. + * + * This format can be selected without any additional configuration - + * no device or frames context is required. + */ + AV_CODEC_HW_CONFIG_METHOD_INTERNAL = 0x04, + /** + * The codec supports this format by some ad-hoc method. + * + * Additional settings and/or function calls are required. See the + * codec-specific documentation for details. (Methods requiring + * this sort of configuration are deprecated and others should be + * used in preference.) + */ + AV_CODEC_HW_CONFIG_METHOD_AD_HOC = 0x08, +}; + +typedef struct AVCodecHWConfig { + /** + * A hardware pixel format which the codec can use. + */ + enum AVPixelFormat pix_fmt; + /** + * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible + * setup methods which can be used with this configuration. + */ + int methods; + /** + * The device type associated with the configuration. + * + * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and + * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused. + */ + enum AVHWDeviceType device_type; +} AVCodecHWConfig; + typedef struct AVCodecDefault AVCodecDefault; struct AVSubtitle; @@ -2884,8 +2940,26 @@ typedef struct AVCodec { * packets before decoding. */ const char *bsfs; + + /** + * Array of pointers to hardware configurations supported by the codec, + * or NULL if no hardware supported. The array is terminated by a NULL + * pointer. + * + * The user can only access this field via avcodec_get_hw_config(). + */ + const struct AVCodecHWConfigInternal **hw_configs; } AVCodec; +/** + * Retrieve supported hardware configurations for a codec. + * + * Values of index from zero to some maximum return the indexed configuration + * descriptor; all other values return NULL. If the codec does not support + * any hardware configurations then it will always return NULL. + */ +const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index); + /** * @defgroup lavc_hwaccel AVHWAccel * @{ diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h index 60dbe81c8b..b6d5662482 100644 --- a/libavcodec/hwaccel.h +++ b/libavcodec/hwaccel.h @@ -19,6 +19,24 @@ #ifndef AVCODEC_HWACCEL_H #define AVCODEC_HWACCEL_H +#include "avcodec.h" + + #define HWACCEL_CAP_ASYNC_SAFE (1 << 0) + +typedef struct AVCodecHWConfigInternal { + /** + * This is the structure which will be returned to the user by + * avcodec_get_hw_config(). + */ + AVCodecHWConfig public; + /** + * If this configuration uses a hwaccel, a pointer to it. + * If not, NULL. + */ + const AVHWAccel *hwaccel; +} AVCodecHWConfigInternal; + + #endif /* AVCODEC_HWACCEL_H */ diff --git a/libavcodec/utils.c b/libavcodec/utils.c index bc421f67f8..3d6b35fa41 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -41,6 +41,7 @@ #include "libavutil/dict.h" #include "avcodec.h" #include "decode.h" +#include "hwaccel.h" #include "libavutil/opt.h" #include "me_cmp.h" #include "mpegvideo.h" @@ -1335,6 +1336,17 @@ int ff_match_2uint16(const uint16_t(*tab)[2], int size, int a, int b) return i; } +const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index) +{ + int i; + if (!codec->hw_configs || index < 0) + return NULL; + for (i = 0; i <= index; i++) + if (!codec->hw_configs[i]) + return NULL; + return &codec->hw_configs[index]->public; +} + static AVHWAccel *first_hwaccel = NULL; void av_register_hwaccel(AVHWAccel *hwaccel) diff --git a/libavcodec/version.h b/libavcodec/version.h index aa6cdcd6bc..e6edd5c867 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 5 +#define LIBAVCODEC_VERSION_MINOR 6 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From 2fcb0090115f7fc7648ad241a5903f866760d4b6 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:40 +0100 Subject: [PATCH 2/9] lavc: Add hardware config metadata for decoders supporting hardware output 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/h263dec.c | 10 +++++++ libavcodec/h264dec.c | 28 ++++++++++++++++++ libavcodec/hevcdec.c | 22 ++++++++++++++ libavcodec/hwaccel.h | 38 ++++++++++++++++++++++++ libavcodec/hwaccels.h | 59 ++++++++++++++++++++++++++++++++++++++ libavcodec/mmaldec.c | 7 +++++ libavcodec/mpeg12dec.c | 27 ++++++++++++++++- libavcodec/mpeg4videodec.c | 10 +++++++ libavcodec/qsvdec.c | 13 +++++++++ libavcodec/qsvdec.h | 3 ++ libavcodec/qsvdec_h2645.c | 2 ++ libavcodec/qsvdec_other.c | 3 ++ libavcodec/vc1dec.c | 37 ++++++++++++++++++++++++ libavcodec/vp8.c | 7 +++++ 14 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 libavcodec/hwaccels.h diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 921ff5fb98..b0000883c1 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -31,6 +31,7 @@ #include "flv.h" #include "h263.h" #include "h263_parser.h" +#include "hwaccel.h" #include "internal.h" #include "mpeg_er.h" #include "mpeg4video.h" @@ -677,4 +678,13 @@ AVCodec ff_h263_decoder = { AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, .flush = ff_mpeg_flush, .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 + NULL + }, }; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 7a8293efa5..4bfd78962d 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -44,6 +44,7 @@ #include "h264chroma.h" #include "h264_mvpred.h" #include "h264_ps.h" +#include "hwaccel.h" #include "mathops.h" #include "me_cmp.h" #include "mpegutils.h" @@ -786,6 +787,33 @@ 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_CUVID_HWACCEL + HWACCEL_CUVID(h264), +#endif +#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_VAAPI_HWACCEL + HWACCEL_VAAPI(h264), +#endif +#if CONFIG_H264_VDPAU_HWACCEL + HWACCEL_VDPAU(h264), +#endif +#if CONFIG_H264_VDA_HWACCEL + HW_CONFIG_HWACCEL(0, 0, 1, VDA, NONE, ff_h264_vda_hwaccel), +#endif +#if CONFIG_H264_VDA_OLD_HWACCEL + HW_CONFIG_HWACCEL(0, 0, 1, VDA_VLD, NONE, ff_h264_vda_old_hwaccel), +#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 f1d1c77497..130b99f77e 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -39,6 +39,7 @@ #include "hevc.h" #include "hevc_data.h" #include "hevcdec.h" +#include "hwaccel.h" #include "profiles.h" const uint8_t ff_hevc_qpel_extra_before[4] = { 0, 3, 3, 3 }; @@ -3120,4 +3121,25 @@ AVCodec ff_hevc_decoder = { AV_CODEC_CAP_FRAME_THREADS, .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_INIT_THREADSAFE, + .hw_configs = (const AVCodecHWConfigInternal*[]) { +#if CONFIG_HEVC_CUVID_HWACCEL + HWACCEL_CUVID(hevc), +#endif +#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_VAAPI_HWACCEL + HWACCEL_VAAPI(hevc), +#endif +#if CONFIG_HEVC_VDPAU_HWACCEL + HWACCEL_VDPAU(hevc), +#endif + NULL + }, }; diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h index b6d5662482..e215736c2c 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,41 @@ typedef struct AVCodecHWConfigInternal { } AVCodecHWConfigInternal; +// These macros are used to simplify AVCodecHWConfigInternal definitions. + +#define HW_CONFIG_HWACCEL(device, frames, ad_hoc, format, device_type_, name) \ + &(const AVCodecHWConfigInternal) { \ + .public = { \ + .pix_fmt = AV_PIX_FMT_ ## format, \ + .methods = (device ? AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX : 0) | \ + (frames ? AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX : 0) | \ + (ad_hoc ? AV_CODEC_HW_CONFIG_METHOD_AD_HOC : 0), \ + .device_type = AV_HWDEVICE_TYPE_ ## device_type_, \ + }, \ + .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 HWACCEL_CUVID(codec) \ + HW_CONFIG_HWACCEL(1, 1, 0, CUDA, CUDA, ff_ ## codec ## _cuvid_hwaccel) +#define HWACCEL_DXVA2(codec) \ + HW_CONFIG_HWACCEL(1, 1, 1, DXVA2_VLD, DXVA2, ff_ ## codec ## _dxva2_hwaccel) +#define HWACCEL_D3D11VA2(codec) \ + HW_CONFIG_HWACCEL(1, 1, 0, D3D11, D3D11VA, ff_ ## codec ## _d3d11va2_hwaccel) +#define HWACCEL_VAAPI(codec) \ + HW_CONFIG_HWACCEL(1, 1, 1, VAAPI, VAAPI, ff_ ## codec ## _vaapi_hwaccel) +#define HWACCEL_VDPAU(codec) \ + HW_CONFIG_HWACCEL(1, 1, 1, VDPAU, VDPAU, ff_ ## codec ## _vdpau_hwaccel) +#define HWACCEL_D3D11VA(codec) \ + HW_CONFIG_HWACCEL(0, 0, 1, D3D11VA_VLD, NONE, ff_ ## codec ## _d3d11va_hwaccel) + #endif /* AVCODEC_HWACCEL_H */ diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h new file mode 100644 index 0000000000..6dee94b44f --- /dev/null +++ b/libavcodec/hwaccels.h @@ -0,0 +1,59 @@ +/* + * This file is part of Libav. + * + * Libav 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. + * + * Libav 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 Libav; 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_h264_cuvid_hwaccel; +extern AVHWAccel ff_h264_d3d11va_hwaccel; +extern AVHWAccel ff_h264_d3d11va2_hwaccel; +extern AVHWAccel ff_h264_dxva2_hwaccel; +extern AVHWAccel ff_h264_vaapi_hwaccel; +extern AVHWAccel ff_h264_vda_hwaccel; +extern AVHWAccel ff_h264_vda_old_hwaccel; +extern AVHWAccel ff_h264_vdpau_hwaccel; +extern AVHWAccel ff_hevc_cuvid_hwaccel; +extern AVHWAccel ff_hevc_d3d11va_hwaccel; +extern AVHWAccel ff_hevc_d3d11va2_hwaccel; +extern AVHWAccel ff_hevc_dxva2_hwaccel; +extern AVHWAccel ff_hevc_vaapi_hwaccel; +extern AVHWAccel ff_hevc_vdpau_hwaccel; +extern AVHWAccel ff_mpeg1_vdpau_hwaccel; +extern AVHWAccel ff_mpeg2_d3d11va_hwaccel; +extern AVHWAccel ff_mpeg2_d3d11va2_hwaccel; +extern AVHWAccel ff_mpeg2_dxva2_hwaccel; +extern AVHWAccel ff_mpeg2_vaapi_hwaccel; +extern AVHWAccel ff_mpeg2_vdpau_hwaccel; +extern AVHWAccel ff_mpeg4_vaapi_hwaccel; +extern AVHWAccel ff_mpeg4_vdpau_hwaccel; +extern AVHWAccel ff_vc1_d3d11va_hwaccel; +extern AVHWAccel ff_vc1_d3d11va2_hwaccel; +extern AVHWAccel ff_vc1_dxva2_hwaccel; +extern AVHWAccel ff_vc1_vaapi_hwaccel; +extern AVHWAccel ff_vc1_vdpau_hwaccel; +extern AVHWAccel ff_vp8_vaapi_hwaccel; +extern AVHWAccel ff_wmv3_d3d11va_hwaccel; +extern AVHWAccel ff_wmv3_d3d11va2_hwaccel; +extern AVHWAccel ff_wmv3_dxva2_hwaccel; +extern AVHWAccel ff_wmv3_vaapi_hwaccel; +extern AVHWAccel ff_wmv3_vdpau_hwaccel; + +#endif /* AVCODEC_HWACCELS_H */ diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 3e480ab49a..9ed8e61371 100644 --- a/libavcodec/mmaldec.c +++ b/libavcodec/mmaldec.c @@ -34,6 +34,7 @@ #include #include "avcodec.h" +#include "hwaccel.h" #include "internal.h" #include "libavutil/avassert.h" #include "libavutil/buffer.h" @@ -808,6 +809,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}, @@ -840,6 +846,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, \ .wrapper_name = "mmal", \ }; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 9a9a92701a..532934ccba 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -34,6 +34,7 @@ #include "avcodec.h" #include "bytestream.h" #include "error_resilience.h" +#include "hwaccel.h" #include "idctdsp.h" #include "internal.h" #include "mpeg_er.h" @@ -2594,7 +2595,13 @@ AVCodec ff_mpeg1video_decoder = { AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, .flush = flush, - .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_MPEG1_VDPAU_HWACCEL + HWACCEL_VDPAU(mpeg1), +#endif + NULL + }, }; AVCodec ff_mpeg2video_decoder = { @@ -2611,4 +2618,22 @@ AVCodec ff_mpeg2video_decoder = { AV_CODEC_CAP_SLICE_THREADS, .flush = flush, .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_VAAPI_HWACCEL + HWACCEL_VAAPI(mpeg2), +#endif +#if CONFIG_MPEG2_VDPAU_HWACCEL + HWACCEL_VDPAU(mpeg2), +#endif + NULL + }, }; diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index eb1b67273b..566fd3a898 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -21,6 +21,7 @@ */ #include "error_resilience.h" +#include "hwaccel.h" #include "idctdsp.h" #include "internal.h" #include "mpegutils.h" @@ -2625,6 +2626,15 @@ AVCodec ff_mpeg4_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, + .hw_configs = (const AVCodecHWConfigInternal*[]) { +#if CONFIG_MPEG4_VAAPI_HWACCEL + HWACCEL_VAAPI(mpeg4), +#endif +#if CONFIG_MPEG4_VDPAU_HWACCEL + HWACCEL_VDPAU(mpeg4), +#endif + NULL + }, .flush = ff_mpeg_flush, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 2c90436a17..c74ec68369 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 c6ec99af15..e25c4d6c93 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 03ba303c95..a7b39da6bf 100644 --- a/libavcodec/qsvdec_h2645.c +++ b/libavcodec/qsvdec_h2645.c @@ -226,6 +226,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", .wrapper_name = "qsv", }; @@ -269,6 +270,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", .wrapper_name = "qsv", }; diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c index 0cea4eee92..63cc113c5c 100644 --- a/libavcodec/qsvdec_other.c +++ b/libavcodec/qsvdec_other.c @@ -195,6 +195,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, .wrapper_name = "qsv", }; #endif @@ -231,6 +232,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, .wrapper_name = "qsv", }; #endif @@ -267,6 +269,7 @@ 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, .wrapper_name = "qsv", }; #endif diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 5e00a33e3d..890211019a 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" @@ -986,6 +987,24 @@ 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_VAAPI_HWACCEL + HWACCEL_VAAPI(vc1), +#endif +#if CONFIG_VC1_VDPAU_HWACCEL + HWACCEL_VDPAU(vc1), +#endif + NULL + }, .profiles = NULL_IF_CONFIG_SMALL(ff_vc1_profiles) }; @@ -1002,6 +1021,24 @@ 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_WMV3_DXVA2_HWACCEL + HWACCEL_DXVA2(wmv3), +#endif +#if CONFIG_WMV3_D3D11VA_HWACCEL + HWACCEL_D3D11VA(wmv3), +#endif +#if CONFIG_WMV3_D3D11VA2_HWACCEL + HWACCEL_D3D11VA2(wmv3), +#endif +#if CONFIG_WMV3_VAAPI_HWACCEL + HWACCEL_VAAPI(wmv3), +#endif +#if CONFIG_WMV3_VDPAU_HWACCEL + HWACCEL_VDPAU(wmv3), +#endif + NULL + }, .profiles = NULL_IF_CONFIG_SMALL(ff_vc1_profiles) }; #endif diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 43580a3a81..6d1a399304 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -27,6 +27,7 @@ #include "libavutil/imgutils.h" #include "avcodec.h" +#include "hwaccel.h" #include "internal.h" #include "mathops.h" #include "rectangle.h" @@ -2851,6 +2852,12 @@ AVCodec ff_vp8_decoder = { .decode = ff_vp8_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, + .hw_configs = (const AVCodecHWConfigInternal*[]) { +#if CONFIG_VP8_VAAPI_HWACCEL + HWACCEL_VAAPI(vp8), +#endif + NULL + }, .flush = vp8_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context), From 57623cba1301ee7874687dd7e04c611051638e9d Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:42 +0100 Subject: [PATCH 3/9] webp: Fix alpha initialisation ff_get_format() in the next patch will reject formats which aren't in the offered list, so the hack in 7cb9296db872c4221453e5411f242ebcfca62664 is no longer valid. Change the hack by adding a new field in the VP8 decoder context to indicate that it's actually WebP and don't call ff_get_format() at all in that case. --- libavcodec/vp8.c | 4 +++- libavcodec/vp8.h | 1 + libavcodec/webp.c | 16 +++++----------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 6d1a399304..5c0b4749ad 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2515,7 +2515,9 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ret < 0) goto err; - if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) { + if (s->actually_webp) { + // avctx->pix_fmt already set in caller. + } else if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) { enum AVPixelFormat pix_fmts[] = { #if CONFIG_VP8_VAAPI_HWACCEL AV_PIX_FMT_VAAPI, diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index 1870705ad2..1bf7561d05 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -140,6 +140,7 @@ typedef struct VP8Context { VP8ThreadData *thread_data; AVCodecContext *avctx; enum AVPixelFormat pix_fmt; + int actually_webp; VP8Frame *framep[4]; VP8Frame *next_framep[4]; diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 18d68e9140..0e769c307d 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -1288,16 +1288,6 @@ static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p, return 0; } -static enum AVPixelFormat webp_get_format(AVCodecContext *avctx, - const enum AVPixelFormat *formats) -{ - WebPContext *s = avctx->priv_data; - if (s->has_alpha) - return AV_PIX_FMT_YUVA420P; - else - return AV_PIX_FMT_YUV420P; -} - static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, uint8_t *data_start, unsigned int data_size) @@ -1309,7 +1299,11 @@ static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, if (!s->initialized) { ff_vp8_decode_init(avctx); s->initialized = 1; - avctx->get_format = webp_get_format; + s->v.actually_webp = 1; + if (s->has_alpha) + avctx->pix_fmt = AV_PIX_FMT_YUVA420P; + else + avctx->pix_fmt = AV_PIX_FMT_YUV420P; } s->lossless = 0; From 39056b5240524e4119fa630240f9b45ea0230aad Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:43 +0100 Subject: [PATCH 4/9] lavc: Use hardware config information in ff_get_format() This removes the dependency that hardware pixel formats previously had on AVHWAccel instances, meaning only those which actually do something need exist after this patch. Also updates avcodec_default_get_format() to be able to choose hardware formats if either a matching device has been supplied or no additional external configuration is required, and avcodec_get_hw_frames_parameters() to use the hardware config rather than searching the old hwaccel list. --- libavcodec/decode.c | 281 ++++++++++++++++++++++++++++++------------ libavcodec/internal.h | 6 + 2 files changed, 210 insertions(+), 77 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 27f75d73e3..bc2208a3fd 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -34,6 +34,7 @@ #include "avcodec.h" #include "bytestream.h" #include "decode.h" +#include "hwaccel.h" #include "internal.h" #include "thread.h" @@ -644,29 +645,67 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, return ret; } -static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *avctx, + const enum AVPixelFormat *fmt) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; -} - -enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) -{ - while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) - ++fmt; - return fmt[0]; -} - -static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, - enum AVPixelFormat pix_fmt) -{ - AVHWAccel *hwaccel = NULL; + const AVPixFmtDescriptor *desc; + const AVCodecHWConfig *config; + int i, n; + + // If a device was supplied when the codec was opened, assume that the + // user wants to use it. + if (avctx->hw_device_ctx && avctx->codec->hw_configs) { + AVHWDeviceContext *device_ctx = + (AVHWDeviceContext*)avctx->hw_device_ctx->data; + for (i = 0;; i++) { + config = &avctx->codec->hw_configs[i]->public; + if (!config) + break; + if (!(config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) + continue; + if (device_ctx->type != config->device_type) + continue; + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) { + if (config->pix_fmt == fmt[n]) + return fmt[n]; + } + } + } + // No device or other setup, so we have to choose from things which + // don't any other external information. + + // If the last element of the list is a software format, choose it + // (this should be best software format if any exist). + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++); + desc = av_pix_fmt_desc_get(fmt[n - 1]); + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + return fmt[n - 1]; + + // Finally, traverse the list in order and choose the first entry + // with no external dependencies (if there is no hardware configuration + // information available then this just picks the first entry). + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) { + for (i = 0;; i++) { + config = avcodec_get_hw_config(avctx->codec, i); + if (!config) + break; + if (config->pix_fmt == fmt[n]) + break; + } + if (!config) { + // No specific config available, so the decoder must be able + // to handle this format without any additional setup. + return fmt[n]; + } + if (config->methods & AV_CODEC_HW_CONFIG_METHOD_INTERNAL) { + // Usable with only internal setup. + return fmt[n]; + } + } - while ((hwaccel = av_hwaccel_next(hwaccel))) - if (hwaccel->id == codec_id - && hwaccel->pix_fmt == pix_fmt) - return hwaccel; - return NULL; + // Nothing is usable, give up. + return AV_PIX_FMT_NONE; } int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, @@ -730,9 +769,19 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, AVBufferRef **out_frames_ref) { AVBufferRef *frames_ref = NULL; - AVHWAccel *hwa = find_hwaccel(avctx->codec_id, hw_pix_fmt); - int ret; + const AVCodecHWConfigInternal *hw_config; + const AVHWAccel *hwa; + int i, ret; + + for (i = 0;; i++) { + hw_config = avctx->codec->hw_configs[i]; + if (!hw_config) + return AVERROR(ENOENT); + if (hw_config->public.pix_fmt == hw_pix_fmt) + break; + } + hwa = hw_config->hwaccel; if (!hwa || !hwa->frame_params) return AVERROR(ENOENT); @@ -749,52 +798,66 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, return ret; } -static int setup_hwaccel(AVCodecContext *avctx, - const enum AVPixelFormat fmt, - const char *name) +static int hwaccel_init(AVCodecContext *avctx, + const AVCodecHWConfigInternal *hw_config) { - AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt); - int ret = 0; - - if (!hwa) { - av_log(avctx, AV_LOG_ERROR, - "Could not find an AVHWAccel for the pixel format: %s", - name); - return AVERROR(ENOENT); - } + const AVHWAccel *hwaccel; + int err; - if (hwa->priv_data_size) { - avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size); + hwaccel = hw_config->hwaccel; + if (hwaccel->priv_data_size) { + avctx->internal->hwaccel_priv_data = + av_mallocz(hwaccel->priv_data_size); if (!avctx->internal->hwaccel_priv_data) return AVERROR(ENOMEM); } - avctx->hwaccel = hwa; - if (hwa->init) { - ret = hwa->init(avctx); - if (ret < 0) { - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; - return ret; - } + avctx->hwaccel = (AVHWAccel*)hwaccel; + err = hwaccel->init(avctx); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed setup for format %s: " + "hwaccel initialisation returned error.\n", + av_get_pix_fmt_name(hw_config->public.pix_fmt)); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + return err; } return 0; } +static void hwaccel_uninit(AVCodecContext *avctx) +{ + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + + av_freep(&avctx->internal->hwaccel_priv_data); + + avctx->hwaccel = NULL; + + av_buffer_unref(&avctx->hw_frames_ctx); +} + int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) { const AVPixFmtDescriptor *desc; enum AVPixelFormat *choices; - enum AVPixelFormat ret; - unsigned n = 0; - - while (fmt[n] != AV_PIX_FMT_NONE) - ++n; - + enum AVPixelFormat ret, user_choice; + const AVCodecHWConfigInternal *hw_config; + const AVCodecHWConfig *config; + int i, n, err; + + // Find end of list. + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++); + // Must contain at least one entry. av_assert0(n >= 1); - avctx->sw_pix_fmt = fmt[n - 1]; - av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); + // If a software format is available, it must be the last entry. + desc = av_pix_fmt_desc_get(fmt[n - 1]); + if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + // No software format is available. + } else { + avctx->sw_pix_fmt = fmt[n - 1]; + } choices = av_malloc_array(n + 1, sizeof(*choices)); if (!choices) @@ -803,44 +866,108 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) memcpy(choices, fmt, (n + 1) * sizeof(*choices)); for (;;) { - if (avctx->hwaccel && avctx->hwaccel->uninit) - avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; - - av_buffer_unref(&avctx->hw_frames_ctx); + // Remove the previous hwaccel, if there was one. + hwaccel_uninit(avctx); - ret = avctx->get_format(avctx, choices); + user_choice = avctx->get_format(avctx, choices); + if (user_choice == AV_PIX_FMT_NONE) { + // Explicitly chose nothing, give up. + ret = AV_PIX_FMT_NONE; + break; + } - desc = av_pix_fmt_desc_get(ret); + desc = av_pix_fmt_desc_get(user_choice); if (!desc) { + av_log(avctx, AV_LOG_ERROR, "Invalid format returned by " + "get_format() callback.\n"); ret = AV_PIX_FMT_NONE; break; } + av_log(avctx, AV_LOG_DEBUG, "Format %s chosen by get_format().\n", + desc->name); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + for (i = 0; i < n; i++) { + if (choices[i] == user_choice) + break; + } + if (i == n) { + av_log(avctx, AV_LOG_ERROR, "Invalid return from get_format(): " + "%s not in possible list.\n", desc->name); break; + } - if (avctx->hw_frames_ctx) { - AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; - if (hw_frames_ctx->format != ret) { - av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " - "does not match the format of provided AVHWFramesContext\n"); - ret = AV_PIX_FMT_NONE; - break; + if (avctx->codec->hw_configs) { + for (i = 0;; i++) { + hw_config = avctx->codec->hw_configs[i]; + if (!hw_config) + break; + if (hw_config->public.pix_fmt == user_choice) + break; } + } else { + hw_config = NULL; } - if (!setup_hwaccel(avctx, ret, desc->name)) + if (!hw_config) { + // No config available, so no extra setup required. + ret = user_choice; break; + } + config = &hw_config->public; + + if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX && + avctx->hw_frames_ctx) { + const AVHWFramesContext *frames_ctx = + (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (frames_ctx->format != user_choice) { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "does not match the format of the provided frames " + "context.\n", desc->name); + goto try_again; + } + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && + avctx->hw_device_ctx) { + const AVHWDeviceContext *device_ctx = + (AVHWDeviceContext*)avctx->hw_device_ctx->data; + if (device_ctx->type != config->device_type) { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "does not match the type of the provided device " + "context.\n", desc->name); + goto try_again; + } + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_INTERNAL) { + // Internal-only setup, no additional configuration. + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_AD_HOC) { + // Some ad-hoc configuration we can't see and can't check. + } else { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "missing configuration.\n", desc->name); + goto try_again; + } + if (hw_config->hwaccel) { + av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel " + "initialisation.\n", desc->name); + err = hwaccel_init(avctx, hw_config); + if (err < 0) + goto try_again; + } + ret = user_choice; + break; - /* Remove failed hwaccel from choices */ - for (n = 0; choices[n] != ret; n++) - av_assert0(choices[n] != AV_PIX_FMT_NONE); - - do - choices[n] = choices[n + 1]; - while (choices[n++] != AV_PIX_FMT_NONE); + try_again: + av_log(avctx, AV_LOG_DEBUG, "Format %s not usable, retrying " + "get_format() without it.\n", desc->name); + for (i = 0; i < n; i++) { + if (choices[i] == user_choice) + break; + } + for (; i + 1 < n; i++) + choices[i] = choices[i + 1]; + --n; } av_freep(&choices); diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 868e3dfc54..a619e977f6 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -272,6 +272,12 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, * Select the (possibly hardware accelerated) pixel format. * This is a wrapper around AVCodecContext.get_format() and should be used * instead of calling get_format() directly. + * + * The list of pixel formats must contain at least one valid entry, and is + * terminated with AV_PIX_FMT_NONE. If it is possible to decode to software, + * the last entry in the list must be the most accurate software format. + * If it is not possible to decode to software, AVCodecContext.sw_pix_fmt + * must be set before calling this function. */ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); From e2d575543ceeee72f12ac911e72f802bc6cba32e Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:44 +0100 Subject: [PATCH 5/9] lavc: Deprecate av_hwaccel_next() and av_register_hwaccel() --- doc/APIchanges | 4 ++++ libavcodec/avcodec.h | 13 +++++++++++++ libavcodec/utils.c | 15 +++++---------- libavcodec/version.h | 5 ++++- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index f5f15c49a1..e29fb24172 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2017-03-23 API changes, most recent first: +2017-xx-xx - xxxxxxx - lavc 58.7.0 - avcodec.h + Deprecate user visibility of the AVHWAccel structure and the functions + av_register_hwaccel() and av_hwaccel_next(). + 2017-xx-xx - xxxxxxx - lavc 58.6.0 - avcodec.h Add AVCodecHWConfig and avcodec_get_hw_config(). diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index cf9f9dfe84..53b5a7c4d4 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2962,6 +2962,10 @@ const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index); /** * @defgroup lavc_hwaccel AVHWAccel + * + * @note Nothing in this structure should be accessed by the user. At some + * point in future it will not be externally visible at all. + * * @{ */ typedef struct AVHWAccel { @@ -5040,17 +5044,26 @@ void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size); */ unsigned int av_xiphlacing(unsigned char *s, unsigned int v); +#if FF_API_USER_VISIBLE_AVHWACCEL /** * Register the hardware accelerator hwaccel. + * + * @deprecated This function doesn't do anything. */ +attribute_deprecated void av_register_hwaccel(AVHWAccel *hwaccel); /** * If hwaccel is NULL, returns the first registered hardware accelerator, * if hwaccel is non-NULL, returns the next registered hardware accelerator * after hwaccel, or NULL if hwaccel is the last one. + * + * @deprecated AVHWaccel structures contain no user-serviceable parts, so + * this function should not be used. */ +attribute_deprecated AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel); +#endif /** diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 3d6b35fa41..ba3457664a 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1347,21 +1347,16 @@ const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index) return &codec->hw_configs[index]->public; } -static AVHWAccel *first_hwaccel = NULL; - -void av_register_hwaccel(AVHWAccel *hwaccel) +#if FF_API_USER_VISIBLE_AVHWACCEL +AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel) { - AVHWAccel **p = &first_hwaccel; - while (*p) - p = &(*p)->next; - *p = hwaccel; - hwaccel->next = NULL; + return NULL; } -AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel) +void av_register_hwaccel(AVHWAccel *hwaccel) { - return hwaccel ? hwaccel->next : first_hwaccel; } +#endif int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) { diff --git a/libavcodec/version.h b/libavcodec/version.h index e6edd5c867..7ef743dc69 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 6 +#define LIBAVCODEC_VERSION_MINOR 7 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -95,5 +95,8 @@ #ifndef FF_API_VAAPI_CONTEXT #define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_USER_VISIBLE_AVHWACCEL +#define FF_API_USER_VISIBLE_AVHWACCEL (LIBAVCODEC_VERSION_MAJOR < 60) +#endif #endif /* AVCODEC_VERSION_H */ From 433522a1b985ef03bdb3ea77714f708b8ee014ae Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:45 +0100 Subject: [PATCH 6/9] lavc: Remove register mechanism for hwaccels There is no longer any need for a list of them at runtime, because decoders now carry the pointers to their associated hwaccels internally. The file containing external declarations is now used to make the list of hwaccels for configure. --- configure | 2 +- libavcodec/allcodecs.c | 51 ------------------------------------------ 2 files changed, 1 insertion(+), 52 deletions(-) diff --git a/configure b/configure index 7f320fee18..d0e1980dc1 100755 --- a/configure +++ b/configure @@ -2704,7 +2704,6 @@ find_things(){ ENCODER_LIST=$(find_things encoder ENC libavcodec/allcodecs.c) DECODER_LIST=$(find_things decoder DEC libavcodec/allcodecs.c) -HWACCEL_LIST=$(find_things hwaccel HWACCEL libavcodec/allcodecs.c) PARSER_LIST=$(find_things parser PARSER libavcodec/allcodecs.c) MUXER_LIST=$(find_things muxer _MUX libavformat/allformats.c) DEMUXER_LIST=$(find_things demuxer DEMUX libavformat/allformats.c) @@ -2719,6 +2718,7 @@ find_things_extern(){ } BSF_LIST=$(find_things_extern bsf AVBitStreamFilter libavcodec/bitstream_filters.c) +HWACCEL_LIST=$(find_things_extern hwaccel AVHWAccel libavcodec/hwaccels.h) PROTOCOL_LIST=$(find_things_extern protocol URLProtocol libavformat/protocols.c) AVCODEC_COMPONENTS_LIST=" diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4ece4307a0..50a87493ea 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -28,13 +28,6 @@ #include "avcodec.h" #include "version.h" -#define REGISTER_HWACCEL(X, x) \ - { \ - extern AVHWAccel ff_##x##_hwaccel; \ - if (CONFIG_##X##_HWACCEL) \ - av_register_hwaccel(&ff_##x##_hwaccel); \ - } - #define REGISTER_ENCODER(X, x) \ { \ extern AVCodec ff_##x##_encoder; \ @@ -66,50 +59,6 @@ void avcodec_register_all(void) return; initialized = 1; - /* hardware accelerators */ - REGISTER_HWACCEL(H263_VAAPI, h263_vaapi); - REGISTER_HWACCEL(H264_CUVID, h264_cuvid); - REGISTER_HWACCEL(H264_D3D11VA, h264_d3d11va); - REGISTER_HWACCEL(H264_D3D11VA2, h264_d3d11va2); - REGISTER_HWACCEL(H264_DXVA2, h264_dxva2); - REGISTER_HWACCEL(H264_MMAL, h264_mmal); - REGISTER_HWACCEL(H264_QSV, h264_qsv); - REGISTER_HWACCEL(H264_VAAPI, h264_vaapi); - REGISTER_HWACCEL(H264_VDA, h264_vda); - REGISTER_HWACCEL(H264_VDA_OLD, h264_vda_old); - REGISTER_HWACCEL(H264_VDPAU, h264_vdpau); - REGISTER_HWACCEL(HEVC_CUVID, hevc_cuvid); - REGISTER_HWACCEL(HEVC_D3D11VA, hevc_d3d11va); - REGISTER_HWACCEL(HEVC_D3D11VA2, hevc_d3d11va2); - REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2); - REGISTER_HWACCEL(HEVC_QSV, hevc_qsv); - REGISTER_HWACCEL(HEVC_VAAPI, hevc_vaapi); - REGISTER_HWACCEL(HEVC_VDPAU, hevc_vdpau); - REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau); - REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va); - REGISTER_HWACCEL(MPEG2_D3D11VA2, mpeg2_d3d11va2); - REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); - REGISTER_HWACCEL(MPEG2_MMAL, mpeg2_mmal); - REGISTER_HWACCEL(MPEG2_QSV, mpeg2_qsv); - REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); - REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); - REGISTER_HWACCEL(MPEG4_VAAPI, mpeg4_vaapi); - REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau); - REGISTER_HWACCEL(VC1_D3D11VA, vc1_d3d11va); - REGISTER_HWACCEL(VC1_D3D11VA2, vc1_d3d11va2); - REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2); - REGISTER_HWACCEL(VC1_QSV, vc1_qsv); - REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); - REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); - REGISTER_HWACCEL(VC1_MMAL, vc1_mmal); - REGISTER_HWACCEL(VP8_QSV, vp8_qsv); - REGISTER_HWACCEL(VP8_VAAPI, vp8_vaapi); - REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va); - REGISTER_HWACCEL(WMV3_D3D11VA2, wmv3_d3d11va2); - REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); - REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); - REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau); - /* video codecs */ REGISTER_ENCODER(A64MULTI, a64multi); REGISTER_ENCODER(A64MULTI5, a64multi5); From 2a4d34d462d60799e045c370dc9b2505f18365e7 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:46 +0100 Subject: [PATCH 7/9] lavc: Delete all fake hwaccels They are now unused. --- configure | 18 +++++------------- libavcodec/mmaldec.c | 21 --------------------- libavcodec/qsvdec_h2645.c | 18 ------------------ libavcodec/qsvdec_other.c | 27 --------------------------- 4 files changed, 5 insertions(+), 79 deletions(-) diff --git a/configure b/configure index d0e1980dc1..d31cb56588 100755 --- a/configure +++ b/configure @@ -2183,8 +2183,6 @@ h264_d3d11va2_hwaccel_deps="d3d11va" h264_d3d11va2_hwaccel_select="h264_decoder" h264_dxva2_hwaccel_deps="dxva2" h264_dxva2_hwaccel_select="h264_decoder" -h264_mmal_hwaccel_deps="mmal" -h264_qsv_hwaccel_deps="libmfx" h264_vaapi_hwaccel_deps="vaapi" h264_vaapi_hwaccel_select="h264_decoder" h264_vda_hwaccel_deps="vda" @@ -2201,7 +2199,6 @@ hevc_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_HEVC" hevc_d3d11va2_hwaccel_select="hevc_decoder" hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" hevc_dxva2_hwaccel_select="hevc_decoder" -hevc_qsv_hwaccel_deps="libmfx" hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" hevc_vaapi_hwaccel_select="hevc_decoder" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" @@ -2214,8 +2211,6 @@ mpeg2_d3d11va2_hwaccel_deps="d3d11va" mpeg2_d3d11va2_hwaccel_select="mpeg2video_decoder" mpeg2_dxva2_hwaccel_deps="dxva2" mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" -mpeg2_mmal_hwaccel_deps="mmal" -mpeg2_qsv_hwaccel_deps="libmfx" mpeg2_vaapi_hwaccel_deps="vaapi" mpeg2_vaapi_hwaccel_select="mpeg2video_decoder" mpeg2_vdpau_hwaccel_deps="vdpau" @@ -2230,13 +2225,10 @@ vc1_d3d11va2_hwaccel_deps="d3d11va" vc1_d3d11va2_hwaccel_select="vc1_decoder" vc1_dxva2_hwaccel_deps="dxva2" vc1_dxva2_hwaccel_select="vc1_decoder" -vc1_mmal_hwaccel_deps="mmal" -vc1_qsv_hwaccel_deps="libmfx" vc1_vaapi_hwaccel_deps="vaapi" vc1_vaapi_hwaccel_select="vc1_decoder" vc1_vdpau_hwaccel_deps="vdpau" vc1_vdpau_hwaccel_select="vc1_decoder" -vp8_qsv_hwaccel_deps="libmfx" vp8_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVP8" vp8_vaapi_hwaccel_select="vp8_decoder" wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel" @@ -2261,12 +2253,12 @@ scale_npp_filter_deps="cuda libnpp" h264_mmal_decoder_deps="mmal" h264_nvenc_encoder_deps="nvenc" h264_omx_encoder_deps="omx" -h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec h264_qsv_hwaccel" +h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec" h264_qsv_encoder_select="qsvenc" h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264" h264_vaapi_encoder_select="cbs_h264 vaapi_encode" hevc_nvenc_encoder_deps="nvenc" -hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser hevc_qsv_hwaccel qsvdec" +hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser qsvdec" hevc_qsv_encoder_select="hevcparse qsvenc" hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC" hevc_vaapi_encoder_select="cbs_h265 vaapi_encode" @@ -2275,14 +2267,14 @@ mjpeg_qsv_encoder_select="qsvenc" mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" mjpeg_vaapi_encoder_select="vaapi_encode jpegtables" mpeg2_mmal_decoder_deps="mmal" -mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel mpegvideo_parser" +mpeg2_qsv_decoder_select="qsvdec mpegvideo_parser" mpeg2_qsv_encoder_select="qsvenc" mpeg2_vaapi_encoder_deps="VAEncPictureParameterBufferMPEG2" mpeg2_vaapi_encoder_select="cbs_mpeg2 vaapi_encode" mpeg4_omx_encoder_deps="omx" vc1_mmal_decoder_deps="mmal" -vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel vc1_parser" -vp8_qsv_decoder_select="qsvdec vp8_qsv_hwaccel vp8_parser" +vc1_qsv_decoder_select="qsvdec vc1_parser" +vp8_qsv_decoder_select="qsvdec vp8_parser" vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8" vp8_vaapi_encoder_select="vaapi_encode" vp9_vaapi_encoder_deps="VAEncPictureParameterBufferVP9" diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 9ed8e61371..10a48d3e0f 100644 --- a/libavcodec/mmaldec.c +++ b/libavcodec/mmaldec.c @@ -788,27 +788,6 @@ static int ffmmal_decode(AVCodecContext *avctx, void *data, int *got_frame, return ret; } -AVHWAccel ff_h264_mmal_hwaccel = { - .name = "h264_mmal", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H264, - .pix_fmt = AV_PIX_FMT_MMAL, -}; - -AVHWAccel ff_mpeg2_mmal_hwaccel = { - .name = "mpeg2_mmal", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO, - .pix_fmt = AV_PIX_FMT_MMAL, -}; - -AVHWAccel ff_vc1_mmal_hwaccel = { - .name = "vc1_mmal", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_VC1, - .pix_fmt = AV_PIX_FMT_MMAL, -}; - static const AVCodecHWConfigInternal *mmal_hw_configs = { HW_CONFIG_INTERNAL(MMAL), NULL diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c index a7b39da6bf..83880dc085 100644 --- a/libavcodec/qsvdec_h2645.c +++ b/libavcodec/qsvdec_h2645.c @@ -180,15 +180,6 @@ static void qsv_decode_flush(AVCodecContext *avctx) #define OFFSET(x) offsetof(QSVH2645Context, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM -#if CONFIG_HEVC_QSV_HWACCEL -AVHWAccel ff_hevc_qsv_hwaccel = { - .name = "hevc_qsv", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_HEVC, - .pix_fmt = AV_PIX_FMT_QSV, -}; -#endif - #if CONFIG_HEVC_QSV_DECODER static const AVOption hevc_options[] = { { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD }, @@ -232,15 +223,6 @@ AVCodec ff_hevc_qsv_decoder = { }; #endif -#if CONFIG_H264_QSV_HWACCEL -AVHWAccel ff_h264_qsv_hwaccel = { - .name = "h264_qsv", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H264, - .pix_fmt = AV_PIX_FMT_QSV, -}; -#endif - #if CONFIG_H264_QSV_DECODER static const AVOption options[] = { { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD }, diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c index 63cc113c5c..90693ed317 100644 --- a/libavcodec/qsvdec_other.c +++ b/libavcodec/qsvdec_other.c @@ -163,15 +163,6 @@ static const AVOption options[] = { { NULL }, }; -#if CONFIG_MPEG2_QSV_HWACCEL -AVHWAccel ff_mpeg2_qsv_hwaccel = { - .name = "mpeg2_qsv", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO, - .pix_fmt = AV_PIX_FMT_QSV, -}; -#endif - #if CONFIG_MPEG2_QSV_DECODER static const AVClass mpeg2_qsv_class = { .class_name = "mpeg2_qsv", @@ -200,15 +191,6 @@ AVCodec ff_mpeg2_qsv_decoder = { }; #endif -#if CONFIG_VC1_QSV_HWACCEL -AVHWAccel ff_vc1_qsv_hwaccel = { - .name = "vc1_qsv", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_VC1, - .pix_fmt = AV_PIX_FMT_QSV, -}; -#endif - #if CONFIG_VC1_QSV_DECODER static const AVClass vc1_qsv_class = { .class_name = "vc1_qsv", @@ -237,15 +219,6 @@ AVCodec ff_vc1_qsv_decoder = { }; #endif -#if CONFIG_VP8_QSV_HWACCEL -AVHWAccel ff_vp8_qsv_hwaccel = { - .name = "vp8_qsv", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_VP8, - .pix_fmt = AV_PIX_FMT_QSV, -}; -#endif - #if CONFIG_VP8_QSV_DECODER static const AVClass vp8_qsv_class = { .class_name = "vp8_qsv", From 2117725dc56e0d20da641a3311939cf4e2ed9549 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 4 Nov 2017 18:53:26 +0000 Subject: [PATCH 8/9] lavc: Mark all AVHWAccel structures as const --- doc/APIchanges | 3 ++ libavcodec/avcodec.h | 2 +- libavcodec/cuvid_h264.c | 2 +- libavcodec/cuvid_hevc.c | 2 +- libavcodec/decode.c | 2 +- libavcodec/dxva2_h264.c | 6 ++-- libavcodec/dxva2_hevc.c | 6 ++-- libavcodec/dxva2_mpeg2.c | 6 ++-- libavcodec/dxva2_vc1.c | 12 +++---- libavcodec/hwaccels.h | 68 +++++++++++++++++++-------------------- libavcodec/vaapi_h264.c | 2 +- libavcodec/vaapi_hevc.c | 2 +- libavcodec/vaapi_mpeg2.c | 2 +- libavcodec/vaapi_mpeg4.c | 4 +-- libavcodec/vaapi_vc1.c | 4 +-- libavcodec/vaapi_vp8.c | 2 +- libavcodec/vda_h264.c | 4 +-- libavcodec/vdpau_h264.c | 2 +- libavcodec/vdpau_hevc.c | 2 +- libavcodec/vdpau_mpeg12.c | 4 +-- libavcodec/vdpau_mpeg4.c | 2 +- libavcodec/vdpau_vc1.c | 4 +-- libavcodec/version.h | 2 +- 23 files changed, 74 insertions(+), 71 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index e29fb24172..0bde3a052d 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2017-03-23 API changes, most recent first: +2017-xx-xx - xxxxxxx - lavc 58.8.0 - avcodec.h + Add const to AVCodecContext.hwaccel. + 2017-xx-xx - xxxxxxx - lavc 58.7.0 - avcodec.h Deprecate user visibility of the AVHWAccel structure and the functions av_register_hwaccel() and av_hwaccel_next(). diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 53b5a7c4d4..7eaa0c9277 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2307,7 +2307,7 @@ typedef struct AVCodecContext { * - encoding: unused. * - decoding: Set by libavcodec */ - struct AVHWAccel *hwaccel; + const struct AVHWAccel *hwaccel; /** * Hardware accelerator context. diff --git a/libavcodec/cuvid_h264.c b/libavcodec/cuvid_h264.c index a83e4ffba0..4f36e922be 100644 --- a/libavcodec/cuvid_h264.c +++ b/libavcodec/cuvid_h264.c @@ -163,7 +163,7 @@ static int cuvid_h264_decode_init(AVCodecContext *avctx) return ff_cuvid_decode_init(avctx, sps->ref_frame_count + sps->num_reorder_frames); } -AVHWAccel ff_h264_cuvid_hwaccel = { +const AVHWAccel ff_h264_cuvid_hwaccel = { .name = "h264_cuvid", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, diff --git a/libavcodec/cuvid_hevc.c b/libavcodec/cuvid_hevc.c index 5de9bca483..fcf20bbcfa 100644 --- a/libavcodec/cuvid_hevc.c +++ b/libavcodec/cuvid_hevc.c @@ -266,7 +266,7 @@ static int cuvid_hevc_decode_init(AVCodecContext *avctx) return ff_cuvid_decode_init(avctx, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1); } -AVHWAccel ff_hevc_cuvid_hwaccel = { +const AVHWAccel ff_hevc_cuvid_hwaccel = { .name = "hevc_cuvid", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, diff --git a/libavcodec/decode.c b/libavcodec/decode.c index bc2208a3fd..12a95d4221 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -812,7 +812,7 @@ static int hwaccel_init(AVCodecContext *avctx, return AVERROR(ENOMEM); } - avctx->hwaccel = (AVHWAccel*)hwaccel; + avctx->hwaccel = hwaccel; err = hwaccel->init(avctx); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed setup for format %s: " diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index 8ce8c358c5..50e7863bf2 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -513,7 +513,7 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx) } #if CONFIG_H264_DXVA2_HWACCEL -AVHWAccel ff_h264_dxva2_hwaccel = { +const AVHWAccel ff_h264_dxva2_hwaccel = { .name = "h264_dxva2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, @@ -530,7 +530,7 @@ AVHWAccel ff_h264_dxva2_hwaccel = { #endif #if CONFIG_H264_D3D11VA_HWACCEL -AVHWAccel ff_h264_d3d11va_hwaccel = { +const AVHWAccel ff_h264_d3d11va_hwaccel = { .name = "h264_d3d11va", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, @@ -547,7 +547,7 @@ AVHWAccel ff_h264_d3d11va_hwaccel = { #endif #if CONFIG_H264_D3D11VA2_HWACCEL -AVHWAccel ff_h264_d3d11va2_hwaccel = { +const AVHWAccel ff_h264_d3d11va2_hwaccel = { .name = "h264_d3d11va2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c index 1d665f07d1..02d3b9b152 100644 --- a/libavcodec/dxva2_hevc.c +++ b/libavcodec/dxva2_hevc.c @@ -422,7 +422,7 @@ static int dxva2_hevc_end_frame(AVCodecContext *avctx) } #if CONFIG_HEVC_DXVA2_HWACCEL -AVHWAccel ff_hevc_dxva2_hwaccel = { +const AVHWAccel ff_hevc_dxva2_hwaccel = { .name = "hevc_dxva2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, @@ -439,7 +439,7 @@ AVHWAccel ff_hevc_dxva2_hwaccel = { #endif #if CONFIG_HEVC_D3D11VA_HWACCEL -AVHWAccel ff_hevc_d3d11va_hwaccel = { +const AVHWAccel ff_hevc_d3d11va_hwaccel = { .name = "hevc_d3d11va", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, @@ -456,7 +456,7 @@ AVHWAccel ff_hevc_d3d11va_hwaccel = { #endif #if CONFIG_HEVC_D3D11VA2_HWACCEL -AVHWAccel ff_hevc_d3d11va2_hwaccel = { +const AVHWAccel ff_hevc_d3d11va2_hwaccel = { .name = "hevc_d3d11va2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c index 036d5baac5..6e5dff308f 100644 --- a/libavcodec/dxva2_mpeg2.c +++ b/libavcodec/dxva2_mpeg2.c @@ -318,7 +318,7 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx) } #if CONFIG_MPEG2_DXVA2_HWACCEL -AVHWAccel ff_mpeg2_dxva2_hwaccel = { +const AVHWAccel ff_mpeg2_dxva2_hwaccel = { .name = "mpeg2_dxva2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, @@ -335,7 +335,7 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = { #endif #if CONFIG_MPEG2_D3D11VA_HWACCEL -AVHWAccel ff_mpeg2_d3d11va_hwaccel = { +const AVHWAccel ff_mpeg2_d3d11va_hwaccel = { .name = "mpeg2_d3d11va", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, @@ -352,7 +352,7 @@ AVHWAccel ff_mpeg2_d3d11va_hwaccel = { #endif #if CONFIG_MPEG2_D3D11VA2_HWACCEL -AVHWAccel ff_mpeg2_d3d11va2_hwaccel = { +const AVHWAccel ff_mpeg2_d3d11va2_hwaccel = { .name = "mpeg2_d3d11va2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c index 79f758a3b9..247ea47825 100644 --- a/libavcodec/dxva2_vc1.c +++ b/libavcodec/dxva2_vc1.c @@ -318,7 +318,7 @@ static int dxva2_vc1_end_frame(AVCodecContext *avctx) } #if CONFIG_WMV3_DXVA2_HWACCEL -AVHWAccel ff_wmv3_dxva2_hwaccel = { +const AVHWAccel ff_wmv3_dxva2_hwaccel = { .name = "wmv3_dxva2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, @@ -335,7 +335,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = { #endif #if CONFIG_VC1_DXVA2_HWACCEL -AVHWAccel ff_vc1_dxva2_hwaccel = { +const AVHWAccel ff_vc1_dxva2_hwaccel = { .name = "vc1_dxva2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, @@ -352,7 +352,7 @@ AVHWAccel ff_vc1_dxva2_hwaccel = { #endif #if CONFIG_WMV3_D3D11VA_HWACCEL -AVHWAccel ff_wmv3_d3d11va_hwaccel = { +const AVHWAccel ff_wmv3_d3d11va_hwaccel = { .name = "wmv3_d3d11va", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, @@ -369,7 +369,7 @@ AVHWAccel ff_wmv3_d3d11va_hwaccel = { #endif #if CONFIG_WMV3_D3D11VA2_HWACCEL -AVHWAccel ff_wmv3_d3d11va2_hwaccel = { +const AVHWAccel ff_wmv3_d3d11va2_hwaccel = { .name = "wmv3_d3d11va2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, @@ -386,7 +386,7 @@ AVHWAccel ff_wmv3_d3d11va2_hwaccel = { #endif #if CONFIG_VC1_D3D11VA_HWACCEL -AVHWAccel ff_vc1_d3d11va_hwaccel = { +const AVHWAccel ff_vc1_d3d11va_hwaccel = { .name = "vc1_d3d11va", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, @@ -403,7 +403,7 @@ AVHWAccel ff_vc1_d3d11va_hwaccel = { #endif #if CONFIG_VC1_D3D11VA2_HWACCEL -AVHWAccel ff_vc1_d3d11va2_hwaccel = { +const AVHWAccel ff_vc1_d3d11va2_hwaccel = { .name = "vc1_d3d11va2", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h index 6dee94b44f..afa86f14e4 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -21,39 +21,39 @@ #include "avcodec.h" -extern AVHWAccel ff_h263_vaapi_hwaccel; -extern AVHWAccel ff_h264_cuvid_hwaccel; -extern AVHWAccel ff_h264_d3d11va_hwaccel; -extern AVHWAccel ff_h264_d3d11va2_hwaccel; -extern AVHWAccel ff_h264_dxva2_hwaccel; -extern AVHWAccel ff_h264_vaapi_hwaccel; -extern AVHWAccel ff_h264_vda_hwaccel; -extern AVHWAccel ff_h264_vda_old_hwaccel; -extern AVHWAccel ff_h264_vdpau_hwaccel; -extern AVHWAccel ff_hevc_cuvid_hwaccel; -extern AVHWAccel ff_hevc_d3d11va_hwaccel; -extern AVHWAccel ff_hevc_d3d11va2_hwaccel; -extern AVHWAccel ff_hevc_dxva2_hwaccel; -extern AVHWAccel ff_hevc_vaapi_hwaccel; -extern AVHWAccel ff_hevc_vdpau_hwaccel; -extern AVHWAccel ff_mpeg1_vdpau_hwaccel; -extern AVHWAccel ff_mpeg2_d3d11va_hwaccel; -extern AVHWAccel ff_mpeg2_d3d11va2_hwaccel; -extern AVHWAccel ff_mpeg2_dxva2_hwaccel; -extern AVHWAccel ff_mpeg2_vaapi_hwaccel; -extern AVHWAccel ff_mpeg2_vdpau_hwaccel; -extern AVHWAccel ff_mpeg4_vaapi_hwaccel; -extern AVHWAccel ff_mpeg4_vdpau_hwaccel; -extern AVHWAccel ff_vc1_d3d11va_hwaccel; -extern AVHWAccel ff_vc1_d3d11va2_hwaccel; -extern AVHWAccel ff_vc1_dxva2_hwaccel; -extern AVHWAccel ff_vc1_vaapi_hwaccel; -extern AVHWAccel ff_vc1_vdpau_hwaccel; -extern AVHWAccel ff_vp8_vaapi_hwaccel; -extern AVHWAccel ff_wmv3_d3d11va_hwaccel; -extern AVHWAccel ff_wmv3_d3d11va2_hwaccel; -extern AVHWAccel ff_wmv3_dxva2_hwaccel; -extern AVHWAccel ff_wmv3_vaapi_hwaccel; -extern AVHWAccel ff_wmv3_vdpau_hwaccel; +extern const AVHWAccel ff_h263_vaapi_hwaccel; +extern const AVHWAccel ff_h264_cuvid_hwaccel; +extern const AVHWAccel ff_h264_d3d11va_hwaccel; +extern const AVHWAccel ff_h264_d3d11va2_hwaccel; +extern const AVHWAccel ff_h264_dxva2_hwaccel; +extern const AVHWAccel ff_h264_vaapi_hwaccel; +extern const AVHWAccel ff_h264_vda_hwaccel; +extern const AVHWAccel ff_h264_vda_old_hwaccel; +extern const AVHWAccel ff_h264_vdpau_hwaccel; +extern const AVHWAccel ff_hevc_cuvid_hwaccel; +extern const AVHWAccel ff_hevc_d3d11va_hwaccel; +extern const AVHWAccel ff_hevc_d3d11va2_hwaccel; +extern const AVHWAccel ff_hevc_dxva2_hwaccel; +extern const AVHWAccel ff_hevc_vaapi_hwaccel; +extern const AVHWAccel ff_hevc_vdpau_hwaccel; +extern const AVHWAccel ff_mpeg1_vdpau_hwaccel; +extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel; +extern const AVHWAccel ff_mpeg2_d3d11va2_hwaccel; +extern const AVHWAccel ff_mpeg2_dxva2_hwaccel; +extern const AVHWAccel ff_mpeg2_vaapi_hwaccel; +extern const AVHWAccel ff_mpeg2_vdpau_hwaccel; +extern const AVHWAccel ff_mpeg4_vaapi_hwaccel; +extern const AVHWAccel ff_mpeg4_vdpau_hwaccel; +extern const AVHWAccel ff_vc1_d3d11va_hwaccel; +extern const AVHWAccel ff_vc1_d3d11va2_hwaccel; +extern const AVHWAccel ff_vc1_dxva2_hwaccel; +extern const AVHWAccel ff_vc1_vaapi_hwaccel; +extern const AVHWAccel ff_vc1_vdpau_hwaccel; +extern const AVHWAccel ff_vp8_vaapi_hwaccel; +extern const AVHWAccel ff_wmv3_d3d11va_hwaccel; +extern const AVHWAccel ff_wmv3_d3d11va2_hwaccel; +extern const AVHWAccel ff_wmv3_dxva2_hwaccel; +extern const AVHWAccel ff_wmv3_vaapi_hwaccel; +extern const AVHWAccel ff_wmv3_vdpau_hwaccel; #endif /* AVCODEC_HWACCELS_H */ diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 0a5c0dfc76..97d4387d71 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -388,7 +388,7 @@ static int vaapi_h264_decode_slice(AVCodecContext *avctx, return 0; } -AVHWAccel ff_h264_vaapi_hwaccel = { +const AVHWAccel ff_h264_vaapi_hwaccel = { .name = "h264_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c index 085d84142d..71fab77655 100644 --- a/libavcodec/vaapi_hevc.c +++ b/libavcodec/vaapi_hevc.c @@ -423,7 +423,7 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx, return 0; } -AVHWAccel ff_hevc_vaapi_hwaccel = { +const AVHWAccel ff_hevc_vaapi_hwaccel = { .name = "hevc_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index 5c0a79788f..4cca00c862 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -173,7 +173,7 @@ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer return 0; } -AVHWAccel ff_mpeg2_vaapi_hwaccel = { +const AVHWAccel ff_mpeg2_vaapi_hwaccel = { .name = "mpeg2_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c index 258ae68568..5dc94a4c2d 100644 --- a/libavcodec/vaapi_mpeg4.c +++ b/libavcodec/vaapi_mpeg4.c @@ -189,7 +189,7 @@ static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer } #if CONFIG_MPEG4_VAAPI_HWACCEL -AVHWAccel ff_mpeg4_vaapi_hwaccel = { +const AVHWAccel ff_mpeg4_vaapi_hwaccel = { .name = "mpeg4_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG4, @@ -207,7 +207,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = { #endif #if CONFIG_H263_VAAPI_HWACCEL -AVHWAccel ff_h263_vaapi_hwaccel = { +const AVHWAccel ff_h263_vaapi_hwaccel = { .name = "h263_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H263, diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 8df219f7e2..8b7d49facf 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -388,7 +388,7 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, } #if CONFIG_WMV3_VAAPI_HWACCEL -AVHWAccel ff_wmv3_vaapi_hwaccel = { +const AVHWAccel ff_wmv3_vaapi_hwaccel = { .name = "wmv3_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, @@ -405,7 +405,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = { }; #endif -AVHWAccel ff_vc1_vaapi_hwaccel = { +const AVHWAccel ff_vc1_vaapi_hwaccel = { .name = "vc1_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, diff --git a/libavcodec/vaapi_vp8.c b/libavcodec/vaapi_vp8.c index 3ccc2bd0ab..e18b1cb2df 100644 --- a/libavcodec/vaapi_vp8.c +++ b/libavcodec/vaapi_vp8.c @@ -220,7 +220,7 @@ fail: return err; } -AVHWAccel ff_vp8_vaapi_hwaccel = { +const AVHWAccel ff_vp8_vaapi_hwaccel = { .name = "vp8_vaapi", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP8, diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c index 037715da81..4dfe532f8a 100644 --- a/libavcodec/vda_h264.c +++ b/libavcodec/vda_h264.c @@ -247,7 +247,7 @@ static int vda_h264_uninit(AVCodecContext *avctx) return 0; } -AVHWAccel ff_h264_vda_old_hwaccel = { +const AVHWAccel ff_h264_vda_old_hwaccel = { .name = "h264_vda", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, @@ -483,7 +483,7 @@ static int vda_h264_alloc_frame(AVCodecContext *avctx, AVFrame *frame) return 0; } -AVHWAccel ff_h264_vda_hwaccel = { +const AVHWAccel ff_h264_vda_hwaccel = { .name = "h264_vda", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c index 8edbc44021..7c4c977b40 100644 --- a/libavcodec/vdpau_h264.c +++ b/libavcodec/vdpau_h264.c @@ -262,7 +262,7 @@ static int vdpau_h264_init(AVCodecContext *avctx) return ff_vdpau_common_init(avctx, profile, level); } -AVHWAccel ff_h264_vdpau_hwaccel = { +const AVHWAccel ff_h264_vdpau_hwaccel = { .name = "h264_vdpau", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index a177c00e43..3b575eb786 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -413,7 +413,7 @@ static int vdpau_hevc_init(AVCodecContext *avctx) return ff_vdpau_common_init(avctx, profile, level); } -AVHWAccel ff_hevc_vdpau_hwaccel = { +const AVHWAccel ff_hevc_vdpau_hwaccel = { .name = "hevc_vdpau", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c index db1ba34e03..bc9ff5da8c 100644 --- a/libavcodec/vdpau_mpeg12.c +++ b/libavcodec/vdpau_mpeg12.c @@ -103,7 +103,7 @@ static int vdpau_mpeg1_init(AVCodecContext *avctx) VDP_DECODER_LEVEL_MPEG1_NA); } -AVHWAccel ff_mpeg1_vdpau_hwaccel = { +const AVHWAccel ff_mpeg1_vdpau_hwaccel = { .name = "mpeg1_vdpau", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG1VIDEO, @@ -138,7 +138,7 @@ static int vdpau_mpeg2_init(AVCodecContext *avctx) return ff_vdpau_common_init(avctx, profile, VDP_DECODER_LEVEL_MPEG2_HL); } -AVHWAccel ff_mpeg2_vdpau_hwaccel = { +const AVHWAccel ff_mpeg2_vdpau_hwaccel = { .name = "mpeg2_vdpau", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c index 519866cf0a..87db6a767c 100644 --- a/libavcodec/vdpau_mpeg4.c +++ b/libavcodec/vdpau_mpeg4.c @@ -107,7 +107,7 @@ static int vdpau_mpeg4_init(AVCodecContext *avctx) return ff_vdpau_common_init(avctx, profile, avctx->level); } -AVHWAccel ff_mpeg4_vdpau_hwaccel = { +const AVHWAccel ff_mpeg4_vdpau_hwaccel = { .name = "mpeg4_vdpau", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG4, diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c index 45b51304c6..1b555888ce 100644 --- a/libavcodec/vdpau_vc1.c +++ b/libavcodec/vdpau_vc1.c @@ -132,7 +132,7 @@ static int vdpau_vc1_init(AVCodecContext *avctx) } #if CONFIG_WMV3_VDPAU_HWACCEL -AVHWAccel ff_wmv3_vdpau_hwaccel = { +const AVHWAccel ff_wmv3_vdpau_hwaccel = { .name = "wm3_vdpau", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_WMV3, @@ -149,7 +149,7 @@ AVHWAccel ff_wmv3_vdpau_hwaccel = { }; #endif -AVHWAccel ff_vc1_vdpau_hwaccel = { +const AVHWAccel ff_vc1_vdpau_hwaccel = { .name = "vc1_vdpau", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VC1, diff --git a/libavcodec/version.h b/libavcodec/version.h index 7ef743dc69..9b47110301 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 7 +#define LIBAVCODEC_VERSION_MINOR 8 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From ddea22a684611c1fec9d8b5c70d835e983a9252e Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Thu, 26 Oct 2017 00:18:47 +0100 Subject: [PATCH 9/9] avconv: Use codec hardware config to configure hwaccels Removes specific support for all hwaccels supported by the generic code (CUVID, DXVA2, D3D11VA, VAAPI and VDPAU). --- avtools/avconv.c | 76 +++++++++---- avtools/avconv.h | 9 +- avtools/avconv_hw.c | 249 +++++++++++++++++++++++++++++-------------- avtools/avconv_opt.c | 47 ++++---- 4 files changed, 246 insertions(+), 135 deletions(-) diff --git a/avtools/avconv.c b/avtools/avconv.c index cee7a7b452..ac15464a8d 100644 --- a/avtools/avconv.c +++ b/avtools/avconv.c @@ -1631,44 +1631,77 @@ static void print_sdp(void) av_freep(&avc); } -static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt) -{ - int i; - for (i = 0; hwaccels[i].name; i++) - if (hwaccels[i].pix_fmt == pix_fmt) - return &hwaccels[i]; - return NULL; -} - static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) { InputStream *ist = s->opaque; const enum AVPixelFormat *p; int ret; - for (p = pix_fmts; *p != -1; p++) { + for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p); - const HWAccel *hwaccel; + const AVCodecHWConfig *config = NULL; + int i; if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) break; - hwaccel = get_hwaccel(*p); - if (!hwaccel || - (ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) || - (ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id)) - continue; + if (ist->hwaccel_id == HWACCEL_GENERIC || + ist->hwaccel_id == HWACCEL_AUTO) { + for (i = 0;; i++) { + config = avcodec_get_hw_config(s->codec, i); + if (!config) + break; + if (!(config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) + continue; + if (config->pix_fmt == *p) + break; + } + } + if (config) { + if (config->device_type != ist->hwaccel_device_type) { + // Different hwaccel offered, ignore. + continue; + } - ret = hwaccel->init(s); - if (ret < 0) { - if (ist->hwaccel_id == hwaccel->id) { + ret = hwaccel_decode_init(s); + if (ret < 0) { + if (ist->hwaccel_id == HWACCEL_GENERIC) { + av_log(NULL, AV_LOG_FATAL, + "%s hwaccel requested for input stream #%d:%d, " + "but cannot be initialized.\n", + av_hwdevice_get_type_name(config->device_type), + ist->file_index, ist->st->index); + return AV_PIX_FMT_NONE; + } + continue; + } + } else { + const HWAccel *hwaccel = NULL; + int i; + for (i = 0; hwaccels[i].name; i++) { + if (hwaccels[i].pix_fmt == *p) { + hwaccel = &hwaccels[i]; + break; + } + } + if (!hwaccel) { + // No hwaccel supporting this pixfmt. + continue; + } + if (hwaccel->id != ist->hwaccel_id) { + // Does not match requested hwaccel. + continue; + } + + ret = hwaccel->init(s); + if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "%s hwaccel requested for input stream #%d:%d, " "but cannot be initialized.\n", hwaccel->name, ist->file_index, ist->st->index); return AV_PIX_FMT_NONE; } - continue; } if (ist->hw_frames_ctx) { @@ -1677,8 +1710,7 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat return AV_PIX_FMT_NONE; } - ist->active_hwaccel_id = hwaccel->id; - ist->hwaccel_pix_fmt = *p; + ist->hwaccel_pix_fmt = *p; break; } diff --git a/avtools/avconv.h b/avtools/avconv.h index b5843fbc03..0d24c71a74 100644 --- a/avtools/avconv.h +++ b/avtools/avconv.h @@ -52,13 +52,9 @@ enum HWAccelID { HWACCEL_NONE = 0, HWACCEL_AUTO, - HWACCEL_VDPAU, - HWACCEL_DXVA2, + HWACCEL_GENERIC, HWACCEL_VDA, HWACCEL_QSV, - HWACCEL_VAAPI, - HWACCEL_D3D11VA, - HWACCEL_CUVID, }; typedef struct HWAccel { @@ -66,7 +62,6 @@ typedef struct HWAccel { int (*init)(AVCodecContext *s); enum HWAccelID id; enum AVPixelFormat pix_fmt; - enum AVHWDeviceType device_type; } HWAccel; typedef struct HWDevice { @@ -301,11 +296,11 @@ typedef struct InputStream { /* hwaccel options */ enum HWAccelID hwaccel_id; + enum AVHWDeviceType hwaccel_device_type; char *hwaccel_device; enum AVPixelFormat hwaccel_output_format; /* hwaccel context */ - enum HWAccelID active_hwaccel_id; void *hwaccel_ctx; void (*hwaccel_uninit)(AVCodecContext *s); int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags); diff --git a/avtools/avconv_hw.c b/avtools/avconv_hw.c index 36ef866927..7e223bf102 100644 --- a/avtools/avconv_hw.c +++ b/avtools/avconv_hw.c @@ -62,6 +62,31 @@ static HWDevice *hw_device_add(void) return hw_devices[nb_hw_devices++]; } +static char *hw_device_default_name(enum AVHWDeviceType type) +{ + // Make an automatic name of the form "type%d". We arbitrarily + // limit at 1000 anonymous devices of the same type - there is + // probably something else very wrong if you get to this limit. + const char *type_name = av_hwdevice_get_type_name(type); + char *name; + size_t index_pos; + int index, index_limit = 1000; + index_pos = strlen(type_name); + name = av_malloc(index_pos + 4); + if (!name) + return NULL; + for (index = 0; index < index_limit; index++) { + snprintf(name, index_pos + 4, "%s%d", type_name, index); + if (!hw_device_get_by_name(name)) + break; + } + if (index >= index_limit) { + av_freep(&name); + return NULL; + } + return name; +} + int hw_device_init_from_string(const char *arg, HWDevice **dev_out) { // "type=name:device,key=value,key2=value2" @@ -109,27 +134,11 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out) p += 1 + k; } else { - // Give the device an automatic name of the form "type%d". - // We arbitrarily limit at 1000 anonymous devices of the same - // type - there is probably something else very wrong if you - // get to this limit. - size_t index_pos; - int index, index_limit = 1000; - index_pos = strlen(type_name); - name = av_malloc(index_pos + 4); + name = hw_device_default_name(type); if (!name) { err = AVERROR(ENOMEM); goto fail; } - for (index = 0; index < index_limit; index++) { - snprintf(name, index_pos + 4, "%s%d", type_name, index); - if (!hw_device_get_by_name(name)) - break; - } - if (index >= index_limit) { - errmsg = "too many devices"; - goto invalid; - } } if (!*p) { @@ -212,6 +221,49 @@ fail: goto done; } +static int hw_device_init_from_type(enum AVHWDeviceType type, + const char *device, + HWDevice **dev_out) +{ + AVBufferRef *device_ref = NULL; + HWDevice *dev; + char *name; + int err; + + name = hw_device_default_name(type); + if (!name) { + err = AVERROR(ENOMEM); + goto fail; + } + + err = av_hwdevice_ctx_create(&device_ref, type, device, NULL, 0); + if (err < 0) { + av_log(NULL, AV_LOG_ERROR, + "Device creation failed: %d.\n", err); + goto fail; + } + + dev = hw_device_add(); + if (!dev) { + err = AVERROR(ENOMEM); + goto fail; + } + + dev->name = name; + dev->type = type; + dev->device_ref = device_ref; + + if (dev_out) + *dev_out = dev; + + return 0; + +fail: + av_freep(&name); + av_buffer_unref(&device_ref); + return err; +} + void hw_device_free_all(void) { int i; @@ -224,85 +276,130 @@ void hw_device_free_all(void) nb_hw_devices = 0; } -static enum AVHWDeviceType hw_device_match_type_by_hwaccel(enum HWAccelID hwaccel_id) +static HWDevice *hw_device_match_by_codec(const AVCodec *codec) { + const AVCodecHWConfig *config; + HWDevice *dev; int i; - if (hwaccel_id == HWACCEL_NONE) - return AV_HWDEVICE_TYPE_NONE; - for (i = 0; hwaccels[i].name; i++) { - if (hwaccels[i].id == hwaccel_id) - return hwaccels[i].device_type; + for (i = 0;; i++) { + config = avcodec_get_hw_config(codec, i); + if (!config) + return NULL; + if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) + continue; + dev = hw_device_get_by_type(config->device_type); + if (dev) + return dev; } - return AV_HWDEVICE_TYPE_NONE; -} - -static enum AVHWDeviceType hw_device_match_type_in_name(const char *codec_name) -{ - const char *type_name; - enum AVHWDeviceType type; - for (type = av_hwdevice_iterate_types(AV_HWDEVICE_TYPE_NONE); - type != AV_HWDEVICE_TYPE_NONE; - type = av_hwdevice_iterate_types(type)) { - type_name = av_hwdevice_get_type_name(type); - if (strstr(codec_name, type_name)) - return type; - } - return AV_HWDEVICE_TYPE_NONE; } int hw_device_setup_for_decode(InputStream *ist) { + const AVCodecHWConfig *config; enum AVHWDeviceType type; - HWDevice *dev; - const char *type_name; - int err; + HWDevice *dev = NULL; + int err, auto_device = 0; if (ist->hwaccel_device) { dev = hw_device_get_by_name(ist->hwaccel_device); if (!dev) { - char *tmp; - size_t len; - type = hw_device_match_type_by_hwaccel(ist->hwaccel_id); - if (type == AV_HWDEVICE_TYPE_NONE) { - // No match - this isn't necessarily invalid, though, - // because an explicit device might not be needed or - // the hwaccel setup could be handled elsewhere. + if (ist->hwaccel_id == HWACCEL_AUTO) { + auto_device = 1; + } else if (ist->hwaccel_id == HWACCEL_GENERIC) { + type = ist->hwaccel_device_type; + err = hw_device_init_from_type(type, ist->hwaccel_device, + &dev); + } else { + // This will be dealt with by API-specific initialisation + // (using hwaccel_device), so nothing further needed here. return 0; } - type_name = av_hwdevice_get_type_name(type); - len = strlen(type_name) + 1 + - strlen(ist->hwaccel_device) + 1; - tmp = av_malloc(len); - if (!tmp) - return AVERROR(ENOMEM); - snprintf(tmp, len, "%s:%s", type_name, ist->hwaccel_device); - err = hw_device_init_from_string(tmp, &dev); - av_free(tmp); - if (err < 0) - return err; + } else { + if (ist->hwaccel_id == HWACCEL_AUTO) { + ist->hwaccel_device_type = dev->type; + } else if (ist->hwaccel_device_type != dev->type) { + av_log(ist->dec_ctx, AV_LOG_ERROR, "Invalid hwaccel device " + "specified for decoder: device %s of type %s is not " + "usable with hwaccel %s.\n", dev->name, + av_hwdevice_get_type_name(dev->type), + av_hwdevice_get_type_name(ist->hwaccel_device_type)); + return AVERROR(EINVAL); + } } } else { - if (ist->hwaccel_id != HWACCEL_NONE) - type = hw_device_match_type_by_hwaccel(ist->hwaccel_id); - else - type = hw_device_match_type_in_name(ist->dec->name); - if (type != AV_HWDEVICE_TYPE_NONE) { + if (ist->hwaccel_id == HWACCEL_AUTO) { + auto_device = 1; + } else if (ist->hwaccel_id == HWACCEL_GENERIC) { + type = ist->hwaccel_device_type; dev = hw_device_get_by_type(type); + if (!dev) + err = hw_device_init_from_type(type, NULL, &dev); + } else { + dev = hw_device_match_by_codec(ist->dec); if (!dev) { - hw_device_init_from_string(av_hwdevice_get_type_name(type), + // No device for this codec, but not using generic hwaccel + // and therefore may well not need one - ignore. + return 0; + } + } + } + + if (auto_device) { + int i; + if (!avcodec_get_hw_config(ist->dec, 0)) { + // Decoder does not support any hardware devices. + return 0; + } + for (i = 0; !dev; i++) { + config = avcodec_get_hw_config(ist->dec, i); + if (!config) + break; + type = config->device_type; + dev = hw_device_get_by_type(type); + if (dev) { + av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto " + "hwaccel type %s with existing device %s.\n", + av_hwdevice_get_type_name(type), dev->name); + } + } + for (i = 0; !dev; i++) { + config = avcodec_get_hw_config(ist->dec, i); + if (!config) + break; + type = config->device_type; + // Try to make a new device of this type. + err = hw_device_init_from_type(type, ist->hwaccel_device, &dev); + if (err < 0) { + // Can't make a device of this type. + continue; + } + if (ist->hwaccel_device) { + av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto " + "hwaccel type %s with new device created " + "from %s.\n", av_hwdevice_get_type_name(type), + ist->hwaccel_device); + } else { + av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto " + "hwaccel type %s with new default device.\n", + av_hwdevice_get_type_name(type)); } + } + if (dev) { + ist->hwaccel_device_type = type; } else { - // No device required. + av_log(ist->dec_ctx, AV_LOG_INFO, "Auto hwaccel " + "disabled: no device found.\n"); + ist->hwaccel_id = HWACCEL_NONE; return 0; } } if (!dev) { - av_log(ist->dec_ctx, AV_LOG_WARNING, "No device available " - "for decoder (device type %s for codec %s).\n", + av_log(ist->dec_ctx, AV_LOG_ERROR, "No device available " + "for decoder: device type %s needed for codec %s.\n", av_hwdevice_get_type_name(type), ist->dec->name); - return 0; + return err; } ist->dec_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); @@ -314,24 +411,16 @@ int hw_device_setup_for_decode(InputStream *ist) int hw_device_setup_for_encode(OutputStream *ost) { - enum AVHWDeviceType type; HWDevice *dev; - type = hw_device_match_type_in_name(ost->enc->name); - if (type != AV_HWDEVICE_TYPE_NONE) { - dev = hw_device_get_by_type(type); - if (!dev) { - av_log(ost->enc_ctx, AV_LOG_WARNING, "No device available " - "for encoder (device type %s for codec %s).\n", - av_hwdevice_get_type_name(type), ost->enc->name); - return 0; - } + dev = hw_device_match_by_codec(ost->enc); + if (dev) { ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref); if (!ost->enc_ctx->hw_device_ctx) return AVERROR(ENOMEM); return 0; } else { - // No device required. + // No device required, or no device available. return 0; } } diff --git a/avtools/avconv_opt.c b/avtools/avconv_opt.c index df693360a7..a4a225c3e9 100644 --- a/avtools/avconv_opt.c +++ b/avtools/avconv_opt.c @@ -56,33 +56,11 @@ } const HWAccel hwaccels[] = { -#if HAVE_VDPAU_X11 - { "vdpau", hwaccel_decode_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU, - AV_HWDEVICE_TYPE_VDPAU }, -#endif -#if CONFIG_D3D11VA - { "d3d11va", hwaccel_decode_init, HWACCEL_D3D11VA, AV_PIX_FMT_D3D11, - AV_HWDEVICE_TYPE_D3D11VA }, -#endif -#if CONFIG_DXVA2 - { "dxva2", hwaccel_decode_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD, - AV_HWDEVICE_TYPE_DXVA2 }, -#endif #if CONFIG_VDA - { "vda", vda_init, HWACCEL_VDA, AV_PIX_FMT_VDA, - AV_HWDEVICE_TYPE_NONE }, + { "vda", vda_init, HWACCEL_VDA, AV_PIX_FMT_VDA }, #endif #if CONFIG_LIBMFX - { "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV, - AV_HWDEVICE_TYPE_NONE }, -#endif -#if CONFIG_VAAPI - { "vaapi", hwaccel_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI, - AV_HWDEVICE_TYPE_VAAPI }, -#endif -#if CONFIG_CUVID - { "cuvid", hwaccel_decode_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA, - AV_HWDEVICE_TYPE_CUDA }, + { "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV }, #endif { 0 }, }; @@ -201,12 +179,15 @@ static double parse_frame_aspect_ratio(const char *arg) static int show_hwaccels(void *optctx, const char *opt, const char *arg) { + enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; int i; printf("Supported hardware acceleration:\n"); - for (i = 0; hwaccels[i].name; i++) { + while ((type = av_hwdevice_iterate_types(type)) != + AV_HWDEVICE_TYPE_NONE) + printf("%s\n", av_hwdevice_get_type_name(type)); + for (i = 0; hwaccels[i].name; i++) printf("%s\n", hwaccels[i].name); - } printf("\n"); return 0; } @@ -623,6 +604,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) else if (!strcmp(hwaccel, "auto")) ist->hwaccel_id = HWACCEL_AUTO; else { + enum AVHWDeviceType type; int i; for (i = 0; hwaccels[i].name; i++) { if (!strcmp(hwaccels[i].name, hwaccel)) { @@ -631,10 +613,23 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) } } + if (!ist->hwaccel_id) { + type = av_hwdevice_find_type_by_name(hwaccel); + if (type != AV_HWDEVICE_TYPE_NONE) { + ist->hwaccel_id = HWACCEL_GENERIC; + ist->hwaccel_device_type = type; + } + } + if (!ist->hwaccel_id) { av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n", hwaccel); av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: "); + type = AV_HWDEVICE_TYPE_NONE; + while ((type = av_hwdevice_iterate_types(type)) != + AV_HWDEVICE_TYPE_NONE) + av_log(NULL, AV_LOG_FATAL, "%s ", + av_hwdevice_get_type_name(type)); for (i = 0; hwaccels[i].name; i++) av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name); av_log(NULL, AV_LOG_FATAL, "\n");